如何在Python中启动后台进程?

我试图将一个shell脚本移植到更易读的python版本。 原始的shell脚本在后台用“&”启动几个进程(实用程序,监视器等)。 我怎样才能在python中实现相同的效果? 我希望这些进程在python脚本完成时不会死掉。 我确信它与某个守护进程的概念有关,但是我找不到如何轻松地做到这一点。

注意 :这个答案比在2009年发布时要少。使用其他答案中显示的subprocess模块现在推荐在文档中

(请注意,子进程模块提供了更强大的工具来生成新进程并检索其结果;使用该模块比使用这些函数要好)。


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

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

(或者,也可以尝试使用便携式的os.P_NOWAIT标志)。

请参阅这里的文档 。

当jkp的解决方案工作时,更新的方式(和文档建议的方式)是使用subprocess模块。 对于简单的命令来说它是等价的,但是如果你想做一些复杂的事情,它提供了更多的选择

您的案例示例:

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

这应该在后台运行rm -r somefile但要小心:如果python脚本中没有任何内容依赖于正在运行的命令的输出,则subprocess.Popen()仅在后台运行进程:

例如,下面的命令不会在后台运行:

 import subprocess ls_output=subprocess.Popen(["ls", "-a"], stdout=subprocess.PIPE) 

请参阅这里的文档。

此外,澄清一点:“背景”纯粹是一个壳概念:你可能想要的是产生一个新的过程。 我在这里使用了“背景”来引用类似shell的背景行为,但不要把这个错误理解为实际处于后台的进程。

您可能需要“如何在Python中调用外部命令”的答案。

最简单的方法是使用os.system函数,例如:

 import os os.system("some_command &") 

基本上,传递给system函数的任何东西都会被执行,就像你把它传递给脚本中的shell一样。

我在这里找到了这个:

在Windows(win xp)上,父进程将不会完成,直到longtask.py完成其工作。 这不是你想要的CGI脚本。 这个问题不是特定于Python,在PHP社区中的问题是一样的。

解决方法是在win API中将DETACHED_PROCESS 进程创建标志传递给底层的CreateProcess函数。 如果你碰巧安装了pywin32,你可以从win32process模块​​导入标志,否则你应该自己定义它:

 DETACHED_PROCESS = 0x00000008 pid = subprocess.Popen([sys.executable, "longtask.py"], creationflags=DETACHED_PROCESS).pid 

您可能想要开始调查os模块以分化不同的线程(通过打开交互式会话并发出帮助(os))。 相关的功能是fork和任何exec。 为了给你一个关于如何开始的想法,把这样的东西放在一个执行fork的函数中(函数需要把一个列表或元组作为一个参数来包含程序的名字和参数;你可能也想要为新线程定义stdin,out和err):

 try: pid = os.fork() except OSError, e: ## some debug output sys.exit(1) if pid == 0: ## eventually use os.putenv(..) to set environment variables ## os.execv strips of args[0] for the arguments os.execv(args[0], args) 

使用close_fds=True 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'