将名称-值对添加到命令与在 bash 中使用 env 之间有区别吗?

Kar*_*ter 19 bash environment-variables env

假设我调用A=B commandenv A=B commandin bash。是否存在两种调用之间可能存在差异的情况?

Sté*_*las 26

它们具有相同的目的(将给定的环境变量传递给命令)。但是有一些显着的差异:

A=B command
Run Code Online (Sandbox Code Playgroud)

是一个 shell (Bourne/POSIX/rc) 构造。

例如,您可以执行以下操作:

A=B find . -exec cmd '{}' +
Run Code Online (Sandbox Code Playgroud)

或者:

find . -exec env A=B cmd '{}' +
Run Code Online (Sandbox Code Playgroud)

但你不能这样做:

find . -exec A=B cmd '{}' +
Run Code Online (Sandbox Code Playgroud)

因为find没有调用 shell 来运行该命令。

另一方面,env作为外部命令,您不能执行以下操作:

f() { ...; }
env A=B f
Run Code Online (Sandbox Code Playgroud)

或者:

env A=B eval '...'
Run Code Online (Sandbox Code Playgroud)

还:

A=B cmd
Run Code Online (Sandbox Code Playgroud)

仅适用于作为有效shell变量名称的环境变量。您需要env任何其他环境变量名称:

env 'my var=foo' cmd...
Run Code Online (Sandbox Code Playgroud)

bash重置_变量:

bash-4.3$ _=xxx env | grep '^_='
_=/usr/bin/env
bash-4.3$ env _=xxx env | grep '^_='
_=xxx
Run Code Online (Sandbox Code Playgroud)

zsh,ARGV0STTY在该上下文中具有特殊含义:

STTY=-echo cat
Run Code Online (Sandbox Code Playgroud)

cat在终端echo禁用的情况下运行。和:

ARGV0=foo cmd
Run Code Online (Sandbox Code Playgroud)

cmdfooas运行argv[0]

如果您不想进行特殊处理,则必须使用env.

注意sudo支持:

sudo A=B cmd
Run Code Online (Sandbox Code Playgroud)

它没有使用外壳或env这样做。它自己做。

它可以传递任何名称的变量,除了以-.

赋值是一个 shell 构造,而参数中的等号env对 shell 没有特殊意义,因此A=$B cmd是安全的,而env A="$B" cmd(或sudo A="$B" cmd) 需要双引号。

A=B cmd语法仅在 Bourne 和rc系列的 shell 中受支持(es尽管不支持)。例如,在cshfish家庭的外壳中,您必须求助于env.