Python中csvwriter经管道输出时触发BrokenPipeError的解决方法
问题分析与解决
原因解释
当你用管道将程序输出传给head时,head读取到足够行数后会立即关闭管道的读端。此时你的Python进程还在持续往管道写数据,操作系统就会抛出BrokenPipeError。而range(15)时数据量极小,所有内容在head关闭管道前就已写入缓冲区并被读取,因此不会触发异常。
解决方法
1. 恢复SIGPIPE默认行为(推荐)
Unix系统中,管道断开时会向写进程发送SIGPIPE信号,默认行为是直接终止进程。但Python会捕获这个信号并抛出BrokenPipeError。你可以在代码开头恢复默认信号处理,让进程像普通命令行工具一样正常退出:
#!/usr/bin/env python3 import csv import signal # 恢复SIGPIPE信号的默认处理逻辑 signal.signal(signal.SIGPIPE, signal.SIG_DFL) with open("/dev/stdout", "w") as f: csvwriter = csv.writer(f) csvwriter.writerows((_,) for _ in range(10000))
这样运行/tmp/test.py | head > /dev/null时,进程会直接退出,退出码为141(Unix系统中SIGPIPE对应的退出码),不会打印任何异常回溯。
2. 捕获BrokenPipeError优雅退出
如果你需要自定义退出逻辑,可以直接捕获异常并返回0退出码:
#!/usr/bin/env python3 import csv import sys try: with open("/dev/stdout", "w") as f: csvwriter = csv.writer(f) csvwriter.writerows((_,) for _ in range(10000)) except BrokenPipeError: sys.exit(0)
这种方式会让进程以0码退出,和直接重定向到文件的行为一致。
额外提示
你代码中直接打开/dev/stdout,其实可以简化为直接使用sys.stdout,效果完全相同:
csvwriter = csv.writer(sys.stdout)
内容的提问来源于stack exchange,提问作者keithpjolley
相关产品推荐
相关产品推荐

