在一些测试情况下,需要验证进程的继承关系,所以想能够持续运行一个脚本,作为daemon。
使用setsid
运行脚本作为daemon
要使得一个shell按照daemon方式运行,需要使用setsid
(setsid - 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脚本。
参考
- Run bash script as daemon
- Using Daemon to create Linux services in 5 minutes
- Managing Linux daemons with init scripts
- How can I run a shell script as a daemon under Redhat?
- How to start Script as Daemon – DEBIAN – UBUNTU
- Best way to make a shell script daemon? - 提到了Unix Programming FAQ有关案例
- Beginners Guide to creating a daemon in Linux - 一个简单的c语言写的daemon,可参考