为啥我的 Python3 脚本不愿将其输出通过管道传输到 head 或 tail(sys 模块)?

Posted

技术标签:

【中文标题】为啥我的 Python3 脚本不愿将其输出通过管道传输到 head 或 tail(sys 模块)?【英文标题】:Why does my Python3 script balk at piping its output to head or tail (sys module)?为什么我的 Python3 脚本不愿将其输出通过管道传输到 head 或 tail(sys 模块)? 【发布时间】:2012-07-10 22:57:05 【问题描述】:

我有一个 Python3 脚本,可以将其输出写入标准输出,但是当我将该输出通过管道传输到头部或尾部时它会报错。请注意,在下面的示例输出中它可以正常工作,因为 head 正在根据请求返回前两行输出。

> ./script.py '../Testdata/*indels.ss' -m 5 | head -2                                                                                              ~/Databases/Avian_genomes/Sandbox/combined
xread
2999 50
Traceback (most recent call last):
  File "./new.py", line 194, in <module>
    sys.stdout.write(lineout)
IOError: [Errno 32] Broken pipe
Exception IOError: IOError(32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored

相比之下,该脚本在将其输出通过管道传送到 awk 方面没有问题,如下所示。

> ./script.py '../Testdata/*indels.ss' -m 5 | awk 'NR < 3 print $0'                                                                              ~/Databases/Avian_genomes/Sandbox/combined
xread
2999 50

如果您需要脚本中的某些代码超出错误消息中包含的内容,请告诉我。我不确定什么是相关的。

【问题讨论】:

你的第三行是否有 Unicode 字符? 另见: ***.com/questions/15793886 其实IOError: [Errno 32] Broken pipe when piping: prog.py | othercmd似乎是这个问题最活跃的版本。 【参考方案1】:
./script.py '../Testdata/*indels.ss' -m 5 | awk 'NR >= 3 exit 1'

将显示与head -2 相同的行为。

您可以将SIGPIPE 处理程序设置为安静地杀死您的程序的处理程序:

import signal
signal.signal(signal.SIGPIPE, signal.SIG_DFL)

【讨论】:

但请注意,这会杀死你的程序。如果您的程序正在报告它正在执行的操作的状态,添加此代码意味着您的程序现在将在通过 head 运行时默默地无法完成其工作。【参考方案2】:

我会引用here:

如果管道中出现一系列命令,并且其中一个

读取命令在写入器完成之前完成,

writer 收到一个 SIGPIPE 信号。

head 就是这样做的。你的脚本还没有写完,但是head已经写好了,所以stdout被关闭了,所以出现了异常。

【讨论】:

我认为可能是这样的。感谢您的解释和参考。

以上是关于为啥我的 Python3 脚本不愿将其输出通过管道传输到 head 或 tail(sys 模块)?的主要内容,如果未能解决你的问题,请参考以下文章

持久的子进程管道 - 没有读取标准输出

如何检测我的 shell 脚本是不是通过管道运行?

为啥我的输入通过管道发送到进程时会延迟?

shell脚本0——一切皆文件与管道

从损坏的管道读取时,管道 Python 脚本占用 100% 的 CPU

可能的竞争条件,来自多个 tee 接收者的管道输出在 BASH 脚本中的命名管道上无序到达