ARM40-A5 应用 --Shell 脚本 OA 幸运飞艇平台搭建论坛: haozbbs.com Q1446595067 实现进程自动拉起
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 是否上电自启动.
参考文章:
shell 脚本自动拉起启动程序
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){}
- }
- }
来源: http://www.bubuko.com/infodetail-2674889.html