Subprocess.Popen 在解释器、可执行脚本中的行为不同
假设您有以下内容:
command = shlex.split("mcf -o -q -e -w %s %s" % (SOLFILE, NETFILE))
task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = task.communicate()
print "stdout: %s" % stdout #debugging
print "stderr: %s" % stderr #debugging
if stderr:
sys.exit("MCF crashed on %s" % NETFILE)
没有必要知道 mcf 是什么,只是它是一个 C 程序,如果没有给出令人满意的网络文件,它就会溢出。 (为什么我不能确保所有网络文件都是可满足的?好吧,因为检查这一点的最简单方法是将其提供给 mcf 并查看它是否溢出...)
无论如何,当我在可执行脚本中运行它时, task.communicate() 似乎没有在 stdout 和 stderr 中存储任何内容。 (准确地说,我得到 stdout == stderr == ''。)相反,来自 mcf 的 stderr 流似乎“泄漏”到终端,而不是被子进程管道捕获。下面是一些示例输出来说明:
Netfile: facility3cat_nat5000_wholesaler_capacitation_test_.net
Solfile: facility3cat_nat5000_wholesaler_capacitation_test_.sol
*** buffer overflow detected ***: mcf terminated
======= Backtrace: =========
...
...[fifty lines of Linda Blair-esque output]...
...
stdout: None
stderr:
...[program continues, since stderr did not evaluate to True]...
仅当从命令行运行脚本时才会失败。当我在解释器中逐行执行它时,stdout 和 stderr 被正确分配:
>>> task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> stdout, stderr = task.communicate()
>>> stderr
'*** buffer overflow detected ***: mcf terminated\n======= Backtrace: =========\n'
...[more headspinning and vomit]...
任何人都可以帮助我理解为什么这在解释器中有效,但在执行时却不起作用?提前致谢!
Let's say you have the following:
command = shlex.split("mcf -o -q -e -w %s %s" % (SOLFILE, NETFILE))
task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = task.communicate()
print "stdout: %s" % stdout #debugging
print "stderr: %s" % stderr #debugging
if stderr:
sys.exit("MCF crashed on %s" % NETFILE)
It's not necessary to know what mcf is, except that it's a C program which will overflow if it's not given a satisfiable netfile. (Why can't I just ensure that all the netfiles are satisfiable? Well, because the easiest way to check that is to feed it to mcf and see if it overflows...)
Anyway, when I run this in an executable script, task.communicate() doesn't seem to store anything in stdout and stderr. (To be precise, I get stdout == stderr == ''.) Instead, the stderr stream from mcf seems to be "leaking" to the terminal rather than getting captured by the subprocess pipe. Here's some sample output to illustrate:
Netfile: facility3cat_nat5000_wholesaler_capacitation_test_.net
Solfile: facility3cat_nat5000_wholesaler_capacitation_test_.sol
*** buffer overflow detected ***: mcf terminated
======= Backtrace: =========
...
...[fifty lines of Linda Blair-esque output]...
...
stdout: None
stderr:
...[program continues, since stderr did not evaluate to True]...
This only fails when running the script from the command line. When I step through it line by line in the interpreter, stdout and stderr are correctly assigned:
>>> task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> stdout, stderr = task.communicate()
>>> stderr
'*** buffer overflow detected ***: mcf terminated\n======= Backtrace: =========\n'
...[more headspinning and vomit]...
Could anyone help me to understand why this works in the interpreter, but not when executed? Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我编写了一个小测试脚本来测试
subprocess
模块。然后我编写了一个小的 Python 脚本来调用它:
运行它的输出如下所示:
在 ipython 中运行相同序列的输出是相同的。
因此,
subprocess
模块的行为方式符合您的预期,而不是它在您的问题中的行为方式。我认为除了subprocess
模块之外的其他东西一定是有问题的,因为你正在做的事情对我有用。我正在运行 Python 2.7,所以另一种可能性是旧版本的
subprocess
模块中可能存在某种奇怪的错误。I wrote a little test script to test the
subprocess
module with.Then I wrote a small Python script that calls it:
The output of running it looks just like this:
The output of running that same sequence in
ipython
is the same.So the
subprocess
module is behaving in the manner you expect, and not how it's behaving for you in your question. I think something other than thesubprocess
module must be at fault here because what you're doing works for me.I'm running Python 2.7, so another possibility is that maybe there is some kind of weird bug in older versions of the
subprocess
module.