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 .