当我直接在终端中跑:
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 ......
答案 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,但这不起作用。