1

在我当前的项目中,我运行了一个循环,在执行期间定义了一个稍后需要的变量。一切都很好,直到我想用 tee 添加日志记录,这样我以后也可以在文件中检查日志。因为我想同时记录标准输出和标准错误,所以我申请|&了(的快捷方式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. 为什么它不会在第二次丢失?

你能告诉?

4

1 回答 1

1

正如 123 所说,管道创建了一个子 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
于 2017-09-04T12:32:27.953 回答