Python Popen等待它不应该(bg和输出重定向)

时间:2014-01-10 11:54:52

标签: python background-process popen output-redirect

当我直接在终端中跑:

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参数不是解决方案。


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

但是,使用ssh时,行为或多或少会自动显示:

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

(我可以没有密码ssh到这个地址)。因此,解决Python问题并非完全不可能;现在我需要一种方法来做到没有ssh ......

2 个答案:

答案 0 :(得分:1)

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

您通常不会意识到这种情况正在发生,因为您通常在的 shell中进行背景操作。您将一个进程放在后台,这样您就可以再次控制shell并继续使用它。

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

答案 1 :(得分:1)

正如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-process会继续运行。欲望行为实现了!

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

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

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