环境或不环境

环境或不环境

命令有什么区别

$ env FOO=bar baz

$ FOO=bar baz

有什么作用呢env

答案1

它们在功能上是等效的。

主要区别在于env FOO=bar baz涉及调用 shell 和 之间的中间进程baz,而FOO=bar bazshell 直接调用baz.
所以从这方面来说,FOO=bar baz是首选。

我发现自己使用的唯一情况env FOO=bar是我必须将一个命令传递给另一个命令。
作为一个具体的示例,假设我有一个包装器脚本,它对环境执行一些修改,然后调用传递exec给它的命令,例如:

#!/bin/bash
FOO=bob
some stuff
exec "$@"

如果你执行它myscript FOO=bar bazexec将会抛出一个错误,因为它exec FOO=bar baz是无效的。
相反,您将其称为 as ,myscript env FOO=bar baz其执行为exec env FOO=bar baz,并且是完全有效的。

答案2

baz在此特定示例中,假设您的 shell 是 POSIX 兼容 shell,并且假设是可执行文件而不是内置 shell,则没有任何有效区别。

如果你的外壳是不是POSIX 兼容的 shell,例如cshtcsh,语法

FOO=bar baz

不起作用,并且没有等效的 shell 语法。对于这些 shell,该env命令是覆盖或注入单个命令的环境变量的唯一方法。

例如,如果baz是 shell 内置命令,fcenv不会给出相同的结果,因为env正在执行新进程而不是由命令 shell 直接运行。此外,没有fc可执行文件,由于它与 shell 环境交互的方式,它只能作为 shell 内置命令运行,env因此绝不使用像fc.

此外,还env提供了一个-i选项,允许您在仅具有指定环境变量集的空环境中启动命令。例如,这env对于在净化环境中启动进程非常有用

env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz

答案3

除了已经说过的

VAR=value cmd args > redirs

作为 shell (Bourne/POSIX) 功能,您传递给的环境变量的名称受到限制cmd。它们必须是有效的 shell 变量名称,并且不能是 shell 的只读变量或特殊变量。

例如,你不能这样做:

1=foo cmd

或者

+++=bar cmd

bash不允许你做:

SHELLOPTS=xtrace cmd

虽然你可以这样做:

env 1=foo cmd
env +++=bar cmd
env '=baz' cmd

(不是说你想要或应该想要这样做)。或者:

env SHELLOPTS=xtrace cmd

(我有时需要这样做)。

请注意,env您仍然无法传递不包含 a 的环境变量字符串=(您也不想这样做)。

答案4

另一种真正有用的情况env是,如果您想完全控制环境。我运行一个服务器程序(Informix,以防你猜不到),我想完全控制其环境。我在脚本末尾使用它来运行它env,该脚本将一堆变量设置为正确的值:

env -i HOME="$IXD" \
       INFORMIXDIR="$IXD" \
       INFORMIXSERVER="$IXS" \
       ${IXC:+INFORMIXCONCSMCFG="$IXC"} \
       ${IXH:+INFORMIXSQLHOSTS="$IXH"} \
       IFX_LISTEN_TIMEOUT=3 \
       ONCONFIG="onconfig.$IXS" \
       PATH="/bin:/usr/bin:$IXD/bin" \
       SHELL=/bin/ksh \
       TZ=UTC0 \
    $ONINIT "$@"

-i选项会破坏现有环境。后续VAR=value选项设置我想要设置的环境变量;程序的名称在 中$ONINIT,所有命令行参数都通过 逐字传递"$@"

${IXH:+INFORMIXSQLHOSTS="$IXH"}构造仅传递INFORMIXSQLHOSTS="$IXH"envif$IXH设置为非空值。

相关内容