脚本作为daemon运行

在一些测试情况下,需要验证进程的继承关系,所以想能够持续运行一个脚本,作为daemon。

使用setsid运行脚本作为daemon

要使得一个shell按照daemon方式运行,需要使用setsidsetsid - run a program in a new session)并将输出重定向。可以将输出重定向到一个认知文件,或者/dev/null抛弃日志。

假设这里我们有一个 test_daemon.sh 脚本内容如下

#!/bin/bash

while true; do
  /bin/echo "run as daemon then sleep 10s"
  /bin/date > /dev/shm/test_daemon
  /bin/sleep 10
done

则我们可以如下方式执行

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

但是发现这个test_daemon.sh并没有如料想的一样运行,而是检查进程发现结束了

$ps aux | grep test_daemon
admin    220955  0.0  0.0  61200   756 pts/0    S+   14:39   0:00 grep test_daemon
[1]+  Done                    setsid test_daemon.sh > /dev/null 2>&1 < /dev/null

/dev/null替换成本地的一个日志文件/home/admin/test_daemon.log,看输出情况

setsid test_daemon.sh > /home/admin/test_daemon.log 2>&1 < /home/admin/test_daemon.log &

可以看到 test_daemon.log 中有一行记录

execvp: No such file or directory

这个问题似乎和终端有关,是执行脚本命令需要tty么?

使用daemon工具

参考 Using Daemon to create Linux services in 5 minutes - 这篇文章解释非常透彻清晰

daemon是一个将其他进程转换成daemon运行的工具,安装方法可以参考README。可以直接从从官网下载源代码安装,或者使用rpm安装。

wget http://libslack.org/daemon/download/daemon-0.6.4.tar.gz
tar xfz daemon-0.6.4.tar.gz
cd daemon-0.6.4
./config
make
sudo make install

make test是用来检测libslack,不确定用途

使用方法非常简单,假设这里运行一个test_daemon_10.sh脚本

daemon -r /home/admin/test_daemon_10.sh

实验用的test_daemon_10.sh内容如下

#!/bin/bash

rm -f /dev/shm/test_daemon

i=0
while true; do
  /bin/echo "run as daemon then sleep 10s"
  /bin/date >> /dev/shm/test_daemon
  /bin/sleep 10
  echo "Hello world - $i" >> /dev/shm/test_daemon
  i=$(( $i + 1 ))
done

这个脚本唯一的功能就是不断循环并将输出记录到/dev/shm/test_daemon文件。

使用daemon -r参数,这个-r参数表示respawn,也就是自动重新重启。表示当脚本被杀死以后,daemon会自动再启动这个脚本作为服务。

下面我们来检验一下,先检查脚本进程

ps aux | grep test_daemon_10 | grep -v grep

可以看到

admin     45747  0.0  0.0  65400   424 ?        S    09:49   0:00 daemon -r /home/admin/test_daemon_10.sh
admin     45749  0.0  0.0  63872  1076 ?        S    09:49   0:00 /bin/bash /home/admin/test_daemon_10.sh

我们杀死进程45749

kill 45749

然后再使用命令ps aux | grep test_daemon_10 | grep -v grep 检查系统中的test_daemon_10,可以看到脚本进程已经杀死

admin     45747  0.0  0.0  65400   436 ?        S    09:49   0:00 daemon -r /home/admin/test_daemon_10.sh
admin     45749  0.0  0.0      0     0 ?        Z    09:49   0:00 [test_daemon_10.] <defunct>

过一会,我们再次使用命令 ps aux | grep test_daemon_10 | grep -v grep 就会发现脚本再次被daemon进程启动(注意进程号不同了)

admin     45747  0.0  0.0  65428   680 ?        S    09:49   0:00 daemon -r /home/admin/test_daemon_10.sh
admin     98336  0.0  0.0  63872  1068 ?        S    09:57   0:00 /bin/bash /home/admin/test_daemon_10.sh

这个daemon化的脚本会一直运行,即使关闭终端窗口。

Using Daemon to create Linux services in 5 minutes还提供了SysVinit兼容的启动脚本用于daemonize脚本。

使用脚本functions来管理daemon(Red Hat/CentOS系使用)

Red Hat系发行版提供了一个标准化的/etc/init.d/functions来管理daemon脚本。

参考

Last updated