命令之间有什么区别
$ env FOO=bar baz
和
$ FOO=bar baz
有什么作用env
?
命令之间有什么区别
$ env FOO=bar baz
和
$ FOO=bar baz
有什么作用env
?
Answers:
它们在功能上是等效的。
主要区别在于env FOO=bar baz
涉及在shell和之间调用中间过程baz
,就像FOO=bar baz
直接调用shell一样baz
。
所以在这方面,FOO=bar baz
是首选。
我发现自己使用的唯一情况env FOO=bar
是必须将一个命令传递给另一个命令。
作为一个特定的示例,可以说我有一个包装脚本,该脚本对环境进行了一些修改,然后调用exec
传递给它的命令,例如:
#!/bin/bash
FOO=bob
some stuff
exec "$@"
如果您将其执行为myscript FOO=bar baz
,exec
将抛出错误,因为exec FOO=bar baz
无效。
取而代之的是,您将其称为myscript env FOO=bar baz
,将被执行为exec env FOO=bar baz
,并且完全有效。
FOO=bar exec baz
,所以您不需要env
最后一点。
exec
做某事时,它会使用您当前的环境吗?
sudo FOO=bar baz
可以传递环境变量而无需env
。
FOO=bar
脚本时才有效。如果FOO
并非总是如此bar
,我不想对其进行硬编码,而直接将其传递
exec
,例如FOO=bar exec baz
。
在此特定示例中,假设您的外壳是POSIX兼容外壳,并且假定baz
是可执行文件而不是内置的外壳,则没有有效的区别。
如果您的外壳不是 POSIX兼容的外壳,例如csh
或tcsh
,则语法
FOO=bar baz
不起作用,并且没有等效的Shell语法。对于这些外壳,该env
命令是覆盖或注入单个命令的环境变量的唯一方法。
例如,如果baz
是内置的shell fc
,则env
不会给出相同的结果,因为它env
正在执行一个新进程,而不是直接由命令shell运行。此外,也没有fc
可执行的,它只能作为一个shell内建因为它的方式与shell环境交互运行,因此env
将永远不会与像一个内置的工作fc
。
另外,env
提供了-i
选项,该选项使您可以在仅具有一组指定的环境变量的空环境中启动命令。因此env
,对于在经过消毒的环境中启动流程非常有用,例如
env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz
tcsh
我会写(setenv FOO bar; baz)
得到等效功能。
除了已经说过的话
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
您仍然无法传递不包含的环境变量字符串=
(这也不是您想要的)。
另一个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"
到env
如果$IXH
被设置为一个非空值。