2012-12-21 15 views
21

Sto provando a richiamare un comando di shell con un ambiente modificato tramite il comando env.Impostazione della variabile di ambiente per una chiamata di programma in bash utilizzando env

Secondo il manuale

env HELLO='Hello World' echo $HELLO 

dovrebbe eco Hello World, ma non è così. Se faccio

HELLO='Hello World' bash -c 'echo $HELLO' 

esso stampa Hello World come previsto (grazie a this answer per queste informazioni).

Cosa mi manca qui?

Cheers, Niklas

+0

Un controllo di integrità senza espansione è 'HELLO = 'Hello World' env | grep HELLO' che fa ciò che è richiesto ma è molto meno utile nella pratica della risposta accettata. –

risposta

37

È perché nel primo caso, la shell corrente espande la variabile $ HELLO prima di eseguire i comandi. E non c'è una serie di variabili HELLO nella tua shell corrente.

env HELLO='Hello World' echo $HELLO

farà questo:

  • espandono le variabili dato, in questo caso $ CIAO
  • eseguire env con i 3 argomenti 'CIAO = Ciao Mondo', 'eco' e ' '(una stringa vuota, poiché non c'è una variabile HELLO impostata nella shell corrente)
  • Il comando env verrà eseguito e verrà impostato HELLO =' Hello World 'nel suo ambiente
  • env verrà eseguito echo con l'argomento '' (una stringa vuota)

Come si vede, la shell corrente ha espanso la variabile $ HELLO, che non è impostata.

HELLO='Hello World' bash -c 'echo $HELLO'

farà questo:

  • impostare la variabile HELLO='Hello World per il seguente comando
  • corsa bash con i 2 argomenti '-c' e 'echo $ CIAO'
  • dal l'ultimo argomento è racchiuso tra virgolette singole, qualsiasi cosa al suo interno non è espansa
  • la nuova bash a sua volta eseguirà il comando echo $HELLO
  • Per eseguire echo $ HELLO nella nuova sub-shell di bash, bash dapprima espande tutto ciò che può, $ HELLO in questo caso e la shell genitore imposta a "Hello World" per noi.
  • Il subshell corre echo 'Ciao Mondo'

Se si è tentato di fare per esempio questo:

env HELLO='Hello World' echo '$HELLO'

  • shell corrente sarebbe espandere nulla si può, che non è nulla in quanto $ CIAO è racchiuso tra virgolette singole
  • eseguire env con i 3 argomenti 'CIAO = Ciao Mondo', ' echo' e '$ CIAO'
  • il comando env verrà eseguito e impostare il CIAO = 'Ciao mondo' nel suo ambiente
  • ENV verrà eseguito l'eco con l'argomento '$ CIAO'

In questo caso, non c'è nessuna shell che espanderà $ HELLO, quindi echo riceve la stringa $HELLO e stampa quello. L'espansione variabile viene eseguita solo dalle shell.

4

Penso che ciò che accade è simile a this situation in cui sono stato anche perplesso.

In breve, l'espansione variabile nel primo caso viene eseguita dalla shell corrente che non ha $HELLO nel proprio ambiente. Nel secondo caso, tuttavia, le virgolette singole impediscono alla shell corrente di eseguire l'espansione della variabile, quindi tutto funziona come previsto.

Nota come cambiare apici di doppi apici impedisce questo comando di lavorare nel modo desiderato:

HELLO='Hello World' bash -c "echo $HELLO" 

Ora questo sarà venendo a mancare per la stessa ragione come il primo comando nella sua interrogazione.

+0

corretto. Nel primo caso, è la shell corrente che espande la variabile. Nel secondo caso, è in esecuzione il nuovo 'bash' che lo fa. –

+0

Anche qui molte grazie per la rapida risposta! Purtroppo posso dare una sola risposta a un bel segno di spunta verde – Niklas

2

Questo funziona ed è buono per me

$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR" 
Hello World!!! 
+1

Non penso che ciò valga per la parte "per una chiamata di programma" della domanda. I vars qui rimarranno impostati per la sessione corrente in modo da poter continuare ad echeggiare. –

0

Ecco un modo più semplice per confermare la conchiglia funziona come previsto.

env A=42 env 
env 

Le prime piste comando imposta A-42 e corre env. Il secondo comando esegue anche corre env. Confronta l'output di entrambi.

Problemi correlati