Допустим, я призываю A=B command
и env A=B command
в bash
. Есть ли ситуация, когда между обоими вызовами может быть разница?
источник
Допустим, я призываю A=B command
и env A=B command
в bash
. Есть ли ситуация, когда между обоими вызовами может быть разница?
Они служат одной и той же цели (передайте данные env vars команде). Однако есть несколько заметных отличий:
A=B command
является оболочкой (Bourne / POSIX / rc)
Например, вы можете сделать:
A=B find . -exec cmd '{}' +
или:
find . -exec env A=B cmd '{}' +
Но вы не можете сделать:
find . -exec A=B cmd '{}' +
Потому find
что не вызывает оболочку для запуска этой команды.
С другой стороны, env
будучи внешней командой, вы не можете делать:
f() { ...; }
env A=B f
или:
env A=B eval '...'
Также:
A=B cmd
работает только с env vars, которые являются допустимыми именами переменных оболочки . Вам нужно env
любое другое имя env var:
env 'my var=foo' cmd...
bash
сбрасывает _
переменную:
bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
В zsh
, ARGV0
и STTY
имеет особое значение в этом контексте:
STTY=-echo cat
Работает cat
с echo
отключенным терминалом . И:
ARGV0=foo cmd
работает cmd
с foo
его argv[0]
.
Если вы не хотите эту специальную обработку, вы должны использовать env
.
Обратите внимание, что sudo
поддерживает:
sudo A=B cmd
Он не использует оболочку или env
для этого. Это делает это само по себе.
Он может передавать переменные с любым именем, кроме тех, которые начинаются с -
.
Присваивание является конструкцией оболочки, тогда как знак равенства в аргументе env
не имеет специального значения для оболочки, поэтому A=$B cmd
безопасен, тогда как env A="$B" cmd
(или sudo A="$B" cmd
) требует двойных кавычек.
A=B cmd
Синтаксис поддерживается только в оболочках Bourne и rc
семей (не es
хотя). В оболочках csh
или fish
семьях, например, вы должны прибегнуть к env
.