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
相关推荐
十夫长12 分钟前
centos与ubuntu系统版本介绍
linux·ubuntu·centos
海海不掉头发16 分钟前
Linux-编辑器的使用
linux·运维·编辑器
HappyGame0227 分钟前
Linux命令-Shell编程
linux·ssh
you秀33 分钟前
ubuntu20.04安装安装x11vnc服务基于gdm3或lightdm这两种主流的显示管理器。
linux·运维·服务器
梁萌42 分钟前
11-DevOps-Jenkins Pipeline流水线作业
运维·jenkins·devops·流水线·pipline
LCY1331 小时前
DevOps功能详解
运维·devops
梁萌1 小时前
05-DevOps-Jenkins自动拉取构建代码2
运维·ci/cd·jenkins·devops·spring boot部署
万山y1 小时前
使用一个公网服务器做内网穿透超详细
运维·服务器
暴富奥利奥1 小时前
Linux学习——了解和熟悉Linux系统的远程终端登录
linux·学习
꧁༺朝花夕逝༻꧂1 小时前
随机面试--<二>
linux·运维·数据库·nginx·面试