我无法理解为什么会挂起。我已将此示例拆分为核心组件。我有一个文件,我们称之为do_ls.py
import fabric.api
import time
host = "myhost.mydomain"
username = "username"
password = "password"
def main():
with fabric.api.settings(host_string=host,user=username,password=password):
result = fabric.api.run("ls")
if __name__ == "__main__":
main()
如果我运行此命令:python do_ls.py
它将正确执行。现在为了这个问题。我想在它自己的过程中运行它。所以我有这个文件,我们称之为main.py
import sys
import os
import logging
import subprocess as sp
import time
def main():
logging.basicConfig(level=logging.DEBUG)
cmd = [sys.executable, "/path/to/do_ls.py"]
p = sp.Popen(cmd, preexec_fn=os.setpgrp)
while p.poll() is None:
print "Sleeping..."
time.sleep(0.5)
print "All Done."
if __name__ == "__main__":
main()
现在,如果我运行python main.py
,这将永远挂起。据我所知,问题是我在一个子组中运行该过程(即如果我取出preexec_fn=os.setpgrp
那么它将正常工作)。我不明白的是,为什么会这样。特别考虑到以下工作:
cmd = ["ssh", "-q", "username@hostname", "ls"]
p = sp.Popen(cmd, preexec_fn=os.setpgrp)
非常感谢任何见解。
答案 0 :(得分:1)
由于以下行有效:
cmd = ["ssh", "-q", "username@hostname", "ls"]
p = sp.Popen(cmd, preexec_fn=os.setpgrp)
但main.py
不断挂起,我认为
while p.poll() is None:
永远不会评估为False
。因此p.poll()
必须始终返回None
,甚至可能在流程完成后返回sp.Popen()
。快速搜索在Python的错误报告网站上返回this conversation。根据该对话,尝试使用(未记录的)_deadstate='dead'
选项调用os.wait()
:
问题是
subprocess.py
与Popen.poll()
的效果不佳。Popen.wait()
和os.waitpid(pid, ...)
会使用os.wait()
如果Popen.poll()
已报告pid,则引发OSError。p.popen(_deadstate='dead')
吞下OSError,默认情况下返回None。您可以(使用)修复您的程序
p.popen()
取代poll()
。这将使 如果OSError被捕获,'dead'
会返回None
而不是Actions
,但是这样 没有证件。