【问题标题】:Unset an environment variable for a single command取消设置单个命令的环境变量
【发布时间】:2026-01-22 22:20:21
【问题描述】:

在 Bash 中,我们可以这样为单个命令设置环境变量:

FOO=bar somecommand

如果我们想取消设置单个命令的变量怎么办?

【问题讨论】:

标签: bash unix environment-variables


【解决方案1】:

从技术上讲,它们不是环境变量,直到有人 exports 他们。但是您至少可以将它们设置为空:

FOO= some command

如果从环境中移除它们就足够了,你可以使用env:

env -u FOO somecommand

【讨论】:

  • 您也可以使用子shell:(unset FOO; some command)。但无论如何,我认为空环境变量与不存在的环境变量不同,所以我不会使用FOO= some command 方法。
  • (我也是)。 (OHAI cky,好久不见!)
  • @glennjackman 不,JB 的意思是运行 FOO=bar 本身不会设置环境变量,除非导出了 FOO
  • @JB:它也不为导出的变量调用 setenv,但它确实将它们添加到传递给子进程的环境变量列表中。由于 bash 并没有真正区分环境变量和其他类型的变量,export 的结果在执行的 shell 中并不是特别明显。 (当然,您可以看到与 declare -p 的区别。)不管您对空变量和缺失变量的感觉如何,bash 也不会真正区分它们,除非您 set -u - 如果您这样做,很多的标准脚本将中断。
【解决方案2】:
env -u FOO somecommand

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

并取消设置多个变量:

env -u FOO -u FOO2 somecommand

【讨论】:

    【解决方案3】:

    当“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)。

    参见Jonathan Nieder (artagnon)commit d6509dacommit a7fbf12commit c7973f2(2019 年 12 月 26 日)。
    (由 Junio C Hamano -- gitster -- 合并到 commit c7372c9,2020 年 1 月 30 日)

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

    签字人:Jonathan Nieder

    就像分配非空值一样,在调用函数时将空值分配给 shell 变量会产生不可移植的行为:在某些 shell 中,分配在函数调用期间持续,在其他情况下,它会在函数返回后持续存在。

    使用带有 envvar 导出的显式子外壳,以使外壳之间的行为一致且清晰

    此模式的所有先前实例都使用“VAR=value”(带有非空value),自a0a630192d(t/check-non-portable-shell:检测“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
    ) &&
    ...
    

    【讨论】:

      【解决方案4】:

      对于任何打算在没有任何环境变量的情况下运行命令的人,您可以通过运行:

      env -i somecommand
      

      【讨论】:

        最近更新 更多