【问题标题】:python run shell script that spawns detached child processespython运行shell脚本,产生分离的子进程
【发布时间】:2013-05-29 05:13:38
【问题描述】:

更新帖子:

我有一个在端口上运行的 Python Web 应用程序。它用于监视一些其他进程,其功能之一是允许用户重新启动自己的进程。重启是通过调用 bash 脚本完成的,该脚本将继续重启这些进程并在后台运行它们。

问题是,每当我在使用它重新启动任何用户的进程后杀死 python web 应用程序时,这些进程将以循环方式接管 python web 应用程序使用的端口,所以我是由于端口受限,无法重新启动 python Web 应用程序。因此,我必须终止重启所涉及的进程,直到没有任何东西占用 python web 应用程序使用的端口。

除了那些占用端口的进程之外,一切都很好。这实在是不可取。

可能重启的进程:

  1. redis 服务器
  2. newrelic-admin 运行程序(生成另一个 Web 应用程序)
  3. python 工作进程

更新(2013 年 6 月 6 日):我已经设法解决了这个问题。看看我下面的答案。


原帖:

我有一个在端口上运行的 Python Web 应用程序。这个 python 程序有一个调用 bash 脚本的函数。 bash 脚本会生成一些后台进程,然后退出。

问题是,每当我杀死 python 程序时,由 bash 脚本生成的后台进程将接管并占用同一个端口。

具体子流程有:

  1. redis 服务器(在配置文件中使用 daemonize = true)
  2. newrelic-admin 运行程序(生成 Web 应用程序)
  3. python 工作进程

更新 2:我尝试使用 nohup 运行这些。在我杀死 python web 应用程序后,只有 python 工作进程不会尝试接管端口。 redis 服务器和 newrelic-admin 仍然可以。

我在 python 程序中使用 subprocess.call 运行 bash 脚本时发现了这个问题。在运行 bash 脚本之前,我在 python 程序中尝试了双 fork 方法,但它导致了同样的问题。

如何防止从 bash 脚本生成的任何进程接管端口?

谢谢。

更新:我的意图是,如果 python 应用程序被终止,那些由 bash 脚本生成的进程应该继续运行。目前,在我关闭 python 应用程序后,它们确实会继续运行。问题是,当我终止 python 应用程序时,由 bash 脚本生成的进程开始以循环方式接管端口。

更新 3: 根据我从“pstree”和“ps -axf”看到的输出,进程 1 和 2(redis 服务器和由 newrelic-admin run-program 生成的 Web 应用程序) 不是 python web 应用程序的子进程。这让他们在我杀死它时接管了 python Web 应用程序占用的端口变得更加奇怪......有人知道为什么吗?

【问题讨论】:

  • 你可以使用 bash 脚本中的nohup
  • @Elazar 尝试了 nohup,它对我不起作用......生成的进程仍然以循环方式接管
  • @yanhan 是的,我没有仔细阅读您的问题。对不起。
  • 我发布了一些可能有帮助的更新

标签: python bash process subprocess


【解决方案1】:

在我继续正确回答之前,只是我尝试解决上述问题的方法的一些背景知识:

  1. subprocess.call
  2. subprocess.Popen
  3. 执行
  4. 双叉方法以及上述方法之一 (http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/)

顺便说一句,以上都不适合我。每当我关闭执行 bash 脚本的 Web 应用程序(这反过来又会产生一些我们现在表示为 Q 的后台进程)时,Q 中的进程将以循环方式接管 Web 应用程序占用的端口,所以我必须一一杀死它们,然后才能重新启动我的 Web 应用程序。

在遇到这个问题并继续我项目的其他部分后,我想到了一些随机的 Stack Overflow 帖子和互联网上的其他文章,并根据我自己的经验,回忆起我的 ssh 进入一个远程并启动一个分离的屏幕会话,然后注销,并在一段时间后再次登录以发现屏幕会话仍然存在。

所以我想,嘿,这到底是怎么回事,到目前为止没有任何效果,所以我不妨尝试使用 screen 看看它是否可以解决我的问题。令我惊讶和高兴的是,它确实如此!所以我发布这个解决方案希望能帮助那些面临同样问题的人。

在 bash 脚本中,我只是使用命名的屏幕进程启动了这些进程。例如,对于 redis 应用程序,我可能会这样启动它:

screen -dmS redisScreenName redis-server redis.conf

因此,这些进程将继续在它们开始时使用的那些分离的屏幕会话上运行。在这种情况下,我没有对 redis 进程进行守护进程。

为了杀死屏幕进程,我使用了:

screen -S redisScreenName -X quit

但是,这不会杀死 redis-server。所以只好分开杀了。

现在,在 Python Web 应用程序中,我可以使用 subprocess.call 来执行 bash 脚本,该脚本将生成分离的屏幕会话(使用“screen -dmS”)来运行我想要生成的进程。当我关闭 python web 应用程序时,没有一个生成的进程接管它的端口。一切顺利。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多