python subprocess pipe_Python2.x subprocess.Popen的Broken pipe解决方法

考虑如下代码:

#!/usr/bin/env python

p1 = Popen(["cat", "somebigfile"], stdout = PIPE)

p2 = Popen(["head"], stdin = p1.stdout, stdout = PIPE)

print p2.communicate()[0]

会出现

cat: write error: Broken pipe

原因是在Unix-like系统中,Python启动就会SIG_IGN掉SIG_PIPE,致使cat获取不了SIG_PIPE信号,还向已关闭的管道写入。很久之前就有人提出这个BUG了,这个BUG在Python 3.x已经修复,但是一直没有在Python 2.x实现。

解决方法如下:

1. 下载对应版本的Python源码,找到Lib\subprocess.py(我发现2.6.x的跟2.7.x的就不同)

2. 把该文件放到项目文件夹,改名为sub.py

3. 作如下改动:

--- /usr/lib/python2.6/subprocess.py 2010-04-16 21:58:41.000000000 +0800

+++ sub.py 2011-08-26 17:45:57.576284992 +0800

@@ -429,7 +429,7 @@

import fcntl

import pickle

-__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"]

+__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError", "_eintr_retry_call"]

try:

MAXFD = os.sysconf("SC_OPEN_MAX")

4. 新建new_subprocess.py, 建立Popen_new类,继承原来subprocess的Popen,并把sub.py里面Popen类的POSIX版本的_execute_child方法copy过来。

5. 在

if cwd is not None:

os.chdir(cwd)

后面加上如下代码:

import signal

signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ')

for sig in signals:

if hasattr(signal, sig):

signal.signal(getattr(signal, sig), signal.SIG_DFL)

(此处有一个示例,Python 2.6.5版本的)

6. 在项目里from new_subprocess import Popen_new as Popen

即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值