python运行shell脚本,它生成分离的子进程

时间:2013-06-03 04:53:52

标签: python bash process subprocess

更新了帖子:

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

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

除了占用端口的进程外,一切都很好。这真的是不受欢迎的。

可以重新启动的流程:

  1. redis的服务器
  2. newrelic-admin run-program(产生另一个Web应用程序)
  3. 一个python工作进程
  4. 更新(2013年6月6日):我设法解决了这个问题。请看下面的答案。


    原帖:

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

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

    具体来说,子流程是:

    1. 一个redis服务器(在配置文件中使用daemonize = true)
    2. newrelic-admin run-program(生成Web应用程序)
    3. 一个python工作进程
    4. 更新2:我尝试使用nohup运行这些。在我杀死python Web应用程序后,只有python worker进程才会尝试接管端口。 redis服务器和newrelic-admin仍然可以。

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

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

      谢谢。

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

      更新3:根据我从'pstree'和'ps -axf'看到的输出,进程1和2(由newrelic-admin运行程序生成的redis服务器和Web应用程序) )不是python Web应用程序的子进程。这使得它甚至更奇怪他们接管python web应用程序占用的端口,当我杀死它时...任何人都知道为什么?

1 个答案:

答案 0 :(得分:0)

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

  1. subprocess.call
  2. subprocess.Popen
  3. execve的
  4. 双叉方法以及上述方法之一(http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/
  5. 顺便说一句,以上都没有为我工作。每当我杀死执行bash脚本的web应用程序(它反过来产生一些后台进程,我们现在称为Q)时,Q中的进程将以循环方式接管Web应用程序占用的端口,所以在重新启动我的网络应用程序之前,我必须逐个杀死它们。

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

    所以我想,嘿,到底是什么,到目前为止没有任何作用,所以我不妨尝试使用屏幕看它是否可以解决我的问题。它让我非常惊喜和高兴!所以我希望发布这个解决方案,以帮助那些面临同样问题的人。

    在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应用程序时,没有一个生成的进程接管它的端口。一切顺利。