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
但我想明白,为什么:-)
- 为什么第一个示例中的值丢失了?
- 为什么一秒不迷路?
你能说出来吗?
一个管道创建了一个子 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
在我当前的项目中,我 运行 一个循环在执行期间定义了一个稍后需要的变量。
一切正常,直到我想用 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
但我想明白,为什么:-)
- 为什么第一个示例中的值丢失了?
- 为什么一秒不迷路?
你能说出来吗?
以下辅助函数显示 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