2011-06-06 60 views
5
unset v 
function f { 
    v=1 
} 
f | cat 
echo v=$v 
f 
echo v=$v 

为什么管道(对任何命令)阻止第一个回显命令打印1?第二个回显打印1.我正在使用bash外壳。我可以通过复制/粘贴或将其作为脚本运行来查看。bash管道阻止全局变量赋值

回答

9

流水线的所有组件(如果多于一个)都在子shell中执行,并且它们的变量赋值不会保留到主shell。

原因是bash不支持真正的多线程(并发访问变量),只有并行运行的子进程。


如何避免这种

你必须做你想做的主要 bash进程保留(或找到某种方式向其传送)的任何变量赋值。这样做的bash的方法是不使用管道,但在使用过程中,而不是替代:

f > >(cat) 

当然,如果您需要在管的两个过程做变量赋值,这将于事无补。那么你不得不考虑一个更好的机制,而不是(可能coprocesses,并在某处输出变量?)

+1

实际上,这适用于管道的所有元素*包括*最后一个。 – 2011-06-06 19:37:10

+0

嗯,奇怪......我在哪里得到错误的印象?谢谢,我改变了这一点。 – 2011-06-06 20:25:48

+1

ŭlo:一些shell(ksh和zsh我认为,但不是bash)在主shell进程中运行管道的最后一个元素。 – camh 2011-06-06 21:13:57