我正在尝试将shell脚本移植到可读性更强的python版本。原来的shell脚本使用“&”在后台启动几个进程(实用程序、监视器等)。如何在python中实现相同的效果?我希望这些进程在python脚本完成时不死亡。我确信这与守护进程的概念有关,但我不知道如何轻松地做到这一点。


当前回答

使用subprocess. popen()和close_fds=True参数,这将允许派生的子进程从Python进程本身分离出来,即使在Python退出后也能继续运行。

https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f

import os, time, sys, subprocess

if len(sys.argv) == 2:
    time.sleep(5)
    print 'track end'
    if sys.platform == 'darwin':
        subprocess.Popen(['say', 'hello'])
else:
    print 'main begin'
    subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)
    print 'main end'

其他回答

注:与2009年发布的答案相比,这个答案没有那么流行。现在建议在文档中使用其他答案中显示的subprocess模块

(注意,subprocess模块为生成新进程和检索其结果提供了更强大的功能;使用该模块比使用这些函数更可取。)


如果你想让你的进程在后台启动,你可以使用system()并像你的shell脚本一样调用它,或者你可以衍生它:

import os
os.spawnl(os.P_DETACH, 'some_long_running_command')

(或者,你也可以试试不那么便携的操作系统。P_NOWAIT国旗)。

请在这里查看文档。

你可以使用

import os
pid = os.fork()
if pid == 0:
    Continue to other code ...

这将使python进程在后台运行。

虽然jkp的解决方案是可行的,但较新的做事方式(以及文档推荐的方式)是使用子流程模块。对于简单的命令,它是等效的,但是如果您想执行一些复杂的操作,它提供了更多的选项。

举个例子:

import subprocess
subprocess.Popen(["rm","-r","some.file"])

这将运行rm -r some。文件在后台。注意,在Popen返回的对象上调用. communication()将阻塞直到它完成,所以如果你想让它在后台运行,就不要这样做:

import subprocess
ls_output=subprocess.Popen(["sleep", "30"])
ls_output.communicate()  # Will block for 30 seconds

请在这里查看文档。

另外,需要澄清的一点是:你在这里使用的“Background”纯粹是一个shell概念;从技术上讲,您的意思是希望在等待进程完成时不阻塞地生成进程。但是,我在这里使用的“background”指的是类似shell-background的行为。

使用subprocess. popen()和close_fds=True参数,这将允许派生的子进程从Python进程本身分离出来,即使在Python退出后也能继续运行。

https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f

import os, time, sys, subprocess

if len(sys.argv) == 2:
    time.sleep(5)
    print 'track end'
    if sys.platform == 'darwin':
        subprocess.Popen(['say', 'hello'])
else:
    print 'main begin'
    subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)
    print 'main end'

我还没有尝试过这个,但使用.pyw文件而不是.py文件应该有帮助。Pyw文件没有控制台,所以理论上它不应该像后台进程一样出现和工作。