我正在与父程序在后台运行独立的子程序。退出父程序后,我希望子程序继续运行并登录到OUTPUT_PATH
。实际上,我可以看到日志文件正在更新。但是,由于我试图从ps aux
查找PID,所以找不到。谁能解释这种行为?我在做什么错了?
shellCommand = "nohup python PYTHON_PROGRAM ARGS >OUTPUT_PATH 2>&1 &"
subprocess.Popen(shellCommand, shell=True, preexec_fn=os.setpgrp)
答案 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
的关键字参数(stderr
,Popen
)处理了输出重定向就像一个好的做法,并且还可以为您提供一致的PID。
最后一步可能引起最大争议:但是您实际上可以通过与相应syscall的python接口来守护进程。记录充分的示例似乎在github中不断增长(从下面提到的PEP中的链接经过一跳)。
注意:该位似乎并不总是正确的(调用sh
是,但是两个PID否)。至少在我的系统上,我观察到sh
到exec
经由-c
调用的程序(本身)没有分叉。从几次快速运行和跟踪来看,至少在我不搞混stdin / -out / -err(即没有管道或重定向),没有强制执行subshell (...)
或没有链接命令的情况下,才是这种情况;
。 (后两种很明显,一旦您意识到重定向的实现方式,前两种也是显而易见的)。因此,至少对于我的外壳,我敢于外推并说:似乎它不是分叉的,除非必须这样做。甚至更简化(因此也不完全正确)的陈述将是:简单的内容不会分叉。