我正在使用子进程启动进程并让它在后台运行,它是一个服务器应用程序。该进程本身是一个带有瘦包装器的java程序(除其他外,这意味着我可以将其作为可执行文件启动而无需显式调用java)。
我正在使用Popen来运行该进程,当我设置shell = False时,它会运行,但它会生成两个进程而不是一个进程。第一个进程将init作为其父进程,当我通过ps检查它时,它只显示原始命令。但是,第二个进程显示扩展的java参数(-D和-X标志) - 这是我期望看到的以及当我手动运行命令时进程的外观。
有趣的是,当我设置shell = True时,命令失败。该命令确实有一条帮助消息,但它似乎并不表示我的参数列表存在问题(不应该存在)。除了命名为Popen的shell外,一切都是一样的。 我在Ubuntu上使用Python 2.7。不确定这里发生了什么,任何帮助表示赞赏。我想java命令可能正在执行exec / fork,出于某种原因,当我通过Python启动时,父进程不会死。
我看到这个SO question看起来很有希望,但并没有改变我正在经历的行为。
答案 0 :(得分:1)
这实际上是关于包装器的一个问题而不是关于Python的问题 - 你会从其他任何语言中获得相同的行为。
为了获得您想要的行为,包装器希望拥有调用JVM外观的行,如下所示:
exec java -D... -cp ... main.class.here "$@"
...而不是缺少前面的exec
:
java -D... -cp ... main.class.here "$@"
在前一种情况下,包装器的过程映像被替换与它调用的JVM的过程映像;在后者中,包装器等待JVM退出,然后继续运行。
如果包装器在JVM退出后进行任何清理,使用exec
将阻止这种情况发生,因此是错误的事情 - 在这种情况下,你会想要包装器在JVM运行时仍然存在,否则它将无法在之后执行清理。
请注意,如果包装器负责分离子进程,则需要能够关闭打开的文件句柄才能正确发生。如果父进程有比仅stdin,stdout和stderr更多的文件描述符,请考虑将close_fds=True
传递给Popen调用。