Let's say I invoke A=B command
and env A=B command
in bash
. Is there any situation where there might be a difference between both invokations?

- 2,192
1 Answers
They serve the same purpose (pass the given env vars to the command). However a few notable differences:
A=B command
is a shell (Bourne/POSIX/rc) construct.
For instance, you can do:
A=B find . -exec cmd '{}' +
or:
find . -exec env A=B cmd '{}' +
But you can't do:
find . -exec A=B cmd '{}' +
Because find
is not invoking a shell to run that command.
On the other hand, env
being an external command, you can't do:
f() { ...; }
env A=B f
or:
env A=B eval '...'
Also:
A=B cmd
works only with env vars that are valid shell variable names. You need env
for any other env var name:
env 'my var=foo' cmd...
bash
resets the _
variable:
bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
In zsh
, ARGV0
and STTY
have special meanings in that context:
STTY=-echo cat
Runs cat
with terminal echo
disabled. And:
ARGV0=foo cmd
runs cmd
with foo
as its argv[0]
.
If you don't want that special processing, you have to use env
.
Note that sudo
supports:
sudo A=B cmd
It's not using the shell or env
to do that. It does it by itself.
It can pass variables with any name except those starting with -
.
Assignment is a shell construct whereas an equal sign in the argument of env
has no special meaning to the shell, so A=$B cmd
is safe whereas env A="$B" cmd
(or sudo A="$B" cmd
) require double quotes.
The A=B cmd
syntax is only supported in the shells of the Bourne and rc
families (not es
though). In shells of the csh
or fish
families for instance, you have to resort to env
.

- 544,893