【问题标题】:Python Popen waiting while it shouldn't (bg and output redirected)Python Popen 在不应该等待的情况下等待(bg 和输出重定向)
【发布时间】:2014-01-29 09:23:20
【问题描述】:

当我直接在终端中运行时:

echo "useful"; sleep 10 &> /tmp/out.txt & echo "more";

在后台进行睡眠时,我得到了两个输出。我对 Popen (python 2.7) 也有同样的行为:

p = Popen('echo "useful"; sleep 10 &> /tmp/out.txt & echo "more";', shell = True, stdout = PIPE, stderr = PIPE)
print p.communicate()

据我了解,具有重定向 stdout 和 stderr 的后台进程可以实现这一点,但事实并非如此;我得等着睡觉。谁能解释一下?

我需要其他输出,因此在 Python 中更改 stdout/stderr 参数不是解决方案。


编辑:我现在明白我想要的行为(获取输出但在没有更多输出时停止而不是在完成时停止)在 Python 中是不可能的。

但是,当使用 ssh 时,该行为或多或少会自动出现:

ssh 1.2.3.4 "echo \'useful\'; cd ~/dicp/python; nohup sleep 5 &> /tmp/out.txt & echo \'more\';"

(我可以在没有密码的情况下 ssh 到这个地址)。因此,围绕 Python 工作并非完全不可能;现在我需要一种不使用 ssh 的方法...

【问题讨论】:

    标签: python background-process popen output-redirect


    【解决方案1】:

    那是因为shell 进程仍然需要等待后台进程完成。

    您通常不会意识到这种情况正在发生,因为您通常是在 后台运行某些内容的 shell 中工作的。您将一个进程置于后台,这样您就可以再次控制 shell 并继续使用它。

    换句话说,后台进程是相对于 shell 的,而不是你的 Python 进程。

    【讨论】:

    • 我是否理解我的 Python 代码不等待就无法继续?即使没有打开的stdout/stderr?
    • 但我希望它阻塞,直到所有具有正常(未重定向)stdout/stderr 的命令都完成。这样的组合是否可能(一个 Popen 调用)?
    • 换句话说:除非您想要读取进程产生的所有输出并等待它退出,否则您根本不必调用communicate()。您可以致电p.poll() 来检查它是否仍在运行(非阻塞调用)。
    • 不,你不能那样做。将您希望在后台运行的进程与您需要与之通信的进程分开。
    【解决方案2】:

    正如 Martijn Pieters 所指出的,这不是 Python 的行为方式(或本应如此)。但是,由于在使用 nohup 通过 ssh 运行命令时会出现所需的行为,所以我发现了这个类似的技巧:

    p = Popen('bash -c "echo \'useful\'; cd ~/dicp/python; nohup sleep 5 &> /tmp/out.txt & echo \'more\';"', shell = True, stdout = PIPE, stderr = PIPE)
    print p.communicate()
    

    因此,如果我理解正确,这将启动一个新的 shell (bash -c),然后启动一个未附加到它的进程 (nohup)。一旦所有其他进程完成,shell 就会终止,但 nohup 进程会继续运行。愿望行为实现!

    可能不漂亮,也可能效率不高,但它确实有效。

    编辑:当然,假设您使用的是 bash。欢迎提供更一般的答案。

    EDIT2:实际上,如果我的解释是正确的,我不确定为什么 nohup 即使不使用 bash -c 也不会分离进程...似乎 bash -c 将是多余的,只需将其从 shell 中分离开始通过 Popen,但这不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 2019-02-01
      • 2020-01-23
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      相关资源
      最近更新 更多