Python程序仍在运行,但找不到PID

时间:2018-07-06 20:37:49

标签: python subprocess pid nohup

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

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

1 个答案:

答案 0 :(得分:1)

好的,这个评论太大了。通过运行ps -fwp $(pgrep -f PYTHON_PROGRAM),我们现在找到了该过程。 :)但其PID与Popen.pid报告的PID不匹配。这取决于您使用shell=True以来调用的shell实例。第一个fork用于调用shell,第二个用于您的脚本。实际上,这在上面提到的链接中有记录:

  

请注意,如果将shell参数设置为True,则这是生成的shell的进程ID。

但是请注意下面的提示。

这将我们带入“更正统的方式”。我们进入可能存在争议的领域的地方,不同的人,不同的想法。第一个建议可能并不像documentation那样建议除非您确实需要否则不要使用shell=True

  所有调用均需要

args ,该参数应为字符串或程序参数序列。通常最好提供一个参数序列,因为它允许模块处理任何必需的参数转义和引用(例如,在文件名中允许空格)。如果传递单个字符串,则外壳程序必须为True(请参见下文),否则该字符串必须简单地命名要执行的程序而无需指定任何参数。

还有另一节关于不注意建议的(安全)含义。

因此,似乎编译了一个参数列表以使用脚本运行nohup并已经通过stdout的关键字参数(stderrPopen)处理了输出重定向就像一个好的做法,并且还可以为您提供一致的PID。

最后一步可能引起最大争议:但是您实际上可以通过与相应syscall的python接口来守护进程。记录充分的示例似乎在github中不断增长(从下面提到的PEP中的链接经过一跳)。

或者在该主题的library中引用了PEP-3143


注意:该位似乎并不总是正确的(调用sh是,但是两个PID否)。至少在我的系统上,我观察到shexec经由-c调用的程序(本身)没有分叉。从几次快速运行和跟踪来看,至少在我不搞混stdin / -out / -err(即没有管道或重定向),没有强制执行subshel​​l (...)或没有链接命令的情况下,才是这种情况;。 (后两种很明显,一旦您意识到重定向的实现方式,前两种也是显而易见的)。因此,至少对于我的外壳,我敢于外推并说:似乎它不是分叉的,除非必须这样做。甚至更简化(因此也不完全正确)的陈述将是:简单的内容不会分叉。

相关问题