作为守护进程运行 bash 脚本

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

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

我怎么能开始它作为守护进程?

178602 次浏览

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

您可以复制它,然后在 start 函数下输入脚本。

要在 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 来读写输出)。

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

[下面的 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

停止: 这将停止一个服务,如果它正在运行

sudo service TheNameOfYourDaemonstop stop

Status: 这将显示服务的状态

sudo service TheNameOfYourDaemonstatus status

另一个很酷的技巧是在后台运行函数或子 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") &

一些评论者已经指出,对您的问题的回答并不适用于所有的发行版。因为你没有在问题中包含 CentOS,而只是在标签中包含 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

希望这个能帮上忙