1. 程式人生 > >ARM40-A5應用——Shell指令碼實現程序自動拉起

ARM40-A5應用——Shell指令碼實現程序自動拉起

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是否上電自啟動。


參考文章:

linux利用shell實現守護程序的指令碼

鳥哥的 Linux 私房菜——第7堂課:認識 bash 基礎與系統救援

 薈聚計劃:共商 共建 共享  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){}

}

}