问题描述
unset v
function f {
v=1
}
f | cat
echo v=$v
f
echo v=$v
为什么管道(到任何命令)会阻止第一个 echo 命令打印 1?第二个 echo 打印 1.我正在使用 bash shell.我可以通过复制/粘贴或将其作为脚本运行来查看.
Why does piping (to any command) prevent the first echo command from printing 1? The second echo prints 1. I'm using a bash shell. I can see this by copy/paste or by running this as a script.
推荐答案
管道的所有组件(如果有多个)都在一个子 shell 中执行,并且它们的变量赋值不会持续到主 shell.
All components of a pipeline (if more than one) are executed in a subshell, and their variable assignments do not persist to the main shell.
这样做的原因是 bash 不支持真正的多线程(并发访问变量),只支持并行运行的子进程.
The reason for this is that bash does not support real multithreading (with concurrent access to variables), only subprocesses which run in parallel.
如何避免这种情况:
您必须在 main bash 进程中执行您想要保留的任何变量分配(或找到某种方法将它们转移到那里).这样做的 bash 方法不是使用管道,而是使用进程替换:
You have to do any variable assignments you want to retain in the main bash process (or find some way to transfer them there). The bash way of doing this would be not to use a pipe, but use process substitution instead:
f > >( cat )
当然,如果您需要在管道的两个进程中进行变量赋值,这将无济于事.那你就得想一个更好的机制来代替(也许是协程,把变量输出到某处?)
Of course, this will not help if you need to do variable assignments in both processes of a pipe. Then you have to think of a better mechanism instead (maybe coprocesses, and output the variables somewhere?)
这篇关于bash 管道防止全局变量分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!