Bash:日志记录会影响变量范围吗?

Bash: Can Logging Influence Variable Scope?

在我当前的项目中,我 运行 一个循环在执行期间定义了一个稍后需要的变量。 一切正常,直到我想用 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. 为什么一秒不迷路?

你能说出来吗?

一个管道创建了一个子 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