在单独进程组挂起中运行Fabric命令

时间:2016-07-29 20:08:38

标签: python subprocess multiprocessing fabric

我无法理解为什么会挂起。我已将此示例拆分为核心组件。我有一个文件,我们称之为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)

非常感谢任何见解。

1 个答案:

答案 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.pyPopen.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,但是这样   没有证件。