2015-05-12 2 views
12

Qual è la differenza tra:L'impostazione di una variabile d'ambiente sulla stessa riga dell'esecuzione del programma è diversa dall'impostazione separata? - le variabili di shell vs. variabili d'ambiente

prompt$ TSAN_OPTIONS="suppressions=/somewhere/file" ./myprogram 

e

prompt$ TSAN_OPTIONS="suppressions=/somewhere/file" 
prompt$ ./myprogram 

La biblioteca thread-sanitizer dà il primo caso come il modo di ottenere la loro biblioteca (utilizzato entro myprogram) per leggere il file indicato in opzioni. L'ho letto e ho pensato che si trattasse di due righe separate, quindi l'ho eseguito come secondo caso.

La libreria non utilizza il file nel secondo caso, dove la variabile di ambiente e l'esecuzione del programma si trovano su righe separate.

Qual è la differenza?

Domanda bonus: come funziona il primo caso senza errori? Non dovrebbe esserci un; o & & tra di loro? La risposta a questa domanda probabilmente risponde il mio primo ...

risposta

13

Il formato VAR=value command imposta la variabile VAR ad avere il valore value nell'ambiente del comando command. La sezione delle specifiche che copre questo è il Simple Commands. In particolare:

Altrimenti, le assegnazioni delle variabili possono essere esportati per l'ambiente di esecuzione del comando e non pregiudicano l'ambiente di esecuzione corrente se non come effetto collaterale delle espansioni eseguite nel passaggio 4.

Il formato VAR=value; command imposta la variabile di shell corrente nella shell e quindi esegue command come processo figlio. Il processo figlio non sa nulla delle variabili impostate nel processo shell.

Il meccanismo con cui un processo esporta (suggerimento suggerimento) una variabile per essere visto dai processi figli è impostandoli nel suo ambiente prima di eseguire il processo figlio. Il built-in di shell che fa questo è export. Questo è il motivo per cui spesso vedi export VAR=value e VAR=value; export VAR.

La sintassi si sta discutendo è un breve modulo per qualcosa di simile a:

VAR=value 
export VAR 
command 
unset -v VAR 

solo senza utilizzare l'ambiente di processo in corso a tutti.

+0

Ahh, OK, grazie! Sono confuso, però, perché se faccio "CC = xyz" o "CXX = xyz ++" senza un'esportazione, cmake preleva le modifiche. Non dovrebbe non raccogliere le modifiche in questo modo? Oppure, quando una variabile d'ambiente viene esportata, viene esportata "per riferimento" anziché "per valore", quindi forse uno script di avvio esporta CC e CXX senza che io lo sappia ... Quindi se li cambio, funziona? – user1902689

+2

Corretto, 'export' contrassegna la * variabile * come esportata e non il valore corrente. Quindi è necessario esportare una variabile solo una volta, anche se si modifica il valore. –

+2

È possibile eseguire 'export -p' o' declare -x' per vedere l'elenco corrente delle variabili esportate (e i loro valori correnti). –

13

Per completare Etan Reisner's helpful answer:

E 'importante distinguere tra guscio variabili e ambiente variabili:

Nota: Quanto segue si applica a tutti i shell POSIX-compatibili; bash -specifiche estensioni sono contrassegnate come tali.

Un shell variabile è un costrutto specifico guscio che si limita al guscio che definisce (con l'eccezione di subshells, che acquistano i loro copie delle variabili della shell corrente),
mentre un ambiente variabile viene ereditato da qualsiasi processo figlio creato dal processo corrente (shell), se tale processo figlio è esso stesso una conchiglia.
Si noti che all-uppercase variable names should only be used for environment variables.

In entrambi i casi, un processo figlio eredita sempre e solo copie di variabili, la cui modifica (dal bambino) non non influenzano la genitore.

  • Tutti ambiente variabili sono ancheshell variabili (shell assicura che),
  • ma l'inverso non è vero: coperture variabili non sono variabili di ambiente , se non esplicitamente designato o ereditato come tale - questa designazione è chiamato esportatore.
    • nota che l'off-by-default l'opzione -a guscio (set con set -a, o passato alla shell stessa come un'opzione della riga di comando) può essere utilizzato per auto-export tutte le variabili di shell.

Così,

  • tutte le variabili create implicitamente mediante cessione - ad esempio, TSAN_OPTIONS="suppressions=/somewhere/file" - sono variabili di shell soltanto, ma variabili non anche d'ambiente,
  • SALVO - forse confusamente - se anteposto direttamente a un comando - ad es. TSAN_OPTIONS="suppressions=/somewhere/file" ./myprogram - nel qual caso sono solo variabili ambiente, solo in vigore per tale comando.
    • Questo è ciò che descrive la risposta di Etan.

variabili di shell variabili di ambiente diventano così nei seguenti casi:

  • basata sulle variabili ambientali che il guscio si ereditarie, come $HOME
  • variabili shell creato esplicitamente con export varName[=value] o, in bash, anche con declare -x varName[=value]
    • contrario, in bash, utilizzando declare senza -x, o utilizzando local in una funzione, crea mera guscio variabili
  • variabili shell create implicitamente mentre l'off-by-default opzione -a shell è in vigore (con eccezioni limitate)

Una volta che una variabile di shell è contrassegnata come esportata - ovvero, contrassegnato come variabile di ambiente: qualsiasi modifiche successive alla variabile di shell aggiornano anche la variabile di ambiente; es .:

export TSAN_OPTIONS # creates shell variable *and* corresponding environment variable 

# ... 

TSAN_OPTIONS="suppressions=/somewhere/file" # updates *both* the shell and env. var. 

  • export -p stampa tutte le variabili di ambiente
  • unset [-v] MYVAR non-definisce guscio variabile $MYVAR e rimuove anche come una variabile ambiente, se applicabile.
  • in bash:
    • È possibile "unexport" un dato variabile senza indefiniti anche come un variabile shell con export -n MYVAR - questo rimuove MYVAR dall'ambiente, ma conserva il suo valore corrente come variabile shell .
    • declare -p MYVAR stampa il valore attuale della variabile $MYVAR insieme ai relativi attributi; se l'uscita inizia con declare -x, $MYVAR viene esportato (è una variabile d'ambiente)
Problemi correlati