如何在Linux下 自定义/编写 一个守护进程

news2024/11/24 9:00:07

【摘要】本文主要讲述何为守护进程,以及如何自编或者利用现有程序将其伪装成守护进程。

何为守护进程?

  • 正常情况下,当我们运行一个前台或后台进程时,一旦离开当前会话(终端),那该会话中的所有前后台进程也随即结束,当你重新打开会话时,已经“物是人非,难遇故人”了。
  • 而守护进程就可以不受会话的限制,可在前后台一直运行直至结束的进程。
  • 守护进程的实现有两种方式:自编和利用现有程序伪装,下文将分别讲述。

自编守护进程的一般步骤及代码实例

通常,当我们写一个守护进程时,需要按照如下步骤来写:

  1. 创建一个子进程,父进程随即退出

    • fork()函数用来创建一个子进程;

    • 在父进程退出后,后续所有步骤在子进程中进行。

  2. 在子进程中创建新会话

    • setsid()函数用来创建一个新的会话;
    • 创建新的会话的目的是使子进程完全从父进程中独立出来,使得即使父进程所在会话(终端)被关闭,也不会影响子进程。
  3. 改变子进程当前工作目录,一般设为根目录

    • chdir()函数用来为子进程重新分配工作目录;
    • 重新制定工作目录的原因是防止原来父进程工作目录含有可卸载的目录(文件系统),从而为今后守护进程的运行产生不必要的麻烦。
    • 工作目录一般设为根目录,当然也可以换成其它安全路径。
  4. 重设文件权限掩码

    • umask()函数用来更改子进程的默认掩码;
    • 文件权限掩码一般设为0,便于在守护进程中指定的文件权限不受掩码干扰,增加灵活性;
      • 通常,系统默认的文件权限为666(rw-rw-rw-),默认的文件权限掩码为022,故最后二者相与,得到的文件真实权限为644(rw-r–r–)。
  5. 关闭文件描述符

    • close()函数用来关闭文件描述符指定的文件;

    • 从父进程继承的打开文件及默认打开的0、1、2在守护进程中一般不会用到,而且又浪费系统资源,所以一般要关闭他们。

    • getdtablesize()函数返回当前打开的文件项数;

  6. 守护进程功能实现(无限循环)

  • 代码实例

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string.h>  
    #include <unistd.h>  
    #include <sys/wait.h>  
    #include <sys/types.h>  
    #include <fcntl.h>  
      
    int main() 
    {    
        pid_t pid;  
        int i, fd, len;  
        char *buf = "守护进程运行中.\n";  
        len = strlen(buf)+1;
        
        pid = fork();	//1.1 创建子进程
        if (pid < 0) {  
        	printf("fork error!");  
        	exit(1);  
        }
        if (pid>0) 		// 1.2父进程退出  
        	exit(0);  
          
        setsid(); 		// 2.在子进程中创建新会话。  
        
        chdir("/"); 	// 3.设置工作目录为根目录  
        
        umask(0); 		// 4.设置权限掩码  
        
        for(i=0; i<getdtablesize(); i++) //5.关闭用不到的文件描述符  
        	close(i);
        
        //6.守护进程功能实现
        while(1) {			// 死循环表征它将一直运行
            fd = open("/var/log/daemon.log",O_CREAT|O_WRONLY|O_APPEND,0600);
        	if(fd < 0) {
                printf("Open file failed!\n");
                exit(1);  
        	}  
        	write(fd, buf, len);  // 将buf写到fd中  
        	close(fd);  
        	sleep(10);  
        	printf("error: Never run here!\n");
            return 1;
        }  
          
    	return 0;  
    }
    
    • 注意:因为守护进程关闭了所有文件描述符,包括默认的标准输入输出和出错,所以在终端上看不到其输出。
    • 运行该程序后,可以通过执行:cat /var/log/daemon.log查看进程运行情况;也可以通过ps -axjf | grep 程序名查看。
    • 关闭当前会话(终端),再次重复执行上步命令,查看进程是否还在运行!

利用现有程序伪装成守护进程

  • 意思就是希望某一个程序能够在当前会话被关闭后,照样能够运行,方法也很简单,就是利用nohup命令。

  • 例如,我想运行一个命令sleep 1000,正常情况下,该命令在终端执行后,如果关闭该终端,命令随之结束,而不会等到1000秒之后。

  • 通过执行:nohup sleep 1000 &命令后,查看sleep的运行情况如下:

    image-20221203214435510

  • 关闭当前会话窗口,再重新打开,执行ps axjf | grep sleep命令发现它任然在执行中。

    image-20221203214533220

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

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

相关文章

BlockingQueue

网上看了好多文章将线程池的但是似乎都没的多少人会详细讲解里面的任务队列&#xff0c;所以只有自己动手学习其中的任务队列 BlockingQueue 要学习其中的任务队列就需要先学习BlockingQueue&#xff0c;Blocking是一个接口&#xff0c;其中主要的方法为 // 尝试往队尾添加元素…

m基于OFDM的OMP压缩感知信道估计算法误码率仿真,对比传统的LS,MMSE以及LMMSE信道估计性能

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 正交频分复用技术(orthogonalfrequencydivisionmultiplexing,ofdm)应用在通信系统中可以有效抵抗码间干扰(inter-symbolinterference,isi)。同时&#xff0c;通过在符号间插入循环前缀(cyclicpre…

格利尔在北交所上市:市值突破9亿元,朱从利夫妇为实控人

12月2日&#xff0c;格利尔数码科技股份有限公司&#xff08;下称“格利尔”&#xff0c;BJ:831641&#xff09;在北京证券交易所上市。本次上市&#xff0c;格利尔公开发行1050万股&#xff0c;发行价格为9.60元/股&#xff0c;发行市盈率为23.32倍。 据了解&#xff0c;格利尔…

