【linux C】daemon函数应用之——进程守护小工具,运维仔看了都说好!并附带shell版本

news2024/11/28 14:47:21

最近接触到Linux C中的daemon函数,顾名思义,它和守护进程Daemon有关;简单来说Linux Daemon(守护进程)是运行在后台的一种特殊进程;

一般来说,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件,因为守护进程是在后台运行,不会占着终端,所以终端可以执行其他命令。

Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等

利用它后台执行且不占用终端的特点,也可以用来守护其他程序,它处于不断监控的状态,一旦监控到目标程序“死掉”,便马上将其“拉起”;

废话不多说,来看案例:

目标

要保证outputTimer.sh程序在后台一直处于“活着”的状态,一旦发现它突然崩溃,则自动将其拉起;

使用方法

本程序名为: diyDaemon
执行方法:./diyDaemon + <待守护程序所在的全路径>

效果

利用diyDaemon这个守护进程来保证outputTimer.sh处于“活着”的状态;

1、可以看到起初并没有outputTimer.sh进程,执行diyDaemon后,便将自动outputTimer.sh拉起来

执行前

执行后

2、手动杀掉outputTimer.sh进程,根据Pid号可知,又拉起来一个outputTimer.sh程序继续运行,从而保证一直有outputTimer.sh活着

杀掉进程

代码

代码中已详细注释

#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;
}

待优化方向

1、如果outputTimer.sh的启动需要参数的话,则无法使用,需要改进为允许待守护的程序可带参数启动
2、可以优化为执行程序时的路径参数可以用相对路径,而不是只能绝对路径
3、可以增加一个日志功能,可记录守护的程序挂了多少次,方便后期优化被守护的程序

当然作为曾经写过一段时间shell的小哥,也给这个程序写了给shell版本的,供大家参考,功能基本上一致,shell版本的似乎看起更简洁,如果做运维的同学,可能会更喜欢这种吧

注意执行这个脚本的时候加上&,让它在后台执行好一点,即“脚本名 &” ,这样不会占用终端

#!/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

当然,实际工作中,也有很多更专业的可实现这个功能的工具,比如supervisor。总之,实际工作时,灵活运用即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/345080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

认识V模型、W模型、H模型

软件测试与软件工程息息相关&#xff0c;软件测试是软件工程组成中不可或缺的一部分。 在软件工程、项目管理、质量管理得到规范化应用的企业&#xff0c;软件测试也会进行得比较顺利&#xff0c;软件测试发挥的价值也会更大。 要关注软件工程、质量管理以及配置管理与软件测试…

ChatGPT中文网尝鲜,感觉自己快下岗了

最近很火的ChatGPT之初体验 ChatGPT中文网 居然可以回答代码问题 尝试了一下, 它居然说自己是一个人 顺便问了下简单的java代码问题 “使用java语言写一个递归打印D盘中所有文件名的程序” 很流畅的回答了出来,注释还写得比我详细,感觉我离下岗不远了 这就是GPT写的代码 i…

工人不戴安全帽自动检测识别 opencv

工人不戴安全帽自动检测识别通过pythonopencv深度学习网络模型&#xff0c;工人不戴安全帽自动检测识别算法对现场人员穿戴进行全天候不间断识别检测&#xff0c;发现现场人员违规行为着装自动抓拍存档。Python是一门解释性脚本语言。解释性语言&#xff1a;解释型语言&#xf…

C语言中大小端问题

目录 一、什么是大小端 二、 举个例子 三、大小端演示 四、解释"二"中举例的问题 ​五、怎么判断是大端还是小端 六、一个题目 一、什么是大小端 大端模式&#xff08;大端字节序存储&#xff09;&#xff1a;就是高位字节数据存放在内存的低地址端&#xff…

工序排序问题--约翰逊法精讲

什么是约翰逊法?约翰逊法是作业排序中的一种排序方法。选出最短加工时间i*&#xff0c;若最短加工时间有多个&#xff0c;任选1个.若i*出现在机床1&#xff0c;它对应的工件先安排加工&#xff0c;否则放在最后安排&#xff0c;安排后划去该工件,重复上两个步骤&#xff0c;直…

python3.11下载安装详细教程

python3.11新的功能特性 1. 支持新的字符串格式化功能&#xff0c;允许使用更多的格式化选项&#xff1b; 2. 支持新的数据类型&#xff0c;如结构化数据类型&#xff1b; 3. 支持新的编程模型&#xff0c;如asyncio&#xff1b; 4. 支持新的编程语言特性&#xff0c;如f-s…

别在用scroll去做懒加载了,交叉观察器轻松搞定

Ⅰ、前言 「懒加载」是网页中非常 常见的&#xff1b;为了减少系统的压力&#xff0c;对于一些电商系统出场频率非常高&#xff1b;那么大家一般用什么方式去实现 「懒加载」 呢 &#xff1f; ① 通过 scroll 的形式&#xff1a; 通过 滚动「scroll」事件&#xff0c;然后去判…

浅析 Makefile

