'yes'子进程的报告错误communications() [英] 'yes' reporting error with subprocess communicate()
问题描述
我使用以下函数在Python中运行命令:
def run_proc(cmd):
child = subprocess.Popen(cmd,shell = True,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
stdout,stderr = child.communicate()
returncode = child.returncode
return stdout,stderr,returncode
它一直工作正常,但现在我想使用 yes
程序将输出管道输出到stdin。我试图运行的命令如下:
yes''| apt-get -y -o Dpkg :: Options :: = - force-confdef-o Dpkg :: Options :: = - force-confolddist-upgrade
但我相信它可以替换为一般的例子,如:
yes |头-3 |我的问题是,如果我尝试运行任何命令,
是的,我的问题是,如果我尝试运行任何命令,
|
在其中,上面的子进程.popen将包含错误消息::破损的管道
是:写入错误
对我来说,管道似乎仍然工作,从
yes |中可以看出头-3 | cat
的回答:yyy
。
我有以下问题: p>
- 是管道仍然有效,即使是报告错误吗?
- 如何解决?
解决方案问题是
subprocess
模块在Python 3.2+之前不会还原SIGPIPE
信号处理程序默认操作。这就是为什么你会得到EPIPE
写入错误。
在Python 3.2中
>> from subprocess import check_output
>>>> check_output(yes | head -3,shell = True)
b'y \\\
y\\\
y\\\
'
$当
head
时,由
SIGPIPE
/ code>退出。
在Python 2中:
>>>> from subprocess import check_output
>>>> check_output(yes | head -3,shell = True)
是:标准输出:管道损坏
是:写入错误
'y \\\
y\\\
y\\\
'
$为了解决这个问题,你可以在Python 2中使用
是
获得EPIPE
写入错误。忽略错误是安全的。 它与SIGPIPE
传递相同的信息。preexec_fn
来模拟restore_signals
参数:>>> from subprocess import check_output
>>>> import signal
>>>> def restore_signals():#from http://hg.python.org/cpython/rev/768722b2ae0a/
... signals =('SIGPIPE','SIGXFZ','SIGXFSZ')
。 .. for sig in signals:
...如果hasattr(signal,sig):
... signal.signal(getattr(signal,sig),signal.SIG_DFL)
.. 。
>>>> check_output(yes | head -3,shell = True,preexec_fn = restore_signals)
'y \\\
y\\\
y\\\
'
I am using the following function to run a command in Python:
def run_proc(cmd): child = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = child.communicate() returncode = child.returncode return stdout, stderr, returncode
It has always been working fine, however now I'm trying to use the
yes
program to pipe output to stdin. The command I'm trying to run is the following:yes '' | apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
but I believe it could be substituted with a general example, like:
yes | head -3 | cat
My problem is that if I try to run any command which has
yes |
in it, the above subprocess.Popen will contain the error messages:yes: standard output: Broken pipe yes: write error
For me it seems that the piping still works, as can be seen from
yes | head -3 | cat
's answer:y y y
.I have the following questions:
- Is the yes piping still functional, even though yes reports error?
- How can I fix it?
解决方案The issue is that
subprocess
module before Python 3.2+ doesn't restoreSIGPIPE
signal handler to default action. That is why you getEPIPE
write error instead.In Python 3.2+
>>> from subprocess import check_output >>> check_output("yes | head -3", shell=True) b'y\ny\ny\n'
yes
is killed bySIGPIPE
whenhead
exits.In Python 2:
>>> from subprocess import check_output >>> check_output("yes | head -3", shell=True) yes: standard output: Broken pipe yes: write error 'y\ny\ny\n'
yes
gotEPIPE
write error. It is safe to ignore the error. It communicates the same information asSIGPIPE
.To workaround the problem, you could emulate
restore_signals
in Python 2 usingpreexec_fn
parameter :>>> from subprocess import check_output >>> import signal >>> def restore_signals(): # from http://hg.python.org/cpython/rev/768722b2ae0a/ ... signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ') ... for sig in signals: ... if hasattr(signal, sig): ... signal.signal(getattr(signal, sig), signal.SIG_DFL) ... >>> check_output("yes | head -3", shell=True, preexec_fn=restore_signals) 'y\ny\ny\n'
这篇关于'yes'子进程的报告错误communications()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!