【问题标题】:Unexpected environment variable unset未设置意外的环境变量
【发布时间】:2016-09-19 07:28:34
【问题描述】:

在 Bash 中,某些全局变量会在命令 tee 运行后意外取消设置。

测试代码如下:

#!/bin/bash
function set_global_variable(){
        GLOBAL_VARIABLE="global_variable"
        echo "set GLOBAL_VARIABLE($GLOBAL_VARIABLE)"
}

function get_global_variable(){
        echo "get GLOBAL_VARIABLE($GLOBAL_VARIABLE)"
}

function normal_test(){
        unset GLOBAL_VARIABLE
        set_global_variable
        get_global_variable
}

function unnormal_test(){
        unset GLOBAL_VARIABLE
        set_global_variable |tee random_file
        get_global_variable
}

echo "normal_test"
normal_test

echo "unnormal_test"
unnormal_test

结果:

normal_test
set GLOBAL_VARIABLE(global_variable)
get GLOBAL_VARIABLE(global_variable)
unnormal_test
set GLOBAL_VARIABLE(global_variable)
get GLOBAL_VARIABLE()

unnormal_test中GLOBAL_VARIABLE的值为null,为什么?

【问题讨论】:

  • 在管道中,命令在子 shell 中执行,这意味着它们对环境所做的任何更改在父 shell 中都不可见。

标签: bash shell environment-variables tee


【解决方案1】:

问题出在这一行:

set_global_variable |tee random_file

运行此行时,bash 将为管道的每个组件创建一个子 shell 并在那里运行它们。所以set_global_variable 实际上会设置变量,但它会在一个单独的过程中执行此操作。当您在下一行运行get_global_variable 时,您仍处于不受此影响的原始进程中。

这是一个更简单的例子:

true | a=1
echo $a

出于与上述相同的原因,这将不打印任何内容。另一方面:

true | { a=1; echo $a; }

将打印 1,因为 echo $a 是从与 a=1 相同的子 shell 运行的。最后一个例子在实践中并不是很有用。

所以一般规则,不要在子shell中设置变量。

【讨论】:

    猜你喜欢
    • 2014-09-05
    • 2012-01-18
    • 2013-11-20
    • 2013-04-20
    • 2022-12-02
    • 2017-12-31
    • 2017-10-30
    • 2014-02-10
    相关资源
    最近更新 更多