Makefile逻辑 Makefile就是将一系列的工作流串在一起自动执行&#xff0c;构成Makefile最基本的要素是目标、依赖、命令。也就是为了实现目标需要哪些依赖并执行什么样的命令。 target: dependences1 dependences2 ... command1 command2 ...其中&#xff0c;target表示要生…

Thinking--FastDom消除浏览器布局抖动

Thinking系列&#xff0c;旨在利用10分钟的时间传达一种可落地的编程思想。 对于大量操作 DOM 的场景&#xff0c;页面时常会出现卡顿现象&#xff0c;导致用户体验不佳。卡顿的原因是由于掉帧导致&#xff01;&#xff01; 掉帧 现在屏幕大部分的固定刷新频率为60Hz&#xf…

30个HTML+CSS前端开发案例(完结篇)

30个HTMLCSS前端开发案例&#xff08;完结篇&#xff09;flex弹性布局-今日头条首页热门视频栏代码实现效果flex弹性布局-微博热搜榜单代码实现效果grid网格布局-360图片展示代码实现效果综合实例-小米商城左侧二级菜单代码实现效果资源包flex弹性布局-今日头条首页热门视频栏 …

Pinia快速入门

Pinia学习1.做什么用的❓2.优势❓3. 介绍❓3.1、与vuex对比与 Vuex 3.x/4.x 的比较#4.实操使用&#x1f4aa;版本须知4.1创建项目4.2运行项目4.3使用pinia安装全局引入挂载使用stategettersactions示例代码分析1.做什么用的❓ 与vuex的作用一致&#xff0c;用于做网页存储的Pin…

【STC15单片机】模拟I2C操作AT24C02数据读取【更新中】

目录 I2C时序结构 I2C代码 AT24C02代码&#xff08;继承I2C底层代码&#xff09; PCF8591 PCB上线的长短可能影响数据传输的时间&#xff0c;写I2C时序可能就要加一点延时 I2C时序结构 起始条件&#xff1a;SCL高电平期间&#xff0c;SDA从高电平切换到低电平终止条件&…

什么蓝牙耳机好用性价比高?性价比最高的蓝牙耳机品牌排行

无线耳机迅速成为了电子产品中的佼佼者&#xff0c;无论是日常通勤、办公或是休闲、娱乐&#xff0c;几乎都能看到戴耳机听音乐的人&#xff0c;细心的朋友应该能够发现&#xff0c;蓝牙耳机在这几年有了很大的进步&#xff0c;下面我就分享几款当前性价比最高的蓝牙耳机。 TO…

T38,数的递归

描述 输入一棵节点数为 n 二叉树&#xff0c;判断该二叉树是否是平衡二叉树。 在这里&#xff0c;我们只需要考虑其平衡性&#xff0c;不需要考虑其是不是排序二叉树 平衡二叉树&#xff08;Balanced Binary Tree&#xff09;&#xff0c;具有以下性质&#xff1a;它是一棵空…

分账系统逻辑

一、说明 主体与业务关系方进行相关利益和支出的分配过程 使用场景&#xff1a; 在分销业务中&#xff0c;主营商户收到用户购买分销商品所支付的款项后&#xff0c;可以通过分账逻辑&#xff0c;与分销商进行佣金结算。在零售、餐饮等行业中&#xff0c;当销售人员完零售等…

小樽 C++指针—— (壹) 指针变量

(壹) 指针变量 一、指针的概念与定义 二、给指针变量p赋值 三、指针变量的的、-运算 四、无类型指针 五、多重指针 C (壹) 指针变量 小明想把从李华家借来的书——《CCF中学生计算机程序设计》还给李华&#xff0c;但李华不在家&#xff0c;于是把书放到书架第3层的最右边…

入门介绍对ChatGPT的应用程序接口API的访问<openai模块>

首先本人建议使用国内环境安装openai模块(这是我切换环境使用国外IP之后安装有问题的建议)pip install openai -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com安装好了之后&#xff0c;我们切换成科学上网&#xff0c;然后我们来到https://platform.openai…

十大开源测试工具和框架,一定有你需要的

目录 前言 Katalon Studio Selenium Appium JMeter SOAP UI Robot Framework Watir JUnit Robotium Citrus 总结 前言 免费的开源框架和工具由于其开源特性&#xff0c;现在逐渐成为自动化测试的首选解决方案。区别在于&#xff0c;你是喜欢使用类库编写一个全新的…

Ubuntu20.04安装redis与远程连接

一、安装Redis5.7 1、安装Redis apt-get install redis-server2、安装完成后&#xff0c;Redis服务器会自动启动。查看redis是否启动成功 service redis-server status #查看状态如下显示Active:active(running)状态&#xff1a;表示redis已在运行&#xff0c;启动成功。 …

Linux常用命令1

目录1、远程登陆服务器2、文件相关&#xff08;1&#xff09;文件和目录属性&#xff08;2&#xff09;创建目录mkdir&#xff08;3&#xff09;删除目录rmdir&#xff08;4&#xff09;创建文件touch&#xff08;5&#xff09;删除文件或目录rm&#xff08;6&#xff09;ls命令…