function f { { while : ; do echo -n a; done & } 1>&2 } a=$( f ); echo "returned"
– > f()永远不会回来!
>()在子shell中执行while循环
function f { ( while : ; do echo -n a; done & ) 1>&2 } a=$( f ); echo "returned"
– > f()将返回!!!
我的分析:
while循环将分叉并开始自己的后台进程,因为结尾&在while循环线上.此后台进程继承当前打开的fd列表.
据我所知,由于while循环是封装的,它继承了封装的fd列表.这是怎么回事
{ echo log; echo err 1>&2; } 1>l_file 2>e_file
按预期工作,l_file将包含“log”,e_file将包含“err”.
因此,在{} 1>& 2或()1>& 2的情况下,bash被告知它应该期望没有stdout被捕获.
为什么它会在{} 2>& 1情况下阻止?
>一些评价顺序之谜?
>也许明确关闭stdout会有帮助吗?我不知道语法,但是,{} 1>& – 1>& 2会有帮助吗?
GNU bash,版本4.3.30(1)-release(x86_64-pc-linux-gnu)
编辑
根据目前为止的答案,我做了一些分析:
11){}
function f { { while : ; do echo -n a; done & echo "after loop" } 1>&2 echo "end of function" } a=$( f ); echo "returned"
– >显示循环后
12)()
function f { ( while : ; do echo -n a; done & echo "after loop" ) 1>&2 echo "end of function" } a=$( f ); echo "returned"
– >显示循环后
– >返回显示
解决方法
重定向子shell时,该子shell不包含指向原始FD的文件描述符;它没有任何需要,因为重定向将由子shell终止隐式结束.
重定向块时,块需要保留原始描述符的副本以在退出时恢复.因此,将存在自动分配的文件描述符,其存储原始(预重定向)标准输出的副本,并且该FD的存在阻止FIFO使写端结束.
观察差异:
f() { ls -l "/proc/$BASHPID/fd" } out1=$( ( f; ) 2>&1; ) out2=$( { f; } 2>&1; )
在上面,out1可以(剥离不相关的字段)看起来像:
0 -> /dev/pts/0 1 -> pipe:[1146313] 2 -> pipe:[1146313] 255 -> /dev/pts/0
…而out2可能在类似的条件下看起来像:
0 -> /dev/pts/0 1 -> pipe:[1146327] 10 -> /dev/pts/0 2 -> pipe:[1146327] 255 -> /dev/pts/0
注意附加的FD 10,存储要恢复的备份.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。