Python - 如何捕获一个断开的管道(Broken Pipe)

4

我刚刚了解到SIGPIPE,然后阅读了关于如何在Python中处理它们的内容。

除其他来源外,我还阅读了:如何在Python中处理断开的管道(SIGPIPE)?

假设读取管道的脚本退出,那么所有答案都建议编写脚本的写入调用应该包含在try子句中。

然而,我无法使其正常工作。这是我的代码:

# printer.py
import time
try:
    for i in range(10):
        time.sleep(1)
        print i
except:
    print 'We caught the problem'

并且

#nonreader.py
#read nothing, but stay alive for 5 sec
import time, sys
time.sleep(5)
sys.exit(0)

在命令行中:

$ python printer.py | python nonreader.py 
close failed in file object destructor:
Error in sys.excepthook:

Original exception was:

显然,没有捕获到任何异常。而且,当它打印“原始异常是:”后就没有了,看起来非常不对劲。
我错在哪里/我理解错了什么?
Thomas
1个回答

5

由于你正在写入如此少量的数据,所有数据都被缓冲,直到文件关闭时才会实际写入到管道中。在关闭期间,尝试将数据写入管道失败,但是您的try / except子句已经完成。如果在try / except期间刷新stdout,则应该捕获错误。(尽管因为你在except子句中写入管道,所以你不会看到它!)


这很有道理,谢谢 :) 但我不喜欢这个概念,即异常可以在代码之后“发生”。这样我就无法捕获该异常。假设我不知道刷新的事情,我只想捕获脚本中的任何问题,并将其写入日志。 - Mads Skjern
问题实际上与未显式关闭文件有关。如果您关闭文件(而不仅仅是退出并让系统为您关闭它),则会在那一点上捕获错误。 - William Pursell
谢谢您的回答,在我的问题中,我所要做的就是刷新管道的写入端,然后关闭就可以正常工作了。 - ihatecache

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接