使用 fifos/命名管道时的随机 141 信号

loo*_*une 5 linux io bash named-pipes mkfifo

我理解 fifos 的方式,读取器或写入器的打开会阻塞,直到另一侧也打开,读取会阻塞,直到有人写入,并且当另一侧的最后一个关闭时,任何一侧都会关闭,即最后一个写入器关闭,读者也会关闭,反之亦然。

假设这是一个正确的理解,请给我一个谜语:我有两个过程。一个是 bash 脚本,另一个是 python。bash 脚本mkfifo在磁盘上创建一个 fifo,并在后台启动 python 脚本,并将 fifo 的名称作为参数。

我的 python 进程有一个像这样的主循环:

while True:
    with open(fifo_path, 'r') as fifo:
        for line in fifo:
            line = line.strip()
            if len(line) == 0:
                continue
            # code to handle line here ...
Run Code Online (Sandbox Code Playgroud)

简化的 bash 脚本执行以下操作:

mkfifo test.pipe
python myscript.py test.pipe &
# code ...
echo "foo" > test.pipe
# more code
echo "bar" > test.pipe
# ...
Run Code Online (Sandbox Code Playgroud)

根据我对管道的理解应该发生什么,读取 python 脚本将挂起,直到第一个 echo(或更具体地说是脚本)打开管道进行写入。然后他们将交换“foo”字符串,当回显完成时,管道关闭,这将导致 python 脚本收到 EOF。但是,由于循环再次打开,Python 脚本将继续执行,一切都会重复。

实际发生的情况是,有时我的 bash 脚本突然退出,退出代码为 141。

我已经做了什么来调试这个:

  1. 我验证了 python 进程确实正在运行并且没有崩溃。我已经打印了每个错误,并添加了非常慷慨的 try/ except 块,以确保我不会错过任何内容。
  2. 运行脚本bash -x似乎表明它确实是以代码 141 结尾的回显。
  3. 谷歌搜索和 Stackoverflowing 暗示我 141 是 SIGPIPE 的幕后黑手,似乎没有被处理。如果是这样的话,我不明白为什么会发生以及我应该如何处理它们。根据我上面的理解,它们不应该发生。
  4. 在Python脚本开始时故意第二次打开fifo并故意泄漏fd(从不读取它)

任何提示表示赞赏。