一个Linux下的监听脚本程序

为了避免linux下的控制台程序A死掉,可以通过一个另外一个程序B来监听A程序,当A程序异常退出时将B程序带起来。当然程序设计的最好方式为程序不崩溃,但是程序中存在bug很难避免,该方法还是有一定的实践意义。对于B程序可以通过shell脚本或者单独一个应用程序来解决。本文将通过shell脚本来解决此问题。

shell脚本的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash

check_process()
{
# check parameter
if [ $1 = "" ];
then
return -1
fi

# get the running process
process_names=$(ps -ef | grep $1 | grep -v grep | awk '{print $8}')
for process_name in $process_names
do
if [ $process_name = $1 ] ;
then
return 1
fi
done

# not run and run the process
echo "$(date) : process $1 not run, just run it"
$1
return 0
}

while [ 1 ];do
check_process "/usr/bin/app/process" # programe path
sleep 5
done

将shell脚本在脱离控制台下可以运行

一旦断开了控制台,shell脚本就会由于接收到SIGHUP信号而退出。这里有两种思路来解决该问题,一种是通过系统的crontab来定期调用脚本程序,另外一种是通过神奇的screen程序来解决该问题,我这里通过screen程序来解决该问题,具体screen程序的应用见我的另外一篇文章《》。

应用程序为daemon方式运行

为了能够保证该脚本监控多个应用程序,需要将应用程序设置为daemon方式运行,可以调用函数daemon实现。也可以调用单独实现的daemon函数,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void init_daemon(void) 
{
int pid;
int i;

if(pid=fork())
exit(0);//是父进程,结束父进程
else if(pid< 0)
exit(1);//fork失败,退出
//是第一子进程,后台继续执行

setsid();//第一子进程成为新的会话组长和进程组长
//并与控制终端分离
if(pid=fork())
exit(0);//是第一子进程,结束第一子进程
else if(pid< 0)
exit(1);//fork失败,退出
//是第二子进程,继续
//第二子进程不再是会话组长

for(i=0;i< NOFILE;++i)//关闭打开的文件描述符
close(i);
chdir("/tmp");//改变工作目录到/tmp
umask(0);//重设文件创建掩模
return;
}