在Linux中,我想添加一个无法停止且监视文件系统更改的守护程序。如果将检测到任何更改,则应将路径写入启动它的控制台+换行符。
守护程序在后台工作,并且(通常…)不属于TTY,这就是为什么您无法以可能想要的方式使用stdout /
stderr的原因。通常,使用syslog守护程序( syslogd )将消息记录到文件中(调试,错误等)。
除此之外,还有一些 必需的步骤 来守护进程。
如果我没有记错的话,这些步骤是:
- 分叉 父进程,如果分叉成功,则终止它。->由于父进程已终止,因此子进程现在在后台运行。
- setsid- 创建一个新会话。调用过程将成为新会话的负责人和新过程组的过程组负责人。现在,该过程已从其控制终端(CTTY)分离。
- 捕获信号 -忽略和/或处理信号。
- 再次分叉并 让父进程终止,以确保您摆脱了会话引导进程。(只有会议负责人才能再次获得TTY。)
- chdir- 更改守护程序的工作目录。
- umask- 根据守护程序的需要更改文件模式掩码。
- close- 关闭所有可能从父进程继承的打开文件描述符。
为您提供一个起点:查看显示基本步骤的此框架代码。现在,也可以在GitHub上分叉此代码:linux守护程序的基本框架
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <syslog.h>static void skeleton_daemon(){ pid_t pid; pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); if (setsid() < 0) exit(EXIT_FAILURE); //TODO: Implement a working signal handler */ signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); umask(0); chdir("/"); int x; for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) { close (x); } openlog ("firstdaemon", LOG_PID, LOG_DAEMON);}int main(){ skeleton_daemon(); while (1) { //TODO: Insert daemon pre here. syslog (LOG_NOTICE, "First daemon started."); sleep (20); break; } syslog (LOG_NOTICE, "First daemon terminated."); closelog(); return EXIT_SUCCESS;}- 编译代码:
gcc -o firstdaemon daemonize.c
- 启动守护程序:
./firstdaemon
检查一切是否正常:
ps -xj | grep firstdaemon
输出应与此类似:
- ------ + ------ + ------ + ------ + ----- + ------- + ------ + ------ + ------ + ----- +
| PPID | PID | PGID | SID | TTY | TPGID | STAT | UID | 时间| CMD | - ------ + ------ + ------ + ------ + ----- + ------- + ------ + ------ + ------ + ----- +
| 1 | 3387 | 3386 | 3386 | ?| -1 | S | 1000 | 0:00 | ./ | - ------ + ------ + ------ + ------ + ----- + ------- + ------ + ------ + ------ + ----- +
- ------ + ------ + ------ + ------ + ----- + ------- + ------ + ------ + ------ + ----- +
您应该在这里看到的是:
- 守护程序没有控制终端( TTY =? )
- 父进程ID( PPID )为 1 (初始化进程)
该 PID!= SID ,这意味着我们的进程不是会话组长
(因为第二叉())由于PID!= SID,我们的过程 无法再次控制TTY
读取系统日志:
- 找到您的系统日志文件。我的在这里:
/var/log/syslog
做一个:
grep firstdaemon /var/log/syslog
输出应与此类似:
firstdaemon [3387]:第一个守护程序已启动。
firstdaemon [3387]:第一个守护程序终止。
注意: 实际上,您还需要实现信号处理程序并正确设置日志记录(文件,日志级别…)。
进一步阅读:
- Linux-UNIX-Programmierung-德语
- Unix守护程序服务器编程



