【问题标题】:Can I start a script so it's independent of its parent process on Linux?我可以启动一个脚本,使其独立于 Linux 上的父进程吗?
【发布时间】:2010-10-25 17:28:28
【问题描述】:

有没有办法从另一个进程启动脚本,这样如果进程死亡/结束,脚本仍然继续?

setuid 会这样做吗?如果我将所有者设置为root,然后启动脚本?

例如,如果我有一些 PHP 代码启动一个脚本,但 httpd 死掉或被杀死,我认为它需要我的脚本。有没有办法解决这个问题?

具体来说,我在 Fedora 10 上使用 Apache 2 和 PHP 5。

【问题讨论】:

    标签: php linux scripting process daemon


    【解决方案1】:

    来自here

    function become_daemon() 
    {
        $child = pcntl_fork();
        if($child) {
            exit; // kill parent
        }
        posix_setsid(); // become session leader
    }
    

    此外,关闭 STDIN、STDOUT 和 STDERR 是个好主意,但我不确定如何在 PHP 中执行此操作。

    【讨论】:

    • fork() 是执行此操作的正确方法,但从技术上讲,您应该再次分叉,这样该进程就不是会话领导者,并且无法重新获取控制终端
    • 我想我可以在对我的脚本的调用中关闭 STDIN、STDOUT 和 STDERR。或者更确切地说,重定向到其他地方。
    • 所以分叉本质上是将进程分成另一个进程,对吗?但是,如果从 PHP 启动的进程的执行时间受到限制,这些限制是否仍然适用?一周后我的脚本似乎死了,但从命令行运行良好。
    • 这取决于杀死它的原因。正确分叉(两次)、关闭文件描述符并确保您位于安全目录中是一个好的开始。
    • 仅供参考,这需要使用 PHP 编译过程控制扩展库,你猜怎么着!我的构建没有它:(仅供参考,图书馆在这里:php.net/pcntl_fork我现在只需要相信你的话:)
    【解决方案2】:

    您可以在命令 shell 中在命令行末尾附加一个与号 (&) 以在后台启动该命令,从而将其与 shell 分离。

    这里有一些很好的信息: http://www.linuxforums.org/forum/linux-programming-scripting/50096-moving-processes-background-foreground.html

    【讨论】:

    • 我已经使用 & 符号在后台运行它。但它似乎并没有真正将它与父进程分离,只是从前台分离。
    • -1 后台进程与将其与父进程分离无关
    【解决方案3】:

    您可以使用 bash 中内置的“disown”将作业从生成它的 shell 中分离出来。见:http://www.faqs.org/docs/bashman/bashref_79.html

    【讨论】:

      【解决方案4】:

      你应该使用 php 的 pcntl_fork() (由@bmdhacks 推荐)。

      基本流程是,fork,setsid,再fork,chdir到/,关闭所有打开的文件描述符。标准做法还要求您创建一个名为 /var/run/$NAME 的文件(其中 $NAME 是您的守护进程的名称),并将 PID 写入该文件,以便您稍后可以控制进程执行。

      我不是 php 程序员,但这是标准的 *nix 东西。 我可以谷歌搜索的最好的 php 示例看起来像这样 hello-world-daemon-with-fork 但是,他没有将他的工作目录更改为“/”,看起来他也没有关闭打开的文件描述符(我不确定这在 php 中如何工作),因此他没有连接到标准输入、标准输出、和原始进程的stderr。

      我又挖了一点,发现另一篇可能对php有帮助的文章pcntl_fork()

      而且,看起来有一个名为 System_Daemon 的 pear 模块可以为您处理这个问题(我是通过 here 找到的)。

      【讨论】:

        【解决方案5】:

        试试“nohup yourscript.sh &”

        【讨论】:

        • [修订后的评论] 您应该确保正确地明确重定向所有流。虽然这种方法有效,但还有更好、更可控的方法。
        • 但是这些方法假设您可以控制子进程并且您想要更改它们。海报没有具体说明。如果您启动 wget 以获取 iso 映像或其他内容,则 nohup 是一种比重新编译 wget 以进行守护程序更好的方法。但是,是的,重定向你的流更好,否则你最终会得到 nohup.out 文件。
        • 不,我不建议修补 wget :) 我想 OP 并不清楚他想创建一个真正的守护进程。我从他的一个 cmets 那里收集到的,他说它正在运行 php,一周后就死了
        猜你喜欢
        • 1970-01-01
        • 2018-05-12
        • 2014-07-15
        • 1970-01-01
        • 2015-02-21
        • 2012-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多