概述:
1、A可以是守護進程也可以是守護腳本
2、A是守護進程
3、A具有保活其他進程的服務
守護進程(已驗證)
1 //main.c 2 3 #include <stdio.h> 4 #include <unistd.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <fcntl.h> 8 #include <syslog.h> 9 10 //守護應用名 11 #define APP_NAME "untitled_ATU201console" 12 //生成日志文件 13 #define LOG_FILE "/home/root/ljc/folder_daemon/untitled_ATU201console.log" 14 //匹配成功 15 #define MATCH_RES "1" 16 //啟動守護應用的腳本 17 #define SCRIPT_FILE "start_daemon" 18 19 20 21 int daemon(int nochdir, int noclose) { 22 pid_t pid; 23 24 //讓init進程成為新產生進程的父進程 25 pid = fork(); 26 //如果創建進程失敗 27 if (pid < 0) { 28 perror("fork"); 29 return -1; 30 } 31 //父進程退出運行 32 if (pid != 0) { 33 exit(0); 34 } 35 //創建新的會話 36 pid = setsid(); 37 if (pid < -1) { 38 perror("set sid"); 39 return -1; 40 } 41 //更改當前工作目錄,將工作目錄修改成根目錄 42 if (!nochdir) { 43 chdir("/"); 44 } 45 //關閉文件描述符,並重定向標准輸入,輸出合錯誤輸出 46 //將標准輸入輸出重定向到空設備 47 if (!noclose) { 48 int fd; 49 fd = open("/dev/null", O_RDWR, 0); 50 if (fd != -1) { 51 dup2(fd, STDIN_FILENO); 52 dup2(fd, STDOUT_FILENO); 53 dup2(fd, STDERR_FILENO); 54 if (fd > 2) { 55 close(fd); 56 } 57 } 58 } 59 //設置守護進程的文件權限創建掩碼 60 umask(0027); 61 62 return 0; 63 } 64 65 //是否有匹配的字符,有則返回1,沒有返回0 66 //src:源字符串 67 //dst:目標字符串 68 //len:源字符串被比較的長度 69 int match(char *src, char *dst, int len) { 70 syslog(LOG_INFO, "--------------------match1"); 71 72 int i = 0; 73 int j = 0; 74 int size_dst = 0; 75 76 //獲得目標字符串的長度 77 size_dst = strlen(dst); 78 //如果目標字符串的長度大於len,返回失敗 79 if (size_dst > len) { 80 syslog(LOG_INFO, "--------------------match11"); 81 return 0; 82 } 83 84 syslog(LOG_INFO, "--------------------match2"); 85 86 //開始比較 87 for (i = 0; i < len; i++) { 88 for (j = 0; j < size_dst; j++) { 89 if (src[i + j] != dst[j]) { 90 break; 91 } 92 } 93 if (j == size_dst) { 94 return 1; 95 } 96 } 97 98 syslog(LOG_INFO, "--------------------match3"); 99 100 return 0; 101 } 102 103 int main(int argc, char *argv[]) { 104 int fd = 0; 105 char buf[100]; 106 107 //開啟守護進程 108 daemon(0, 0); 109 110 while (1) { 111 syslog(LOG_INFO, "--------------------main1"); 112 113 //打開日志 114 openlog(argv[0], LOG_CONS | LOG_PID, LOG_USER); 115 116 //查看程序是否運行 117 //新建輸出文件 118 system("touch "LOG_FILE); 119 //獲得程序ID 120 system("ps -ef | grep "APP_NAME" | grep -v grep | wc -l >> "LOG_FILE); 121 //打開輸出文件 122 fd = open(LOG_FILE, O_CREAT | O_RDONLY, 0777); 123 //清空緩存 124 memset(buf, 0, 100); 125 //讀取全部 126 read(fd, buf, 100); 127 128 syslog(LOG_INFO, "--------------------main2"); 129 130 //判斷是否有程序文件運行 131 // if (match(buf, MATCH_RES, 1)) { 132 // syslog(LOG_INFO, "match success!!!"); 133 // } else { 134 // syslog(LOG_INFO, "match fail!!!"); 135 // //運行程序 136 // system(SCRIPT_FILE); 137 // } 138 139 int res = memcmp(buf, MATCH_RES, 1); 140 syslog(LOG_INFO, "buf = %s\n", buf); 141 syslog(LOG_INFO, "MATCH_RES = %s\n", MATCH_RES); 142 syslog(LOG_INFO, "res = %d\n", res); 143 if ( res == 0) { 144 syslog(LOG_INFO, "match success!!!"); 145 } else { 146 syslog(LOG_INFO, "match fail!!!"); 147 //運行程序 148 // system(SCRIPT_FILE); 149 system("/home/root/ljc/folder_daemon/untitled_ATU201console &"); 150 } 151 152 syslog(LOG_INFO, "--------------------main3"); 153 154 //休眠 155 sleep(2); 156 //刪除輸出文件 157 system("rm "LOG_FILE); 158 //休眠 159 sleep(5); 160 } 161 //關閉日志 162 closelog(); 163 164 return 0; 165 }
守護腳本1(待驗證)
1 //假設要監控的進程名稱為test,TargetProcessName為啟動該進程的腳本,status 有一系列的宏 對應可以檢測。 2 while [ 0 ] 3 do 4 Result=$(ps -ef | grep -v grep |grep "test") 5 if [ "" == "$Result" ] 6 then 7 RecordTime=$(date) 8 echo "Restar test" >>$LogFile 9 nohup $TargetProcessName>>$LogFile & 10 sleep 2 11 fi 12 Result= 13 done
守護腳本2(待驗證)
1 #!/bin/bash 2 # 直接上代碼吧 3 # watchdog.sh 4 5 #定義映射表 k=進程號 v=作業 6 declare -A mapper 7 #進程號文件 8 conf=dog.pid 9 10 11 function debug 12 { 13 echo $@ 14 } 15 16 #param pid 進程號 17 #使用ps命令查詢該進程是否存在,如果不存在返回"gone",否則返回"stay" 18 19 function watch 20 { 21 local pid=$1 22 local index=`ps -ef|awk '{print $2}'|grep -P "^${pid}$"` 23 if [ "${index}None" = "None" ]; then 24 echo gone 25 return 26 fi 27 echo stay 28 } 29 30 #每過5秒鍾檢查一遍所有的進程,調用上面的watch 31 32 function dogit 33 { 34 while [ 1 ] 35 do 36 sleep 5 37 for pid in ${!mapper[@]} 38 do 39 debug pid:$pid 40 local t=`watch $pid` 41 debug "test result is $t!!!" 42 if [ "$t" = "gone" ]; then 43 debug "$c with pid $pid was gone" 44 loadscript ${mapper[$pid]} 45 unset mapper[$pid] 46 sed -i "/$pid/d" $conf 47 fi 48 done 49 done 50 } 51 52 #從作業文件加載需要守護的作業命令 53 54 function loadscript 55 { 56 local script=$@ 57 debug script=$script 58 $script > /dev/null & 59 local pid=$! 60 mapper[$pid]=$script 61 echo $pid >> $conf 62 } 63 64 function clean 65 { 66 if [ -f $conf ]; then 67 while read line; do 68 if [ -n "$line" ]; then 69 pid=`ps -ef|awk '{print $2}'|grep $line|grep -v 'grep'` 70 if [ -n "${pid}" ]; then 71 debug killing $pid 72 kill $pid 73 fi 74 fi 75 done < $conf 76 fi 77 echo > $conf 78 debug done! 79 } 80 81 function main 82 { 83 clean 84 local file=$1 85 if [ -f $file ]; then 86 while read line 87 do 88 loadscript $line 89 done < $file 90 dogit 91 else 92 echo "Not a file!" 93 fi 94 } 95 96 main $1;