【发布时间】:2015-03-16 12:17:17
【问题描述】:
我已经阅读了大部分关于 subprocess 和 os.fork() 的相关问题,包括所有关于双分叉技巧的讨论。但是,这些解决方案似乎都不适用于我的场景。
我想分叉一个新进程并允许父进程(通常)终止,而不会弄乱子进程的标准输入、标准输出和标准错误,也不会杀死子进程。
我的第一次尝试是使用subprocess.Popen()。
#!/usr/bin/python
from subprocess import call,Popen
Popen("/bin/bash", shell=True)
call("echo Hello > /tmp/FooBar", shell=True)
这会失败,因为一旦父进程退出,子进程就会被杀死。我知道creationflags,但这是特定于 Windows 的,我在 Linux 上运行。请注意,如果我们只是通过在其末尾添加一个无限循环来保持父进程处于活动状态,则上面的代码可以很好地工作。这是不可取的,因为父母已经完成了它的工作,没有真正的理由让它留下来。
第二次尝试是使用os.fork()。
#!/usr/bin/python
from subprocess import call
from os import fork
try:
pid = fork()
if pid > 0:
pass
else: # child process will start interactive process
call("/bin/bash", shell=True)
except:
print "Forking failed!"
call("echo Hello > /tmp/FooBar", shell=True)
这里,子进程不再与父进程一起死亡,但在父进程死亡后,子进程不能再读取输入和写入输出。
因此,我想知道如何使用完全独立的 stdout、stderr 和 stdin 分叉一个新进程。独立性意味着父进程可以(通常)终止,而子进程(无论是 bash 还是 tmux 或任何其他交互式程序)的行为就像父程序没有终止一样。更准确地说,请考虑以下原始程序的变体。
#!/usr/bin/python
from subprocess import call,Popen
Popen("/bin/bash", shell=True)
call("echo Hello > /tmp/FooBar", shell=True)
while True:
pass
上面的代码具有我所寻求的所有行为,但它人为地使 Python 进程保持活力。我正在尝试实现这种确切的行为,Python 进程不存在。
警告:我通过 ssh 运行这些应用程序,因此生成新的 GUI 窗口不是一个可行的解决方案。
期望的行为:
- 我运行 python 代码。
- 我得到了一个闪亮的新
bashshell,它的工作方式与我开始使用的 bash shell 完全一样。 - 文件
/tmp/FooBar已创建。 - 原始 Python 脚本完成。
- 我继续使用我闪亮的新 bash shell,
ps aux | grep python的输出不包括我刚刚运行的 python 脚本。
【问题讨论】:
-
(在那个 Popen 技术中)孩子是守护进程吗?如果不是,那它怎么会在父母去世后立即终止?
-
不能 >>> Popen("tmux -S /tmp/TestSmux attach-session", shell=True) 在单独的线程中完成?这个线程不能是一个守护进程,否则它不会给出想要的结果。您可以阻止该线程的 RUN 方法完成,直到您的任务完成...这样您的父进程将继续执行其工作,如果您希望在父级基于子级接收到的输入。然后你可以从父母发出信号(阻止孩子)或加入确保父母和孩子都停止。
-
1.
tmux是一个复杂的例子。如果您需要tmux;询问您遇到的具体问题。 2.您的问题是:如何模拟nohup、disown或在Python中创建一个合适的守护进程? -
@SyedMauzeRehan,我给了你完整的可重复的例子,以及我对行为的观察。它的行为就像一个守护进程,但它是一个吗?我不能说我肯定知道。
-
@SyedMauzeRehan,对于单独线程的建议,如果我不能单独使用进程,我会尝试这样做。但是,如果您认为它会起作用并且您有时间对其进行测试并确保所有用户交互都正常工作,那么欢迎您写一个答案。
标签: python linux subprocess fork