压缩文件7-Zip与WinRAR个人免费版在不同压缩等级下的对比

总结&#xff1a; 压缩率越高&#xff0c;压缩及解压时间相对更长&#xff0c;但传输时间越短&#xff0c;消耗流量越少。在各个压缩等级下&#xff0c;7-Zip均比RAR的压缩率更高&#xff0c;更能达到**“压缩”**的目的&#xff1b;而且相同参数下的压缩速度更快&#xff0c;…

基于增强蛇优化算法求解单目标优化问题附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

从源码分析vue3组件的生命周期

概览 借官网一张图充篇幅☺ 这张图展示了一个vue组件从开始渲染到卸载结束一整个生命周期经历的每个环节 但只罗列了选项式api生命周期钩子&#xff0c;没有将组合式api的生命周期钩子放进去 下面这个表格列出了所有选项式api生命周期钩子和组合式api生命周期钩子&#xff0c…

函数的节流和防抖?节流和防抖的区别及实现

一.防抖和节流的本质 本质上就是优化高频率执行代码的一种手段。 比如说&#xff1a;浏览器的scroll,keypress,mousemove,resize等事件在触发时&#xff0c;会不断的调用绑定在事件上的回调函数&#xff0c;会极大地浪费资源&#xff0c;降低前端的性能。 因此为了优化用户体…

【C++模板】非类型模板参数

目录什么是非类型模板参数&#xff1f;非类型的类模板参数非类型的函数模板参数非类型模板参数的局限性限制使用的场景支持使用的场景什么是非类型模板参数&#xff1f; 在函数模板和类模板中&#xff0c;模板参数并不仅仅可以当作类型&#xff0c;还可以当作普通值。当使用普通…

Numpy解决找出二维随机矩阵中每行数据中最接近某个数字的数字

解决思路&#xff1a; 利用np.random.rand()函数生成随机的矩阵。abs函数实现对矩阵中每一个元素和指定元素相减np.argsort()函数实现找到排序后新元素在原来矩阵中的下标利用mask函数提取矩阵中第一列的元素最后利用for循环遍历所有的二维坐标&#xff0c;找到矩阵中每行中满…

微信小程序-读取数据

在开发微信小程序的时候,我们经常都会用到一些配置数据,或者当做“单向数据库(只读)”使用。 我们新建一个新的项目工程,JS版本就可以。 免于麻烦,我们新建一个page(showdata)来显示数据。 为了方便管理,我们在项目工程新建一个目录(data),用于存数据。另外我们再新…

面向对象-05-06-构造方法,标准的 javabean 类

实例化的本质就是调用构造方法 package com.luo.demo01;public class StudenTest {public static void main(String[] args) {// 创建对象// 本质&#xff1a;调用构造器Student s new Student();Student student new Student("luo",18);System.out.println(studen…

Git系列,自定义 git 命令,用 shell 脚本帮助你更好的实现 git 版本控制

一、问题引出 在实际的生产当中&#xff0c;无论是 git、小乌龟 git 、idea git 插件&#xff0c;都满足不了我们生产中遇到的一些常见的问题&#xff0c;例如&#xff1a; 工作任务重的时候&#xff0c;手头上可能有若干个分支&#xff0c;每个分支对应着不同的业务&#xf…

Mysql面试题汇总

Mysql面试题 文章目录Mysql面试题一 Mysql索引001 Mysql如何实现的索引机制&#xff1f;002 InnoDB索引与MyISAM索引实现的区别是什么&#xff1f;003 一个表中如果没有创建索引&#xff0c;那么还会创建B树吗&#xff1f;004 说一下B树索引实现原理&#xff08;数据结构&#…

妙啊,Python 管道 Pipe 编写代码如此优雅

大家好&#xff0c;今天这篇文章我将详细讲解 Pipe 如何让你的代码更加简洁的方法&#xff0c;喜欢本文点赞支持&#xff0c;欢迎收藏学习&#xff0c;文末提供技术交流群&#xff0c;欢迎畅聊&#xff01; 我们知道 map 和 filter 是两种有效的 Python 方法来处理可迭代对象。…

如何基于YAML设计接口自动化测试框架?看完秒会!

在设计自动化测试框架的时候&#xff0c;我们会经常将测试数据保存在外部的文件&#xff08;如Excel、YAML、CSV&#xff09;或者数据库中&#xff0c;实现脚本与数据解耦&#xff0c;方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测试用例&…

[附源码]计算机毕业设计springboot招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

电子学会2021年6月青少年软件编程(图形化)等级考试试卷(四级)答案解析

青少年软件编程&#xff08;图形化&#xff09;等级考试试卷&#xff08;四级&#xff09; 分数&#xff1a;100.00 题数&#xff1a;24 一、单选题&#xff08;共10题&#xff0c;每题3分&#xff0c;共30分&#xff09; 1. 执行下列程序&#xff0c;输出的结果为…

bert 环境搭建之PytorchTransformer 安装

这两天跑以前的bert项目发现突然跑不了&#xff0c;报错信息如下&#xff1a; Step1 transformer 安装 RuntimeError: Failed to import transformers.models.bert.modeling_bert because of the following error (look up to see its traceback): module signal has no att…

IOT物联网系统架构

主要由 IotCloodServer物网联服务平台&#xff0c; IotAdminWeb物联网管理平台&#xff0c; IotDataProcessing物联网数据平台&#xff0c; IotDeviceGateway物联网边缘网关&#xff0c; IotDeviceToolHepler物联网边缘网关 控制 设备的工具类&#xff0c; IotApp物联网应…

SpringBoot_整合Mybatis

一 导入依赖 <!--整合mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><group…