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
相关推荐
运维有小邓@21 小时前
Active Directory服务账户是什么?
运维·服务器·网络
HIT_Weston21 小时前
84、【Ubuntu】【Hugo】搭建私人博客:文章目录(三)
linux·运维·ubuntu
moxiaoran57531 天前
使用docker安装myql 8.0
运维·docker·容器
qq_5470261791 天前
Linux 常用快捷键及文本编辑器
linux·运维·服务器
埃伊蟹黄面1 天前
磁盘级文件系统核心原理解析
linux·文件
醇氧1 天前
【Linux】 安装 Azul Zulu JDK
java·linux·运维
一直跑1 天前
查看显卡驱动版本,查看哪个用户使用显卡(GPU)进程
linux·服务器
滴水之功1 天前
Windows远程桌面(非图形化界面)连接Ubuntu22.04
linux
借你耳朵说爱你1 天前
在Linux上挂载磁盘
linux
小成202303202651 天前
Linux高级
linux·开发语言