Bash:Logging可以影响变量范围吗?

时间:2017-09-04 09:24:51

标签: bash scope io-redirection tee process-substitution

在我当前的项目中,我运行一个循环,在执行期间定义一个稍后需要的变量。 一切顺利,直到我想用tee添加日志记录,以便我 以后可以在文件中检查日志。 由于我想记录stdout和stderr,我应用了|&2>&1 |的快捷方式)。 但奇怪的是,变量的值会丢失。

for i in 1 2 3 ; do
    # ... do something meaningful ...
    myVar=test1
done |& tee test1
echo "myVar=$myVar"

输出:

myVar=

与此同时,我找到了一种更好的方法:当我切换到文件重定向进程替换的组合时,变量定义可以正常工作。

for i in 1 2 3 ; do 
    # ... do something meaningful ...
    myVar=test2
done > >(tee test2    ) \
    2> >(tee test2 >&2)
echo "myVar=$myVar"

输出:

myVar=foo

但我想明白,为什么: - )

  1. 为什么第一个例子中的值会丢失?
  2. 为什么它不会在第二次迷失?
  3. 你知道吗?

1 个答案:

答案 0 :(得分:1)

As 123 said管道创建子shell(新范围),子shell无法访问父shell的变量。

以下辅助函数显示shell的PID和变量a的值。

show_a () { echo $BASHPID: a=$a >&2; }

以下示例不创建子shell,因为仅使用重定向。只使用了一个变量a

$ a=1; show_a; { a=2; show_a; } > /dev/null ; show_a
31072: a=1
31072: a=2
31072: a=2

但是这个例子创建了一个子shell,因为管道。每个流程都有自己的变量a

$ a=1; show_a; { a=2; show_a; } | tee ; show_a
31072: a=1
6375: a=2
31072: a=1