Existe uma diferença entre colocar um par nome-valor em um comando e usar env no bash?

18

Digamos que eu invoque A=B command e env A=B command em bash . Existe alguma situação em que possa haver uma diferença entre as invocações?

    
por Karl Richter 03.12.2014 / 20:55

1 resposta

25

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 .

    
por 03.12.2014 / 21:15