Powiedzmy, wzywam A=B command
i env A=B command
w bash
. Czy jest jakaś sytuacja, w której może istnieć różnica między tymi dwoma wywołaniami?
Powiedzmy, wzywam A=B command
i env A=B command
w bash
. Czy jest jakaś sytuacja, w której może istnieć różnica między tymi dwoma wywołaniami?
Odpowiedzi:
Służą temu samemu celowi (przekazują podane zmienne env do polecenia). Jednak kilka znaczących różnic:
A=B command
jest konstrukcją powłoki (Bourne / POSIX / rc).
Na przykład możesz wykonać:
A=B find . -exec cmd '{}' +
lub:
find . -exec env A=B cmd '{}' +
Ale nie możesz zrobić:
find . -exec A=B cmd '{}' +
Ponieważ find
nie wywołuje powłoki, aby uruchomić to polecenie.
Z drugiej strony, env
będąc poleceniem zewnętrznym, nie możesz wykonać:
f() { ...; }
env A=B f
lub:
env A=B eval '...'
Również:
A=B cmd
działa tylko z zmiennymi env, które są poprawnymi nazwami zmiennych powłoki . Potrzebujesz env
innej nazwy env var:
env 'my var=foo' cmd...
bash
resetuje _
zmienną:
bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
W zsh
, ARGV0
i STTY
mają specjalne znaczenie w tym kontekście:
STTY=-echo cat
Działa cat
z echo
wyłączonym terminalem . I:
ARGV0=foo cmd
biegnie cmd
z foo
jak jego argv[0]
.
Jeśli nie chcesz tego specjalnego przetwarzania, musisz go użyć env
.
Uwaga sudo
: obsługuje:
sudo A=B cmd
Nie używa powłoki ani env
tego nie robi. Robi to samo.
Może przekazywać zmienne o dowolnej nazwie oprócz tych rozpoczynających się od -
.
Przypisanie jest konstrukcją powłoki, podczas gdy znak równości w argumencie argumentu env
nie ma specjalnego znaczenia dla powłoki, więc A=$B cmd
jest bezpieczny, podczas gdy env A="$B" cmd
(lub sudo A="$B" cmd
) wymagają podwójnych cudzysłowów.
A=B cmd
Składnia jest obsługiwana tylko w muszlach Bourne i rc
rodzin (nie es
chociaż). Na przykład w muszlach csh
lub fish
rodzinach musisz uciekać się env
.