为单个命令取消设置环境变量

70
在Bash中,我们可以按照以下方式为单个命令设置环境变量:

通过这种方式,可以为特定的命令设置环境变量。

FOO=bar somecommand

如果我们想要在单个命令中取消设置一个变量,该怎么办?


与单个命令不同,此问题涉及多个方面:https://dev59.com/V2w15IYBdhLWcg3wCXKJ - Ciro Santilli OurBigBook.com
4个回答

66

严格来说,只有当有人 export 它们时,它们才是环境变量。但是至少你可以将它们设置为空:

FOO= some command

如果只需要将它们从环境中移除,您可以使用 env

env -u FOO somecommand

27
您也可以使用子Shell:(unset FOO; some command)。但无论如何,我认为空环境变量与不存在的环境变量有所不同,因此我不会使用FOO= some command的方法。 - C. K. Young
1
(我也是)。(嗨,cky,好久不见了!) - JB.
4
从技术上来说,它们是环境变量,只不过不是针对当前环境的:这些变量会添加到执行命令的环境中,不会影响当前的shell环境 - glenn jackman
1
@glennjackman 不,JB 的意思是,仅运行 FOO=bar 并不会设置环境变量,除非 FOO 被导出。 - C. K. Young
3
@JB:对于导出的变量,它也不调用 setenv 函数,但会将它们加入传递给子进程的环境变量列表中。由于 bash 并没有真正区分环境变量和其他类型的变量,在执行 export 命令后,其结果在当前 shell 中并不特别明显(当然,你可以用 declare -p 命令查看区别)。无论你如何看待空和不存在的变量,bash 也没有真正区分它们,除非你使用 set -u 命令——如果你这样做,很多标准脚本都会出错。 - rici
显示剩余4条评论

22
env -u FOO somecommand

这将从somecommand进程的环境变量中删除FOO变量。

要取消设置多个变量:

env -u FOO -u FOO2 somecommand

3

如果有人想要在没有任何环境变量的情况下运行命令,则可以执行以下操作:

env -i somecommand

2

当"somecommand"是一个shell函数时,这就变得棘手了。

一次性环境变量赋值,比如在"FOO=bar cmd"中的'FOO',仅在'cmd'调用期间存在。
然而,如果'cmd'恰好是一个shell函数,则'FOO'将在执行shell本身时被赋值,并且该赋值会一直保留到进程退出(除非明确取消设置)。
由于"FOO=bar shell_func"的这种副作用很可能不是有意为之,因此应该避免使用它。

为了进一步说明'FOO= aCommand'是危险的,请考虑Git 2.26(2020年第一季度),它避免了"FOO=shell_function(仅为一个命令取消设置FOO)。

请参见提交d6509da提交a7fbf12提交c7973f2(由Jonathan Nieder (artagnon)于2019年12月26日提交)。
(由Junio C Hamano -- gitster --于2020年1月30日在提交c7372c9中合并)

fetch test: 避免在shell函数中使用“VAR= cmd”

Signed-off-by: Jonathan Nieder

就像给一个非空值赋值一样,在调用函数时将空值分配给shell变量会产生不可移植的行为:在某些shell中,分配只持续到函数调用结束,在其他shell中,分配还会在函数返回后继续存在。

使用显式子shell,并导出envvar以使行为在各种shell下保持一致和清晰易懂

所有先前出现这种模式的实例都使用了“VAR=value”(具有非空的value),自a0a630192d以来,“make test-lint”已经自动诊断了这种情况(t/check-non-portable-shell: detect "FOO=bar shell_func", 2018-07-13)。

GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch

使用子shell:

(
    GIT_TEST_PROTOCOL_VERSION= &&
    export GIT_TEST_PROTOCOL_VERSION &&
    trace_fetch client origin to_fetch
) &&
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接