ARM40-A5应用——Shell脚本实现进程自动拉起
2018.6.11
版权声明:本文为博主原创文章,允许转载。
在Linux上许多程序是无法保证绝对稳定的,但必须要确保程序在出现小概率错误或者未知崩溃退出后,可以重新运行起来。
本文介绍一种基于shell脚本的后台进程来解决这种问题。
一、普通程序自动拉起
后台进程脚本process-watcher.sh
#!/bin/sh
while true
do
#启动一个循环,每10s检查一次进程状态
procnum=$(ps -ef | grep "process-test" | grep -v "grep" | wc -l)
if [ $procnum -eq 0 ];then
#返回值为0,说明进程不存在,重启
/protect/process-test &
fi
#休眠10s
sleep 10
done
程序process-test只做了简单的打印启动信息并等待15秒退出功能,用来测试后台进程的脚本是否起效。
#!/bin/sh
echo "arm40 is start"
sleep 15
echo"arm40 is close"
其中procnum变量用来获取所有进程中含有”process-test”的进程个数
图1
如图1中先将程序process-test在后台中运行,再将后台脚本启动。
图2
之后就可以发现程序process-test在结束后会被重启。
注:避免监控的程序名和系统进程中的程序名重复,如果存在会导致脚本判断错误。
二、多副本进程自动拉起
后台进程脚本multiprocess-watcher.sh
#!/bin/sh
while true
do
procnum=$(ps -ef | grep "/protect/process-test" | grep -v "grep" | wc -l)
if [ $procnum -lt 2 ];then
killall process-test
#此处运行的程序仅为参考
/protect/process-test &
/protect/process-test &
fi
sleep 10
done
由于某些程序可能需要打开两次或者程序中带有多进程,所以会出现需要确保两个同名进程的正常运行,其中任意一个崩溃就需要将其重新运行。
图3
图3中可以发现在一些程序中,会出现两个相同名字的进程,这样我们就无法通过之前单进程的脚本来实现异常退出后的自动拉起,因为如果程序中只有一个进程因为意外退出,会被错误判断为程序仍然还在正常运行。
但我们会发现kill掉一个进程后,数量发生了改变,所以修改后台进程脚本,通过进程数来判断是否重启该程序。
图4
通过修改后的脚本发现只要kill掉其中任意一个进程,就会重启该程序,并没有等到另一个程序运行完再重启。
程序中进程大于两个,也只须以此类推修改脚本即可。
含fork()程序的自动拉起与上述情况相同,不多做赘述。(测试代码见附录)
三、上电自启动
有如下两种方法:
① 方法一
在 /etc/profile 的最后添加:
protect/process-watcher.sh &
修改 /etc/inittab中的
console::respawn:/sbin/getty L console 0 vt100
#console::respawn:/bin/sh
为:
#console::respawn:/sbin/getty L console 0 vt100
console::respawn:/bin/sh
② 方法二
在 /etc/init.d/rcS 文件的最后添加:
protect/process-watcher.sh &
方法一和方法二的测试:
重新上电后,ps 观察process-watcher.sh和process-test是否上电自启动。
参考文章:
https://www.cnblogs.com/akidongzi/p/6015874.html
linux利用shell实现守护进程的脚本
https://blog.csdn.net/ljxfblog/article/details/52036004
鳥哥的 Linux 私房菜——第7堂課:認識 bash 基礎與系統救援
http://linux.vbird.org/linux_basic_train/unit07.php
荟聚计划:共商 共建 共享 ZDD
含fork()测试程序(需要在linux下交叉编译)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void main(){
pid_t pid;
pid = fork();
if(pid > 0){
printf("fork1\r\n");
while(1){}
}
if(pid == 0){
printf("fork2\r\n");
while(1){}
}
}