Diciamo che invoco A=B command
e env A=B command
dentro bash
. Esiste una situazione in cui potrebbe esserci una differenza tra entrambe le invocazioni?
Diciamo che invoco A=B command
e env A=B command
dentro bash
. Esiste una situazione in cui potrebbe esserci una differenza tra entrambe le invocazioni?
Risposte:
Servono allo stesso scopo (passare i dati indicati al comando). Tuttavia alcune differenze notevoli:
A=B command
è un costrutto shell (Bourne / POSIX / rc).
Ad esempio, puoi fare:
A=B find . -exec cmd '{}' +
o:
find . -exec env A=B cmd '{}' +
Ma non puoi fare:
find . -exec A=B cmd '{}' +
Perché find
non sta invocando una shell per eseguire quel comando.
D'altra parte, env
essendo un comando esterno, non puoi fare:
f() { ...; }
env A=B f
o:
env A=B eval '...'
Anche:
A=B cmd
funziona solo con env var che sono nomi di variabili shell valide . È necessario env
per qualsiasi altro nome var env:
env 'my var=foo' cmd...
bash
reimposta la _
variabile:
bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
In zsh
, ARGV0
e STTY
hanno significati speciali in quel contesto:
STTY=-echo cat
Funziona cat
con terminale echo
disabilitato. E:
ARGV0=foo cmd
funziona cmd
con foo
il suo argv[0]
.
Se non si desidera tale elaborazione speciale, è necessario utilizzare env
.
Si noti che sudo
supporta:
sudo A=B cmd
Non sta usando la shell o env
per farlo. Lo fa da solo.
Può passare variabili con qualsiasi nome tranne quelli che iniziano con -
.
L'assegnazione è un costrutto di shell mentre un segno di uguale nell'argomento di env
non ha alcun significato speciale per la shell, quindi A=$B cmd
è sicuro mentre env A="$B" cmd
(o sudo A="$B" cmd
) richiedono doppie virgolette.
La A=B cmd
sintassi è supportata solo nelle shell di Bourne e rc
famiglie (non es
però). Nelle shell delle famiglie csh
o fish
, per esempio, devi ricorrere a env
.