【发布时间】:2018-09-22 12:22:00
【问题描述】:
在考虑如何在我自己的一个程序中实现某个功能时,我一直想知道 bash 如何在内部处理以下性质的管道:
yes | sleep 10
这显然没有任何作用,但我不明白这不会导致错误。我会认为要么:
因为
sleep不从标准输入读取,连接两个进程的管道会填满并导致yes在尝试写入现在已满的管道时无限期阻塞如果使用非阻塞 IO,如果首先执行
yes并在sleep进程甚至运行之前写入管道并且因此没有进程连接到管道
我想这是我的一些重大误解。我试过查看 bash 源代码,但那已经超出了我的想象。
【问题讨论】:
-
在我的系统上我得到
yes: standard output: Broken pipe,你不明白吗?如果你的意思是为什么$?等于0,那是因为你没有设置-o pipefail,见here。管道的退出状态是最右边命令的状态,sleep 10返回成功。并且管道上的正确进程首先(及时)运行,因为首先需要一个进程在标准输入上监听,以便另一个进程开始发送。 -
即使
yes被阻止写入一个完整的管道,为什么会导致错误?它将继续尝试直到管道消失,此时您将收到 Kamil Cuk 报告看到的错误。您希望看到什么错误? -
我没有收到那个错误(我在 Arch 上使用 bash 4.4.23)。我原以为即使在读取文件描述符关闭后写入完整管道也会阻塞,但我想可能不是这样,我想我可能会尝试一下。此外,我不太确定必须先运行正确的进程,在我的系统上,构成管道的命令并不总是从右到左启动。