Eles servem a mesma finalidade (passe o dado env vars para o comando). No entanto, algumas diferenças notáveis:
A=B command
é uma construção shell (Bourne / POSIX / rc).
Por exemplo, você pode fazer:
A=B find . -exec cmd '{}' +
ou:
find . -exec env A=B cmd '{}' +
Mas você não pode fazer:
find . -exec A=B cmd '{}' +
Porque find
não está invocando um shell para executar esse comando.
Por outro lado, env
é um comando externo, você não pode fazer:
f() { ...; }
env A=B f
ou:
env A=B eval '...'
Além disso:
A=B cmd
funciona apenas com env vars que são nomes de variáveis shell válidos. Você precisa de env
para qualquer outro nome de env de variável:
env 'my var=foo' cmd...
bash
redefine a variável _
:
bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
Em zsh
, ARGV0
e STTY
têm significados especiais nesse contexto:
STTY=-echo cat
Executa cat
com o terminal echo
desativado. E:
ARGV0=foo cmd
executa cmd
com foo
como seu argv[0]
.
Se você não quiser esse processamento especial, precisará usar env
.
Observe que sudo
suporta:
sudo A=B cmd
Não está usando o shell ou env
para fazer isso. Ele faz isso sozinho.
Ele pode passar variáveis com qualquer nome, exceto as que começam com -
.
Atribuição é uma construção shell, enquanto um sinal de igual no argumento de env
não tem significado especial para o shell, portanto A=$B cmd
é seguro, enquanto env A="$B" cmd
(ou sudo A="$B" cmd
) requer aspas duplas.
A sintaxe A=B cmd
é suportada apenas nos shells das famílias Bourne e rc
(não es
). Em shells das famílias csh
ou fish
, por exemplo, você precisa recorrer a env
.