Linux下的守护程序

启动流程

嵌入式设备下Linux的内核系统启动的流程并不复杂,从最早的父进程init开始,为创建各种服务进程:系统会从 inittab 文件中,读取每一行作为执行命令👇

bash 复制代码
# Note: BusyBox init doesn't support runlevels.  The runlevels field is completely ignored by BusyBox init. If you want runlevels, use
# sysvinit.
#
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id        == tty to run on, or empty for /dev/console
# runlevels == ignored
# action    == one of sysinit, respawn, askfirst, wait, and once
# process   == program to run

# Startup the system
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,ro,noatime /
::sysinit:/bin/mount -t tmpfs tmpfs /dev
::sysinit:/bin/mkdir -p /dev/pts
::sysinit:/bin/mkdir -p /dev/shm
::sysinit:/bin/mount -a
::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::sysinit:/etc/init.d/rcS

# Put a getty on the serial port
ttySLB0::respawn:/sbin/getty -L -n -l /bin/autologin ttySLB0 0 vt100 # GENERIC_SERIAL

# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot

# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r

sysinit即为系统启动时要做的内容

  1. 挂载目录文件
  2. 创建目录
  3. 读取fstab内容实现自动挂在
  4. 设置主机名信息
  5. /etc/init.d 目录下指定 rcS 脚本

rcS 脚本

查看rcS脚本文件,可知,rcS是为了启动 /etc/init.d 目录下一个个以 S 开头的可执行脚本,若不是以sh作为后缀,则执行 并直接传参为 start

bash 复制代码
#!/bin/sh
# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do
     # Ignore dangling symlinks (if any).
     [ ! -f "$i" ] && continue
     case "$i" in
        *.sh)
            # Source shell script for speed.
            (
                trap - INT QUIT TSTP
                set start
                . $i
            )
            ;;
        *)
            # No sh extension, so fork subprocess.
            $i start
            ;;
    esac
done

查看S*脚本

bash 复制代码
# cat S50telnet 
#!/bin/sh
# Start telnet....
TELNETD_ARGS=-F
[ -r /etc/default/telnet ] && . /etc/default/telnet

start() {
      printf "Starting telnetd: "
      start-stop-daemon -S -q -m -b -p /var/run/telnetd.pid \
                        -x /usr/sbin/telnetd -- $TELNETD_ARGS
      [ $? = 0 ] && echo "OK" || echo "FAIL"
}

stop() {
        printf "Stopping telnetd: "
        start-stop-daemon -K -q -p /var/run/telnetd.pid \
                          -x /usr/sbin/telnetd
        [ $? = 0 ] && echo "OK" || echo "FAIL"
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart|reload)
        stop
        start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

脚本中判断传入参数是否为start,以start-stop-daemon 命令启动守护进程。

start-stop-daemon

查看该命令的相关参数,常用的一些参数为👇
start-stop-daemon实现linux下的守护进程👈

bash 复制代码
# start-stop-daemon --help
Usage: start-stop-daemon [OPTIONS] [-S|-K] ... [-- ARGS...] 

Search for matching processes, and then
-K: stop all matching processes 				#停止所有匹配进程
-S: start a process unless a matching process is found #除非找到匹配的进程,否则启动进程

Process matching:
        -u USERNAME|UID Match only this user's processes
        -n NAME         Match processes with NAME in comm field in /proc/PID/stat
        -x EXECUTABLE   Match processes with this command in /proc/PID/cmdline
        -p FILE         Match a process with PID from FILE
        All specified conditions must match
-S only:
        -x EXECUTABLE   Program to run 			#执行命令
        -a NAME         Zeroth argument			#第零个参数
        -b              Background				#后台执行
        -N N            Change nice level		#更改nice等级
        -c USER[:[GRP]] Change user/group		#更改用户组
        -m              Write PID to pidfile specified by -p #将进程的PID写入-p指定的pid文件
-K only:
        -s SIG          Signal to send			# 发送信号
        -t              Match only, exit with 0 if found	
Other:
        -o              Exit with status 0 if nothing is done
        -v              Verbose
        -q              Quiet					#不输出进程信息

一个简单的示例example.sh,来自Debian /etc/init.d/ssh,不过在嵌入式的设备下,start-stop-daemon 源命令程序大多是轻量化裁剪过的,参数用较精简的-s -q -m -p 等即可(👆)

bash 复制代码
#!/bin/sh
# Quick start-stop-daemon example, derived from Debian /etc/init.d/ssh
set -e

# Must be a valid filename
NAME=foo
PIDFILE=/var/run/$NAME.pid
#This is the command to be run, give the full pathname
DAEMON=/usr/local/bin/bar
DAEMON_OPTS="--baz=quux"

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
  start)
        echo -n "Starting daemon: "$NAME
	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
	#无输出启动进程,将其PID存在$PIDFILE文件中,命令跟着的参数是 $DAEMON_OPTS
        echo "."
	;;
  stop)
        echo -n "Stopping daemon: "$NAME
	start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
        echo "."
	;;
  restart)
        echo -n "Restarting daemon: "$NAME
	start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE
	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
	echo "."
	;;

  *)
	echo "Usage: "$1" {start|stop|restart}"
	exit 1
esac

exit 0
相关推荐
上学的小垃圾4 小时前
基于docker安装MySQL(openEuler系统)
linux·mysql·docker·容器
一直C6 小时前
Linux网络编程|HTTP协议详解(报文、请求方法、状态码)
linux·http·wireshark·vim·visual studio
爱喝水的鱼丶6 小时前
SAP-ABAP:ABAP 用户出口开发规范与避坑指南:10 类典型错误与运维方案
运维·性能优化·sap·abap·增强·经验交流·出口
博、、6 小时前
从零构建智慧场馆解决方案:架构设计与开发实践
大数据·运维
敢敢是只喵i7 小时前
给现有业务系统接 AI 助手,入口怎么选?网页聊天、自动化任务与本地 Agent 对比
运维·人工智能·ai·开源·自动化·安全架构
章老师说8 小时前
BFE v1.8.6 正式发布:AI 网关计费精细化、Claude 协议与会话亲和性升级
运维·人工智能·ai·负载均衡·ai-native
Brilliantwxx8 小时前
【Linux】 进程(10) 进程控制深度解析:创建、终止与等待
linux·运维·服务器·c语言·开发语言·网络
欧米欧9 小时前
Linux基础指令上
linux·运维·服务器
爱喝水的鱼丶9 小时前
SAP-ABAP:BAdI 上下文数据获取与交互:标准数据读取与修改逻辑实现
运维·性能优化·sap·abap·增强·经验交流·badi
ARM|X86+FPGA工业主板厂家10 小时前
基于嵌入式 GPU 的智能服务机器人
linux·运维·arm开发·fpga开发·机器人