微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在bash中的输出捕获函数中,{} 1>&2和()1>&2之间有什么区别

> with {} – 在当前 shell中执行while循环

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"

– >显示循环后

– >返回显示

解决方法

输出关闭时打开FIFO时,命令替换不会返回.

重定向子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 举报,一经查实,本站将立刻删除。

相关推荐