Esportazione di una variabile con punto (.) In essa


39

Come esportare una variabile che contiene punti. Ottengo "nome variabile non valido" quando ho provato:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name

Persino la fuga di punti metacaratteri (.) Non ha aiutato neanche

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier


1
purtroppo non è elencato quando ho digitato / cercato una domanda simile. spiacente. ..
user1587504

Risposte:


50

Almeno per bashla pagina man definisce la sintassi di esportazione come:

export [-fn] [name[=word]] ...

Definisce anche un "nome" come:

   name   A  word  consisting  only  of alphanumeric characters and under
          scores, and beginning with an alphabetic character or an  under
          score.  Also referred to as an identifier.

Quindi non puoi davvero definire una variabile come in my.homequanto non è un identificatore valido.

Sono molto sicuro che il tuo ksh abbia una definizione molto simile di identificatore e quindi non consente anche questo tipo di variabili. (Dai un'occhiata alla sua pagina man.)

Sono anche molto sicuro che ci sia una sorta di standard generale (POSIX?) Che specifica, cosa è permesso come identificatore (e quindi un nome variabile).


Se hai davvero bisogno di questo tipo di variabile per qualche motivo, puoi usare qualcosa del genere

env "my.home=/tmp/someDir" bash

per definirlo comunque. Ma poi di nuovo, non sarai in grado di accedervi usando la normale sintassi della shell. In questo caso probabilmente avrai bisogno di un'altra lingua come perl:

perl -e 'print $ENV{"my.home"}'

Per esempio

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'

dovrebbe stampare il tuo percorso.


È a causa dell'integrazione della formica. E sfortunatamente non consente di impostare / esportare variabili da unix. Accettare la tua risposta ..
user1587504

1
ant è di solito configurato da una singola variabile d'ambiente chiamata ANT_OPTSo da ~ / .antrc. Non sono necessari nomi di variabili di ambiente strani per la formica stessa.
Michas,

8

Mentre le variabili di ambiente possono avere qualsiasi nome (inclusa la stringa vuota) che non contenga un segno uguale o un byte null, le shell associano le variabili di ambiente alle variabili di shell e nella maggior parte delle shell, i nomi delle variabili sono limitati ai caratteri alfanumerici ASCII e _dove il primo carattere può " t essere una cifra (esclusi i parametri posizionali e altri quelli speciali come $*, $-, $@, ..., (che non vengono mappati ai corrispondenti variabili di ambiente)). Si noti inoltre che alcune variabili sono riservate / speciali da / alla shell.

Eccezioni a ciò:

  • Il rcguscio e suoi derivati come ese akangasupportano qualsiasi nome eccetto la stringa vuota, e quelli che sono del tutto-numerico o contengono =caratteri (e sempre esportare tutti loro variabili per l'ambiente, e l'azione del variabili speciali come *, status, pid...):

    ; '%$£"' = test
    ; echo $'%$£"'
    test
    ; '' = x
    zero-length variable name
    ;

    Tuttavia, utilizza la propria codifica per le variabili il cui nome non contiene alnum o per array quando passato nell'ambiente dei comandi in esecuzione:

    $ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
    __2b=zzz$
    __5f_=zzz$
    a=zzz\001xxx$
    $ env +=x rc -c "echo $'+'"
    x
    $ env __2b=x rc -c "echo $'+'"
    x
  • AT & T ksh, yashe zsh(anche bash, ma solo per i caratteri a un byte) alnums supporto nella localizzazione corrente, non solo quelli ASCII.

    $ Stéphane=1
    $ echo "$Stéphane"
    1

    In quelle shell, potresti cambiare le impostazioni locali per considerare la maggior parte dei caratteri come alfa, ma ciò non funzionerebbe con caratteri ASCII come .. Puoi ingannare zsho kshpensare che £è una lettera, ma non quello .o qualsiasi altro carattere ASCII (per quanto riguarda consentire i caratteri nei nomi delle variabili, non per il [[:alpha:]]glob per esempio).

  • ksh93ha variabili speciali il cui nome contiene un punto simile ${.sh.version}, ma quelle non sono mappate su variabili di ambiente e sono speciali. Lo scopo .è assicurarsi che non sia in conflitto con altre variabili. Se avesse scelto di chiamarlo $sh_version, allora avrebbe potuto potenzialmente rotto script che ha utilizzato quella variabile già (si veda ad esempio quanto zshha problemi con il suo $patho $commandsvariabili speciali matrice / hash (alla csh) che si rompono alcuni script).

Si noti che, oltre a conchiglie che non supportano tali variabili, alcune conchiglie come pdksh / mksh fanno togliere loro dall'ambiente che ricevono ( bashrimuove quello con un nome vuoto, ash, kshe bashrimuovere quelle stringhe di ambiente che non contengono un =carattere):

$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%

$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%

$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%

Per riassumere, migliore è attaccare con nomi variabili supportati dalla maggior parte dei gusci e anche cercare di utilizzare maiuscole per le variabili di ambiente (e minuscole o miste per variabili shell non-esportati) evitando quelle che sono speciali in conchiglie (come IFS, PS1, BASH_VERSION...).

Se hai bisogno di impostare una tale variabile in una shell che non le supporta, ma non le scarta, puoi rieseguire te stesso, con qualcosa del tipo:

#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"

(ovviamente, se è necessario farlo nel mezzo dello script, ciò non sarà di aiuto, ma si potrebbe quindi dare un'occhiata a quell'approccio per salvare e ripristinare l'ambiente di esecuzione della shell su un re-exec). Oppure prova l'approccio debugger:

gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"

(che sembra di lavoro con zsh, yash, cshe tcshsu Linux amd64, ma non con una qualsiasi delle altre shell che ho provato ( mksh, ksh93, bash, dash)).


1
mksh(e pdksh) in effetti costruiscono i processi ambientali che generano ottengono completamente da zero, usando solo quei parametri esportati nell'attuale ambiente di esecuzione della shell, quindi non c'è modo di passare quelle variabili attraverso quelle shell. (Si noti che le variabili che vengono passate sono soggette a modifiche; ad esempio, sto pianificando di supportare le esportazioni di array per mkshun giorno.)
mirabilos,

0

Come sottolineato dagli altri post, le shell più comuni non consentono di impostare variabili di ambiente con punti nel nome. Tuttavia, ho trovato situazioni, in particolare che coinvolgono Docker e programmi invocati, in cui il software richiedeva valori chiave con punti.

Tuttavia, in ognuna di queste situazioni, queste coppie chiave-valore potrebbero essere passate al programma con mezzi diversi dalle sole variabili d'ambiente. Ad esempio, in Ant, è possibile utilizzare "-propertyfile (nome file)" per passare un insieme di valori-chiave formattato nel file delle proprietà. Confd consente di "-endend file -file (yaml file)".

Ho passato le variabili di ambiente nel formato "C__any_value = 'my.property.key = il valore'". Ho quindi cambiato l'invocazione del programma per generare prima il file:

set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt

Il setcomando, in Borne Shell, produrrà ciascuna proprietà su una riga separata nel modulo

C__any_value='my.property.key=the value'

Il awkcomando elaborerà solo le variabili di ambiente che iniziano con C__, quindi estrae i valori contenuti tra virgolette singole.

Questo metodo richiede che il valore della variabile di ambiente sia impostato nella forma precisa richiesta dal programma di elaborazione. Inoltre, se il valore o la chiave della tua proprietà conterrà virgolette singole, dovrai modificare il carattere di separazione del campo awk in qualcosa che sai che non verrà visualizzato e racchiudere il valore con quel carattere. Ad esempio, da utilizzare %come separatore:

$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value

(l'output preciso dipenderà dalla vostra shell.) Dovrete prendere ulteriori misure per decodificare la fuga delle quotazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.