python-使用管道时子进程调用未终止

python-使用管道时子进程调用未终止,python,linux,performance,subprocess,Python,Linux,Performance,Subprocess,我对python 2.6.5有一个奇怪的问题。如果我打电话 p = subprocess.Popen(["ifup eth0"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() 当接口eth0关闭时,python程序挂起。“p.communicate()”需要一分钟或更长时间才能完成。如果之前接口已打开,则程序运行平稳。我从命令行手动测试了两种情况下的“ifup et

我对python 2.6.5有一个奇怪的问题。如果我打电话

p = subprocess.Popen(["ifup eth0"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
当接口eth0关闭时,python程序挂起。“p.communicate()”需要一分钟或更长时间才能完成。如果之前接口已打开,则程序运行平稳。我从命令行手动测试了两种情况下的“ifup eth0”及其闪电般的速度

如果你知道问题出在哪里,我将非常感激

提前谢谢

编辑:

根据答案,我尝试了以下几点:

p = subprocess.Popen(["ifup", "eth0"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
如果接口之前启动过,SKcript将平稳运行。但是,如果接口关闭,python将再次挂起。我还尝试:

p = subprocess.Popen(["ifup", "eth0"], shell=False)
out, err = p.communicate()
而且一切都运行得非常快。因此,正如funktku指出的那样,它可能确实与僵局有关。然而,python文档还指出:

警告

这将在使用时死锁 标准输出=管道和/或标准输出=管道和 子进程生成足够的输出 连接到管道上,以阻止等待 让OS管道缓冲区接受更多 数据。使用communicate()可以避免这种情况

因此,不应该出现僵局。隐马尔可夫模型。。。以下是我在命令行上运行程序时的详细输出:

1个案例,接口eth0已启动:

ifup eth0
Interface eth0 already configured
2种情况下,界面关闭前:

ifup eth0 
ssh stop/waiting
ssh start/running
因此,ifup命令生成两行输出,以防之前接口关闭,否则生成一行输出。这是我注意到的唯一区别。但我怀疑这是问题的原因,因为“ls-ahl”会导致更多的输出线路,并且运行得非常好

我还尝试使用buffersize参数,但没有成功,将其设置为一些较大的值,如4096

你有什么想法吗?原因可能是什么?或者这可能是python管道处理或ifup命令本身中的错误?我真的必须使用旧的os.popen(cmd.read()

EDIT2:

os.popen(cmd.read()也有同样的问题。知道如何在命令行上测试ifup的管道行为吗

我感谢您的每一个提示,请提前感谢

您应该在
子流程.call
方法下查看。这可能是你问题的原因

警告

像Popen.wait()一样,这将 使用stdout=PIPE和/或时出现死锁 stderr=管道和子进程 为这样的管道生成足够的输出 它会阻止等待操作系统管道 缓冲区以接受更多数据

设置
shell=False
,您不需要它

尝试运行此代码,它应该可以工作。注意两个参数在列表中是如何独立的元素。

这就是为什么read()会等待fds(stdin/stdout/stderr)关闭。
您可以分离stdin/stderr/stdout(不要将stdout=subprocess.PIPE和相同的内容添加到Popen构造函数调用中)。

您能在回答中引用警告吗?外部页面的内容可能会随着时间的推移而改变。非常感谢您的回答,但是根据我所做的测试,死锁不应该是问题所在,正如我在文章编辑部分所解释的。如果您还有其他想法,我将非常感谢您的来信。非常感谢你的回答,你完全正确,我不需要schell=True。然而不幸的是,上面的代码不起作用。Python仍然挂断。请看我在帖子中添加的附加部分…我仍然有这个问题:-(哇,已经三年了,但这可以解释这个问题。非常感谢!
p = subprocess.Popen(["ifup", "eth0"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()