Linux 守护进程
Linux 守护进程概述
Linux Daemon (守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。 Linux 系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程 syslogd 、 web 服务器 httpd 、邮件服务器 sendmail 和数据库服务器 mysqld 等。
守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户( root )权限运行,因为它们要使用特殊的端口( 1-1024 )或访问某些特殊的资源。
一个守护进程的父进程是 init 进程,因为它真正的父进程在 fork 出子进程后就先于子进程 exit 退出了,所以它是一个由 init 继承的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备 stdout 还是标准出错设备 stderr 的输出都需要特殊处理。
工作原理
Linux 守护进程的工作模式是服务器 / 客户机( Server/Client ),服务器在一个特定的端口上监听( Listen )等待客户连接,连接成功后服务器和客户端通过端口进行数据通信。守护进程的工作就是打开一个端口,并且监听( Listen )等待客户连接。如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听其他的服务请求。
工作模式
Linux 守护进程有两种工作模式: stand-alone 模式和 xinetd 模式。
( 1 ) stand-alone 模式
独立运行的守护进程由 init 负责管理,所有独立运行守护进程的脚本在 /etc/rc.d/init.d/ 目录下。独立运行的守护进程工作方式称作 stand-alone ,是 Unix 传统的 C/S 模式的访问模式。服务器监听( Listen )在一个特点的端口上等待客户端的联机。如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听。工作在 stand-alone 模式下的网络服务有 route 、 gated 、 web 服务器等。在 Linux 系统中通过 stand-alone 工作模式启动的服务由 /etc/rc.d/ 下面对应的运行级别当中的符号链接启动。
( 2 ) xinetd 模式
从守护进程的概念可以看出,对于系统所要求的每一种服务,都必须运行一个监听某个端口连接所发生的守护进程,这意味着资源浪费。为了解决这个问题, Linux 引进了 " 网络守护进程服务程序 " 的概念。 Redhat Linux 使用的网络守护进程是 xinted ( eXtended InterNET Daemon )。和 stand - alone 模式相比 xinetd 模式也称 Internet
Super-Server (超级服务器)。 xinetd 能够同时监听多个指定的端口,在接受用户请求时,他能够根据用户请求的端口不同,启动不同的网络服务进程来处理这些用户请求。可以把 xinetd 看做一个管理启动服务的管理服务器,它决定把一个客户请求交给那个程序处理,然后启动相应的守护进程。
和 stand-alone 工作模式相比,系统不必为每一个网络服务进程监听其服务端口,运行 xinetd 守护进程就可以同时监听所有服务端口,这样就降低了系统开销,保护系统资源。但是对于访问量大、经常出现并发访问时, xinetd 想要频繁启动对应的网络服务进程,反而会导致系统性能下降。一般来说系统一些负载高的服务,比如 Apache 、 sendmail 等服务是单独启动的。而其他服务类型都可以使用 xinetd 超级服务器管理。
查看系统为 Linux 服务提供那种模式方法在 Linux 命令行可以使用 pstree 命令可以看到两种不同方式启动的网络服务。
Linux 守护进程管理
Linux 提供了几种不同的守护进程管理工具: ntsysv 、 chkconfig 等,可以根据具体需要灵活运用。
( 1 ) ntsysv
ntsysv 工具为启动或关闭由 xinetd 管理的服务提供了简单的界面,也可以使用 ntsysv 来配置运行级别。按照默认设置,只有当前运行级别会被配置。要配置不同的运行级别,使用 --level 选项来指定一个或多个运行级别。比如,命令 ntsysv --level 345 配置运行级别 3 、 4 、和 5 。使用上下箭头来上下查看列表。使用空格键来选择或取消选择服务,或用来 " 按 " 「确定」和「取消」按钮。要在服务列表和「确定」、「取消」按钮中切换,使用
[Tab] 键。 * 标明某服务被设为启动。 [F1] 键会弹出每项服务的简短描述。
(3)chkconfig
Chkconfig 工具可以用来启动或停止服务。
chkconfig --list 命令显示系统服务列表,以及这些服务在运行级别 0 到 6 中已被启动( on )还是停止( off ),还显示 xinetd 管理的系统服务。
chkconfig 还能用来设置某一服务在某一指定的运行级别内被启动还是被停运。比如,要在运行级别 3 、 4 、 5 中停运 nfs 服务,使用下面的命令: chkconfig
--level 345 nfs off
查看系统为 Linux 服务提供那种模式方法在 Linux 命令行可以使用 pstree 命令可以看到两种不同方式启动的网络服务。
Linux 守护进程列表
守护进程
含义
alsasound
Alsa 声卡驱动的守护程序
acpid
替代传统 APM 电源管理标准的新型电源管理标准( Advanced
Configuration and Power Interface Daemon )的守护进程
atalk
AppleTalk 网络的守护进程
amd
自动安装 NFS 的守护进程
anacron
自动运行任务的守护进程
apmd
高级电源管理( Advanced
Power Management )的守护进程
arpwatch
记录日志并构建一个在 LAN 接口上看到的以太网地址和 IP 地址的进程
atd
at 和 batch 命令的守护进程
autofs
自动安装管理进程的守护进程,与 NFS 相关,依赖于 NIS 服务器
bootparamd
引导参数服务器,为 LAN 上的无盘工作站提供引导所需的相关信息
bluetooch
蓝牙服务的守护进程
crond
Cron 服务的守护进程,该程序周期地运行用户调度的任务
chargen
使用 tcp 协议的 chargen server ,( Character Generator Protocol )是一种网络服务,主要功能是提供类似远程打字的功能
chargen-udp
使用 udp 协议的 chargen server 的守护进程
cpuspeed
监测系统空闲百分比,降低或加快 CPU 时钟速度和电压的守护进程
dhcpd
动态主机控制协议 (Dynamic
Host Control Protocol) 服务的守护进程
cups
提供第三代打印功能的守护进程 (Common UNIX Printing System)
daytime
使用 tcp 协议日期时间的守护进程,该协议为客户机实现从远程服务器获取日期和时间的功能
daytime-udp
使用 udp 协议日期时间的守护进程
dc_server
使用 SSL 安全套接字代理服务器的守护进程
dc_client
使用 SSL 安全套接字客户端的守护进程
diskdump
服务器磁盘备份的守护进程
echo
服务器回显客户数据服务的守护进程
echo-udp
使用 udp 协议的服务器回显客户数据服务守护进程
gated
网关路由的守护进程
gpm
为文本模式下的 Linux 程序如 mc(Midnight Commander) 提供鼠标的支持的守护进程( General Purpose Mouse
Daemon )
httpd
Web 服务器 Apache 的守护进程
inetd
网络管理的守护进程
innd
Usenet 新闻服务器的守护进程
iiim
中文输入法服务器的守护进程
iptables
防火墙功能的守护进程
irda
红外功能的守护进程
isdn
isdn 启动和中止服务的守护进程
krb5-telnet
使用 kerberos 5 认证的 telnet 守护进程
klogin
远程登陆的守护进程
irqbalance
对多个系统处理器环境下的系统中断请求进行负载平衡的守护进程
kshell
Kshell 服务器的守护进程
kudzu
硬件自动检测的守护进程,自动检测硬件的添加、删除等
ldap
目录访问协议服务器的守护进程( Lightweight Directory Access Protocol )
lm_seroems
检测主板工作情况的守护进程
lpd
老式打印服务的守护进程
mdmonitor
RAID 相关设备的守护程序
mysqld
Mysql 数据库的守护进程
named
名称服务器的守护进程
netplugd
网络接口管理的守护进程( Network
Cable Hot Plug Management Daemon )
netdump
远程网络备份服务器的守护进程
netfs
安装和卸载 NFS 、 SAMBA 和 NCP 网络文件系统的守护进程( Network Filesystem Mounter )
ntpd
使系统和一个精确的时间源保持时间同步的协议守护进程( Network Time Protocol Daemon )
network
激活、关闭网络接口的守护进程
pcmcia
支持笔记本 PCMCIA 服务的守护进程
portmap
支持 RPC 连接的守护进程, RPC 被用于 NFS 以及 NIS 等服务
postgresql
PostgreSQL 数据库的守护进程
random
随机数生成器的守护进程
rawdevices
使用集群文件系统时用于加载 raw 设备的守护进程
routed
支持 RIP 协议的自动 IP 路由表维护的守护进程
rsync
远程数据备份( Remote
Sync )的守护进程
rsh
Shell 服务器的守护进程
sendmail
邮件服务器的守护进程
smb
Samba 文件共享 / 打印服务的守护进程
snmpd
本地简单网络管理的守护进程
squid
代理服务器 squid 守护进程
sshd
OpenSSH ( Secure Shell Protocol )服务器的守护进程
smartd
监控硬盘的守护进程( Self
Monitor Analysis and Reporting Technology System )
syslog
系统引导时启动 syslog 和 klogd 系统日志守护进程的程序
time
使用 tcp 协议从远程主机获取时间和日期的守护进程
time-udp
使用 udp 协议从远程主机获取时间和日期的守护进程
tux
在 Linux 内核中运行 apache 服务器的守护进程
vsftpd
vsftp 服务器的守护进程
vncserver
VNC 服务( Virtual Network Computing 虚拟网络计算)的守护进程
xfs
X Window 字型服务器的守护进程,为本地和远程 X 服务器提供字型集
xinetd
支持多种网络服务的核心守护进程
ypbind
使客户进程能绑定或连接到网络信息系统( Network Information System )服务器的守护进程
yppasswdd
网络信息系统 NIS 口令服务器的守护进程
ypserv
网络信息系统 NIS 主服务器的守护进程
yum
自动升级和软件包管理的守护进程
运行不必要或有漏洞的守护进程会给操作系统带来安全和性能上的影响。如果操作系统中的任何一个漏洞,都可能使整个系统受到攻击。所以,增加系统安全的最佳办法就是尽量监视系统的功能。对于一些重要的守护进程,比如 crond 、 syslog 、 keytable 、 xinetd 、 kudzu 、 iptables 等是需要运行的; echo 、 echo-udp 、 daytime 、 daytime-udp 、 chargen 、 chargen-udp 主要是做调试用,普通用户基本用不到,可以关闭。
r 字开头的守护进程: rsh 、 rstatd 、 rsync 、 rusersd 、 rwalld 这些命令都是 Berkley 远程命令,因为都以字母 r 开头,故称 r* 命令。主要使用来使一台计算机上的某个用户以相同的帐户远程执行另一台计算机的一个程序。但是, r 命令已经被证实存在安全风险。对于确实需要的守护进程,应该尽量选用最新的版本程序,并增加其安全防范。 另外我们还要合理选择守护进程例如 innd 是运行新闻组服务的进程,如果用户不做 Usenet 服务器,应该关掉。
Linux 守护进程编程
守护进程最重要的特性是后台运行;其次守护进程必须与其运行前的环境隔离开来,这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建模式等。这些环境通常是守护进程从执行它的父进程(特别是 shell )中继承下来的;最后守护进程的启动方式有其特殊之处。它可以在 Linux 系统启动时从启动脚本 /etc/rc.d 中启动,可以由作业规划进程 crond 启动,还可以由用户终端(通常是 shell )执行。
总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。
编写守护进程的步骤:
( 1 )在父进程中执行 fork 并 exit 推出;
( 2 )在子进程中调用 setsid 函数创建新的会话;
( 3 )在子进程中调用 chdir 函数,让根目录 ”/” 成为子进程的工作目录;
( 4 )在子进程中调用 umask 函数,设置进程的 umask 为 0 ;
( 5 )在子进程中关闭任何不需要的文件描述符
Setsid 函数
#include
pid_t
setsid(void);
返回值:成功返回新会话的 ID ;失败返回 -1
setsid 函数创建一个新会话和新进程组, setsid 调用保证新会话没有控制终端。
守护进程调用该函数将成为新会话的会话领导和新进程组的进程组领导。
chdir 函数
#include
int
chdir(const char *path);
chdir 函数改变当前的工作目录为 path 所包含的新目录
umask 函数
#include
void
umask(int mask); // r-4; w-2; x-1
umask 函数改变目录和文件的创建模式。
第一个守护进程
$ vi
mydaemon1.c
/*
mydaemon1.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int
main(void)
{
pid_t
pid, sid;
time_t timebuf;
int
fd, len;
char
*buf;
// 创建子进程,然后父进程退出
pid = fork();
if(pid < 0){
perror("fork");
exit(EXIT_FAILURE);
}else
if(pid > 0){ // 父进程
exit(EXIT_SUCCESS);
}
// 子进程
// 创建新会话和新进程组
if((sid = setsid()) < 0){
perror("setsid");
exit(EXIT_FAILURE);
}
// 改变当前的工作目录到根目录
if((chdir("/")) < 0){
perror("chdir");
exit(EXIT_FAILURE);
}
// 改变目录文件的创建模式
umask(0);
// 关闭不必要的文件描述符
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// malloc buf
len = strlen(ctime(&timebuf));
buf = malloc(len+1);
// 子进程主要工作,每 10 秒钟向日志文件写入当前的时间
while(1)
{
if((fd = open("/var/log/mydaemon.log",
\
O_CREAT | O_WRONLY | O_APPEND,
0600)) < 0){
perror("open file");
exit(EXIT_FAILURE);
}
time(&timebuf);
bzero(buf, len+1);
strncpy(buf,
ctime(&timebuf),len+1);
write(fd, buf, len+1);
close(fd);
sleep(10);
}
free(buf);
exit(EXIT_SUCCESS);
}
该守护进程的主要任务是每 10 秒钟向日志文件 /var/log/mydaemon.log 写入当前的时间。
编译、运行 :
# gcc
mydaemon1.c -o mydaemon1
#
./mydaemon1
# cat
/var/log/mydaemon.log
Thu Sep
11 19:01:34 2008
Thu Sep
11 19:01:44 2008
Thu Sep
11 19:01:54 2008
Thu Sep
11 19:02:04 2008
# ps -elf
| grep mydaemon1
1 S root
4732 1
0 75 0 -
408 - 19:01 ? 00:00:00 ./mydaemon1
# kill -9
4732
运行时需要超级用户权限;
运行后查看生成的日志文件信息,该守护进程每 10 秒钟向日志文件写入当前的时间;
查看该守护进程,进程的父进程已变成 init 进程( PID=1 );
向该进程 PID 号发送信号强行终止该进程。
守护进程出错处理
守护进程调用了 setsid 函数就不再拥有控制终端,所以就无法正常向标准输出 stdout 或标准出错 stderr (比如出错信息)输出信息。幸运的是系统日志守护进程 syslogd 可以提供这一服务。
Syslog 函数
#include
void
openlog(char *ident, int option, int facility); //
打开日志
void
syslog(int priority, char *format, …); //
写入消息
void
closelog(void); //
关闭日志
syslog 函数向系统日志写入信息。
Option
含义
LOG_CONS
如果系统服务器不能使用,则写入控制台
LOG_NDELAY
立即打开连接,正常情况下直到发送第一条消息时才打开连接
LOG_PERROR
打印输出到标准出错 stderr
LOG_PID
在每条消息中包含进程的 PID
Facility
含义
LOG_AUTHPRIV
安全、授权消息
LOG_CRON
时钟守护进程 cron at
LOG_DAEMON
其他系统守护进程
LOG_KERN
内核消息
LOG_LOCAL[0-7]
为本地使用而保留
LOG_LPR
行打印机子系统
LOG_MAIL
邮件子系统
LOG_NEWS
新闻组子系统
LOG_SYSLOG
Syslogd 产生的消息
LOG_USER
默认
LOG_UUCP
UUCP
Priority
含义
LOG_EMERG
系统不能使用
LOG_ALERT
立即采取措施
LOG_CRIT
紧急条件
LOG_ERR
出错条件
LOG_WARNING
警告条件
LOG_NOTICE
正常但重大条件
LOG_INFO
信息消息
LOG_DEBUG
调试信息
openlog 发起到系统日志服务器的一个连接, closelog 关闭到系统日志服务器的连接, syslog 向系统日志服务器写入消息。严格讲 openlog 和 closelog 是可选的,因为 syslog 在首次调用时会自动打开日志文件。
下面的例子是出错时将错误信息写入系统日志里。
$ vi mydaemon_syslog.c
/*
mydaemon_syslog.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int
main(void)
{
pid_t
pid, sid;
time_t timebuf;
int
fd, len;
char
*buf;
pid = fork();
if(pid < 0){
syslog(LOG_ERR, "Error: fork %s\n", strerror(errno));
exit(EXIT_FAILURE);
}else if(pid > 0){ // Parent
exit(EXIT_SUCCESS);
}
// Child
// open log
openlog("mydaemon", LOG_PID,
LOG_DAEMON);
// setsid
if((sid = setsid()) < 0){
syslog(LOG_ERR, "Error: setsid
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// change work directory
if((chdir("/")) < 0){
syslog(LOG_ERR, "Error: chdir
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// change umask
umask(0);
// close unnessary file descriptions
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// malloc buf
len = strlen(ctime(&timebuf));
buf = malloc(len+1);
// main work, write current datetime to
file 10 second per
while(1)
{
if((fd =
open("/var/log/mydaemon.log", \
O_CREAT | O_WRONLY | O_APPEND,
0600)) < 0){
syslog(LOG_ERR, "Error: open
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
time(&timebuf);
bzero(buf, len+1);
strncpy(buf,
ctime(&timebuf),len+1);
write(fd, buf, len+1);
close(fd);
sleep(10);
}
free(buf);
// close log
closelog();
exit(EXIT_SUCCESS);
}
该守护进程出错时向 syslogd 写入出错信息
编译、运行 :
$ gcc
mydaemon_syslog.c -o mydaemon_syslog
$
./mydaemon_syslog
# cat
/var/log/messages | grep mydaemon
Sep 11
19:12:03 cn_emb_501 mydaemon[7165]: Error: open Permission denied
使用非超级用户 root 运行该守护进程,然后查询系统日志信息,可看到该守护进程打开文件时出错,没有权限。 Mydaemon 是打开日志时的名称,后面的数字 7165 是该守护进程的进程 PID 。即使时间信息仍然被写入到 /etc/log/mydaemon.log 文件,但该进程产生的所有出错信息都被记录到系统日志 /var/log/messages 文件。
控制守护进程
/*
mydaemon_control.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NORMAL 1
#define
ROT13 2
int
style;
int
read_config(int etcfd, int *style)
{
int len;
char etcbuf[256];
if((len = read(etcfd, etcbuf, 256)) <
0){
syslog(LOG_ERR, "Error: read
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
etcbuf[len]='\0';
// Determine style
if( strncmp(etcbuf, "normal", 6)
== 0){
*style = NORMAL;
syslog(LOG_INFO, "output style is
normal\n");
}else if( strncmp(etcbuf,
"rot13", 5) == 0){
*style = ROT13;
syslog(LOG_INFO, "output style is
rot13\n");
}else{
syslog(LOG_ERR, "invalid output style\n");
return(2);
}
return(0);
}
void
sig_act(int sig)
{
if( sig == SIGUSR1){
style = NORMAL;
syslog(LOG_INFO, "Recieved
SIGUSR1, output style change to normal\n");
}else if( sig == SIGUSR2){
style = ROT13;
syslog(LOG_INFO, "Received
SIGUSR2, output style change to rot13\n");
}else{
style = 0;
}
return;
}
int
main(void)
{
pid_t
pid, sid;
time_t timebuf;
int
i, fd, etcfd, len;
char
*buf;
pid = fork();
if(pid < 0){
syslog(LOG_ERR, "Error: fork
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}else if(pid > 0){ // Parent
exit(EXIT_SUCCESS);
}
// Child
// open log
openlog("mydaemon", LOG_PID,
LOG_DAEMON);
// open config file
if((etcfd =
open("/etc/mydaemon.conf", O_RDONLY)) < 0){
syslog(LOG_ERR, "Error: open
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// read config file
if((len = read_config(etcfd, &style))
< 0){
syslog(LOG_ERR, "Error: read
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// close config file
if(close(etcfd) < 0){
syslog(LOG_ERR, "Error: close
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// setsid
if((sid = setsid()) < 0){
syslog(LOG_ERR, "Error: setsid
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// change work directory
if((chdir("/")) < 0){
syslog(LOG_ERR, "Error: chdir
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// change umask
umask(0);
// close unnessary file descriptions
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// malloc buf
len = strlen(ctime(&timebuf));
buf = malloc(len+1);
// register signal
signal(SIGUSR1, sig_act);
signal(SIGUSR2, sig_act);
// main work, write current datetime to
file 10 second per
while(1)
{
if((fd =
open("/var/log/mydaemon.log", \
O_CREAT | O_WRONLY | O_APPEND,
0600)) < 0){
syslog(LOG_ERR, "Error: open
%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
time(&timebuf);
bzero(buf, len+1);
strncpy(buf,
ctime(&timebuf),len+1);
// if style is rot13, rotate character;
normal style, keep unchanged
if(style == ROT13){
for(i=0; i<=len; i++)
{
if(buf[i] >= 'A' &&
buf[i] <= 'M' || buf[i] >= 'a' && buf[i] <= 'm'){
buf[i] +=13;
}else if( buf[i] >= 'N'
&& buf[i] <= 'Z' || buf[i] >= 'n' && buf[i] <= 'z'){
buf[i] -=13;
}
}
}else{
;
}
write(fd, buf, len+1);
close(fd);
sleep(10);
}
free(buf);
// close log
closelog();
exit(EXIT_SUCCESS);
}
该程序开始通过读取配置文件获取输出模式,用户通过发送信号来改变输出模式。
Read_config 函数从配置文件 /etc/mydaemon.conf 中查找两个值中的一个,如果值为 normal ,则守护进程的写入时间与正常情况下一样;如果值为 rot13 ,会把每个字符向前或后移动 13 个位置,用旋转后的值代替实际值。 Rot13 是称为凯撒密码的一类加密方法的一种简单的形式,根据公式处理文本,很容易破解。
函数还注册了两个信号,用来改变输出的模式,如果收到 SIGUSR1 信号,改成正常输出模式;收到 SIGUSR2 信号,改成 Rot13 模式。程序每 10 秒钟并根据当前的输出格式向日志文件写入当前的时间。
编译、运行
$ gcc
mydaemon_control.c -o mydaemon_control
$ su 切换到 root 用户
# vi
/etc/mydaemon.conf 编辑配置文件
rot13
#
./mydaemon_control 运行守护进程
# cat
/var/log/mydaemon.log 查看守护进程的日志文件
Sev Frc
12 19:57:26 2008
Sev Frc
12 19:57:36 2008
# ps -elf
| grep mydaemon_control 查看该守护进程的进程 PID
1 S root
7384 1
0 75 0 -
408 - 19:57 ? 00:00:00 ./mydaemon_control
# kill –SIGUSR1
7384 向该守护进程发送 SIGUSR1 信号
# cat
/var/log/mydaemon.log 查看守护进程的日志文件
Sev Frc
12 19:57:26 2008
Sev Frc
12 19:57:36 2008
Fri Sep
12 19:57:42 2008
Fri Sep
12 19:57:52 2008
# kill –SIGUSR2
7384 向该守护进程发送 SIGUSR1 信号
# cat
/var/log/mydaemon.log 查看守护进程的日志文件
Sev Frc
12 19:57:26 2008
Sev Frc
12 19:57:36 2008
Fri Sep
12 19:57:42 2008
Fri Sep
12 19:57:52 2008
Sev Frc
12 19:57:58 2008
# cat
/var/log/messages | grep mydaemon 查看系统日志文件信息
Sep 12
19:57:06 cnemb505 mydaemon[7384]: output style is rot13
Sep 12
19:57:42 cnemb505 mydaemon[7384]: Recieved SIGUSR1, output style change to
normal
Sep 12
19:57:58 cnemb505 mydaemon[7384]: Received SIGUSR2, output style change to
rot13
编译好后切换到超级用户权限,首先创建该守护进程的配置文件 /etc/mydaemon.conf, 写入 rot13 字符串;然后超级用户权限运行该守护进程;查看该进程生成的日志文件 /var/log/mydaemon.log ,程序读取配置文件信息输出格式为 rot13 模式;使用 ps 工具查看该守护进程的 PID ;分别向该进程发送 SIGUSR1 和 SIGUSR2 信号,日志文件的输出格式也随之改变;查看系统日志文件 /var/log/messages ,看到该守护进程输出模式的改变情况。