【问题标题】:Run bash script as daemon将 bash 脚本作为守护进程运行
【发布时间】:2013-10-14 12:56:46
【问题描述】:

我有一个脚本,每 X 次运行我的 PHP 脚本:

#!/bin/bash
while true; do
/usr/bin/php -f ./my-script.php
echo "Waiting..."
sleep 3
done

如何将它作为守护进程启动?

【问题讨论】:

    标签: linux centos centos6 daemons


    【解决方案1】:

    一些评论者已经表示,您的问题的答案不适用于所有发行版。由于您没有在问题中包含 CentOS,而只是在标签中包含,所以我想在这里发布一个必须理解的主题,以便无论分发如何都能控制他/她的进程:

    1. 什么是 init 守护进程(可选)
    2. 什么是inittab文件(/etc/inittab)
    3. inittab 文件在您的发行版中做了什么(例如,它实际上是否运行所有 /etc/init.d 中的脚本?)

    对于您的问题,可以通过在 /etc/inittab 中添加这一行来启动 sysinit 上的脚本,并使其在终止时重新生成:

    # start and respawn after termination
    ttyS0::respawn:/bin/sh /path/to/my_script.sh
    

    当然,脚本必须提前执行:

    chmod +x /path/to/my_script.sh
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      守护进程只是作为后台进程运行的程序,而不是在交互式用户的直接控制之下...

      [以下 bash 代码适用于 Debian 系统 - Ubuntu、Linux Mint 发行版等]

      简单的方法:

      简单的方法是编辑您的 /etc/rc.local 文件,然后让您的脚本从那里运行(即每次启动系统时):

      sudo nano /etc/rc.local
      

      添加以下内容并保存:

      #For a BASH script
      /bin/sh TheNameOfYourScript.sh > /dev/null &
      

      更好的方法是通过 Upstart 创建一个守护进程:

      sudo nano /etc/init/TheNameOfYourDaemon.conf
      

      添加以下内容:

      description "My Daemon Job"
      author "Your Name"
      start on runlevel [2345]    
      
      pre-start script
        echo "[`date`] My Daemon Starting" >> /var/log/TheNameOfYourDaemonJobLog.log
      end script
      
      exec /bin/sh TheNameOfYourScript.sh > /dev/null &
      

      保存。

      确认它看起来没问题:

      init-checkconf /etc/init/TheNameOfYourDaemon.conf
      

      现在重启机器:

      sudo reboot
      

      现在,当您启动系统时,您可以看到说明您的守护程序正在运行的日志文件:

      cat  /var/log/TheNameOfYourDaemonJobLog.log
      

      • 现在您可以通过以下方式启动/停止/重新启动/获取守护程序的状态:

      重启:这将停止,然后启动服务

      sudo service TheNameOfYourDaemonrestart restart
      

      start:这将启动一个服务,如果它没有运行

      sudo service TheNameOfYourDaemonstart start
      

      stop:如果服务正在运行,这将停止服务

      sudo service TheNameOfYourDaemonstop stop
      

      status:这将显示服务的状态

      sudo service TheNameOfYourDaemonstatus status
      

      【讨论】:

      • 你应该真正指出这是针对哪个发行版,因为这些命令和路径并非在所有发行版上都是正确的。
      • 好点 sgtPooki。我添加了一个警告,解释我的示例是指 Ubuntu / Mint 发行版等。感谢您的评论。
      • 有人可以为这个答案做一个系统插件吗? :)
      • 请注意,Upstart 已被弃用。 Ubuntu 移至 systemd。
      【解决方案3】:

      另一个很酷的技巧是在后台运行函数或子shell,但并不总是可行

      name(){
        echo "Do something"
        sleep 1
      }
      
      # put a function in the background
      name &
      #Example taken from here
      #https://bash.cyberciti.biz/guide/Putting_functions_in_background
      

      在后台运行子shell

      (echo "started"; sleep 15; echo "stopped") &
      

      【讨论】:

        【解决方案4】:

        您可以转到 /etc/init.d/ - 您将看到一个名为骨架的守护程序模板。

        您可以复制它,然后在启动功能下输入您的脚本。

        【讨论】:

        • 您也可以考虑在后台运行脚本,方法是在末尾添加 '&' 或使用 nohup 运行。
        • @LuisMuñoz 如何让它在后台自动运行。例如,当您发出 /etc/init.d/mysql start 时,守护程序默认启动并在后台运行。
        • @DavidOkwii 将您的代码放在一个函数中并在后台运行它。检查我添加到这个问题的答案。
        【解决方案5】:

        要在 shell 中将其作为完整的守护进程运行,您需要使用 setsid 并重定向其输出。您可以将输出重定向到日志文件,或重定向到 /dev/null 以丢弃它。假设您的脚本名为 myscript.sh,请使用以下命令:

        setsid myscript.sh >/dev/null 2>&1 < /dev/null &
        

        这会将进程与您当前的 shell(stdin、stdout 和 stderr)完全分离。如果您想将输出保存在日志文件中,请将第一个 /dev/null 替换为您的 /path/to/logfile。

        你必须重定向输出,否则它不会作为一个真正的守护进程运行(它将取决于你的 shell 来读取和写入输出)。

        【讨论】:

        • 那我怎么杀掉它?
        • 您必须找到它的 pid 并向其发送信号。这是 linux 系统的 UNSAFE 示例:kill $(ps -fade | grep myscript.sh | grep -v grep | awk '{print $2}')。这将杀死名称或参数中包含“myscript.sh”的所有进程,因此使用起来不是很安全,但您可以对其进行调整以满足您的需求。
        • 谢谢,这很有帮助!你能解释一下2&gt;&amp;1 &lt; /dev/null在做什么吗?
        • @DanielPatrick 在 bash(和大多数其他 shell)中,这是标准输入/标准错误/标准输出重定向。 &gt; /dev/null(与 1&gt;/dev/null 相同)将 stdout(即文件描述符 1)重定向到 /dev/null。 2&gt;&amp;1 表示将所有 stderr(文件描述符 2)重定向到文件描述符 1,该文件描述符已经重定向到 /dev/null。 &lt;/dev/null 将 /dev/null 附加到标准输入 (fd 0)。所有这些都让脚本与所有当前输入/输出源分离,并重新附加到 /dev/null。希望这个答案。
        • 非常有帮助,熟悉重定向但不熟悉文件描述符。谢谢!
        猜你喜欢
        • 2011-01-03
        • 2014-09-05
        • 2015-03-21
        • 1970-01-01
        • 2023-03-02
        • 1970-01-01
        • 2015-11-07
        相关资源
        最近更新 更多