[linux C] daemon function application - process guardian tool, the operation and maintenance boy read it and said it is good! and comes with the shell version

I recently came into contact with the daemon function in Linux C. As the name suggests, it is related to the daemon process; simply speaking, a Linux Daemon (daemon process) is a special process running in the background;

Generally speaking, it is independent of the controlling terminal and periodically executes some kind of task or waits for certain events to be processed, because the daemon process runs in the background and does not occupy the terminal, so the terminal can execute other commands.

Most servers of the Linux system are implemented through daemon processes. Common daemon processes include system log process syslogd, web server httpd, mail server sendmail, database server mysqld, etc.

It can also be used to guard other programs by using its background execution and not occupying the terminal. It is in a state of constant monitoring. Once the target program is "dead" in monitoring, it will be "pulled up" immediately;

Without further ado, let’s look at the case:

Target

To ensure that outputTimer.shthe program is always "alive" in the background, once it is found to crash suddenly, it will be pulled up automatically;

Instructions

The name of this program is : diyDaemon
Execution method : ./diyDaemon + <full path where the daemon is located>

Effect

Use diyDaemonthis daemon to keep outputTimer.shit "alive";

1. You can see that there is no outputTimer.sh process at first, after executing diyDaemon, it will automatically pull up outputTimer.sh

before execution

after execution

2. Manually kill the outputTimer.sh process. According to the Pid number, pull up another outputTimer.sh program to continue running, so as to ensure that outputTimer.sh is always alive

kill process

the code

The code is well commented

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFSIZE 128

int main(int argc,char *argv[])
{
    
    
	char cmd[BUFSIZE] = {
    
    '\0'};	
	char startUpCmd[BUFSIZE] = {
    
    '\0'};	//存放 拉起死掉程序 的命令
	char returnBuffer[BUFSIZE] = {
    
    '\0'};	//存放popen的输出
	char *token = NULL;
	char *programName = NULL;	//存放守护的程序名
	char path[BUFSIZE] = {
    
    '\0'};	//存放 守护的程序 的路径
	FILE *file 	= NULL;
	
	if(argc < 2)
	{
    
    
		printf("Usage:./diyDaemon <Program execution path>\n");
		exit(0);	
	}

	//将本程序设定为守护进程
	//int daemon(int nochdir, int noclose);
	//函数参数:
	//nochdir:为0时表示将当前目录更改至“/”
	//noclose:为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”
	
	if(-1 == daemon(0, 0))
	{
    
    
		printf("daemon error\n");
		exit(1);
	}

	//copy守护的程序的路径名到path数组中,因为strtok会更改到path的值,所以用copy 
	strcpy(path,argv[1]);	
	sprintf(startUpCmd,"%s &",argv[1]);		//将守护的程序设为后台运行
	
	//分割输入的路径名,以获得程序的名字,默认以“/”来分割
	token=strtok(path,"/");
	while(token != NULL)
	{
    
    
		programName = token;
		token=strtok(NULL,"/");		//NULL代表从上一次切割剩下的path字符串中继续切割
	}
	
	while(1)
	{
    
    
		//检测守护的程序是否存在,grep的时候,排除掉“grep进程、自身”,
		//防止误认为守护的进程还活着
		sprintf(cmd,"ps -ef | grep %s |grep -Ev '(grep|diyDaemon)'",programName);	
		//puts(cmd);
		file = popen(cmd,"r");		//popen相比于system,可以读取到命令的输出结果
		fgets(returnBuffer,BUFSIZE,file);
		
		//通过比对来确认守护进程是否活着,如果死去了就重新拉起
		if(strstr(returnBuffer,programName) == NULL)
		{
    
    
			printf("%s\n",startUpCmd);
			system(startUpCmd);
		}
		memset(returnBuffer,'\0',BUFSIZE);
		
		//!这里特别重要,花费了许多时间才排查到
		//不加的话,returnBuffer的数据永远都是第一次获得数据;导致后面的比对有误
		//读man手册可知,因为popen进程执行时输出输出缓冲区和本程序共享
		//所以并没有将数据从输出缓存区中读出,所以要用fflush来清空缓存区;
		//或者用fread来将数据读出也行;
		fflush(file);		
		sleep(3);
	}
	pclose(file);
	return 0;
}

Direction to be optimized

1. If outputTimer.shthe startup needs parameters, it cannot be used. It needs to be improved to allow the program to be guarded to start with parameters. 2. It can be optimized so that the
path parameters when executing the program can use relative paths instead of only absolute paths. 3.
Yes Add a log function, which can record how many times the guarded program hangs up, which is convenient for later optimization of the guarded program

Of course, as a little brother who has written a shell for a while, he also wrote a shell version of this program for your reference. The functions are basically the same, and the shell version seems to be more concise. If you are a student of operation and maintenance, you may Do you like this better?

Note that when executing this script, add & to make it execute better in the background, that is, "script name &", so that it will not occupy the terminal

#!/bin/bash
path=$1
echo $path
file=${
    
    path##*/}
echo $file
while :
do
	procnum=`ps -ef|grep $file|grep -Ev '(grep|test.sh)' | wc -l`
	#echo $procnum
	if [ $procnum -eq 0 ];then
		`$path &`
	fi
	sleep 3
done

Of course, in actual work, there are many more professional tools that can realize this function, such as supervisor. In short, in actual work, you can use it flexibly

Guess you like

Origin blog.csdn.net/weixin_44517500/article/details/129031469