我对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()
如果之前接口已启动,则skript运行顺利。但是如果接口关闭,python会再次挂起。我也尝试过:
p = subprocess.Popen(["ifup", "eth0"], shell=False)
out, err = p.communicate()
一切都快速完成。因此,它可能确实与死锁有关,正如funktku所指出的那样。但是python文档也说python ref:
警告
使用时会死锁 stdout = PIPE和/或stderr = PIPE和 子进程生成足够的输出 到管道,以阻止等待 为OS管道缓冲区接受更多 数据。使用communic()来避免这种情况。
因此不应该出现死锁。嗯......这是我在命令行上运行程序时的详细输出:
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的管道行为吗?
我很感激每一个提示,提前谢谢
答案 0 :(得分:2)
您应该查看subprocess.call
方法下的warning。这可能是您遇到问题的原因。
警告
与Popen.wait()一样,这样会 使用stdout = PIPE和/或时死锁 stderr = PIPE和子进程 为管道产生足够的输出 它阻止等待OS管道 缓冲区接受更多数据。
答案 1 :(得分:1)
p = subprocess.Popen(["ifup", "eth0"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
设置shell=False
,您不需要它。
尝试运行此代码,它应该工作。注意两个参数是如何在列表中单独的元素。
答案 2 :(得分:1)
/etc/network/if-up.d/ntpdate does not detach correctly
这就是为什么read()等到fds(stdin / stdout / stderr)关闭的原因。 你可以分离stdin / stderr / stdout(不要添加stdout = subprocess.PIPE和Popen构造函数调用相同)。