Python 程序仍然 运行 但找不到 PID

Python program still running but PID can't be found

我是 运行 一个独立于我的父程序后台的子程序。在我退出父程序后,我希望子程序继续 运行 并登录 OUTPUT_PATH。事实上,我可以看到日志文件正在更新。然而,当我试图从 ps aux 中找到 PID 时,我找不到它。谁能解释这种行为?我做错了什么?

 shellCommand = "nohup python PYTHON_PROGRAM ARGS >OUTPUT_PATH 2>&1 &" 
 subprocess.Popen(shellCommand, shell=True, preexec_fn=os.setpgrp) 

好的,这对于评论来说太大了。通过 运行ning ps -fwp $(pgrep -f PYTHON_PROGRAM),我们现在已经找到了进程。 :) 但它的 PID 与 Popen.pid 报告的不匹配。这将归结为自您使用 shell=True 以来调用的 shell 个实例。第一个 fork 是调用 shell,第二个是你的脚本。实际上,这在上面提到的 link 中有记录:

Note that if you set the shell argument to True, this is the process ID of the spawned shell.

但请参阅下面的注意事项。

这将我们带到 "more orthodox way"。我们进入可能有争议的领域的地方,不同的人,不同的想法。不像第一个那样可能与 documentation 一致建议不要使用 shell=True 除非你真的需要。

args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.

还有另一节是关于不听从建议的(安全)影响。

因此,使用您的脚本编译 运行 nohup 的参数列表,并通过 stdoutstderr 的关键字参数(stdoutstderr)处理输出重定向=18=] 似乎是一个很好的行动方案,还可以让您获得一致的 PID。

这最后一步可能会引起最多的争议:但您实际上可以通过 python 接口将进程守护进程到相应的系统调用。有据可查的例子似乎在 github 中增长(从下面提到的 PEP 中的 link 超过一跳)。

或者有一个关于这个话题的library referred to from the PEP-3143


注意:该位似乎并不总是正确的(调用 sh 是,但两个 PID 不是)。至少在我的系统上,我观察到 shexec 通过 -c (本身)调用的程序没有分叉。从一些快速的 运行s 和跟踪中可以看出,至少如果我没有弄乱 stdin/-out/-err(即没有管道或重定向),没有强制 subshell (...),或者没有在 ; 上链接命令。 (后两者是显而易见的,一旦您了解如何实现重定向,前者也是显而易见的)。所以至少对于我的 shell 我敢于推断并说:它似乎不会分叉,除非它必须。或者更简化(因此不完全正确)的陈述是:简单的东西不会分叉。