「LINUX」- LSB Init Scripts

LSB Init Scripts,LSB 初始化脚本,用于控制系统服务的启动、停止、重启、状态查看等等;

我也不知道我为什么不喜欢 Systemd :(。因为要用到 VirtualBox 虚拟机,我也不想每次开机以后都去手动启动虚拟机,所以学习一下 LSB Init Scripts,开机的时候可以自己启动;

以内容,如果没有特殊说明,“LIS”一词默认指的都是LSB 初始化脚本

有关详细内容查看 LBS3.1 的第 20 章 | http://refspecs.linuxfoundation.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/tocsysinit.html

脚本的结构

LSB 注释头
引入函数库
动作(Actions)

LSB 注释头

在 /etc/init.d 下,有一个skeleton文件,该文件的内容是 LIS 的基本框架。下面是 /etc/init.d/skeleton 文件的内容:

#!/bin/sh
# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
	set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
### BEGIN INIT INFO
# Provides:          skeleton
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.  This example start a
#                    single forking daemon capable of writing a pid
#                    file.  To get other behavoirs, implemend
#                    do_start(), do_stop() or other functions to
#                    override the defaults in /lib/init/init-d-script.
### END INIT INFO

# Author: Foo Bar <foobar@baz.org>
#
# Please remove the "Author" lines above and replace them
# with your own name if you copy and modify this script.

DESC="Description of the service"
DAEMON=/usr/sbin/daemonexecutablename

所以,以后要写 init 脚本,先把skeleton文件复制一份,然后继续开发;

### BEGIN INIT INFO
# Provides:          boot_facility_1 [ boot_facility_2 ...]
# Required-Start:    boot_facility_1 [ boot_facility_2 ...]
# Required-Stop:     boot_facility_1 [ boot_facility_2 ...]
# Should-Start:      boot_facility_1 [ boot_facility_2 ...]
# Should-Stop:       boot_facility_1 [ boot_facility_2 ...]
# X-Start-Before:    boot_facility_1 [ boot_facility_2 ...]
# X-Stop-After:      boot_facility_1 [ boot_facility_2 ...]
# Default-Start:     run_level_1 [ run_level_2 ...]
# Default-Stop:      run_level_1 [ run_level_2 ...]
# X-Interactive:     true
# Short-Description: single_line_description
# Description:       multiline_description
### END INIT INFO

insserv 会计算所有脚本之间的依赖关系。不建议直接执行 insserv,除非您确切知道您在做什么,否则可能会导致启动系统无法运行。update-rc.d 是用于管理 init 脚本的推荐接口;

# Required-Stop: boot_facility_1 [ boot_facility_2 …]
声明在 Provides 标签中声明的服务关闭期间必须可用的工具(facilities);

# Should-Stop: boot_facility_1 [ boot_facility_2 …]
同样的,指出在关闭 Provides 标签中声明的服务关闭时应该可用的工具;

在声明 Required-Stop 和 Should-Stop 情况下,脚本系统应避免停止这两个 Stop 标签​​声明的服务,直到包含这些标签的脚本都停止为止;

# X-Interactive true
该选项是可选的,表示使用此关键字的脚本应该在并发启动配置中单独启动,因为它与控制台上的用户交互。只有值“true”被识别,其他的都被忽略;

# X-Start-Before: boot_facility_1 [ boot_facility_2 …]
该选项是可选的,表示使用此关键字的脚本应在指定的服务名称之前启动。意味着这些服务现在依赖于指定脚本;

# X-Stop-After: boot_facility_1 [ boot_facility_2 …]
而可选的 X-Stop-After 关键字表示使用此关键字的脚本应在指定的服务名称后停止。意味着这些服务现在依赖于指定脚本。使用已知的依赖关系和运行级别 insserv 集并重新排列相关运行级别目录的相应符号链接

insserv 扫描配置文件 /etc/insserv.conf 中的系统工具和 /etc/insserv.conf.d/ 中的每个文件。以$开头的每一行和跟在后面的名称都会相应地定义一个”系统工具“到”Linux 标准基本规范“(LSB),所有这些”系统工具“后面的所有名称都将声明设备的所需依赖性。下面演示 /etc/insserv.conf 的内容:

# All local filesystems are mounted

# (done during boot phase)

$local_fs boot

# Low level networking

$network network route

# Named is operational

$named named

# All remote filesystems are mounted

# (in some cases /usr may be remote).

$remote_fs $local_fs nfs

# System logger is operational

$syslog syslog

# All network daemons are running (This was removed in LSB 1.2)

$netdaemons portmap inetd

# Services which need to be interactive

<interactive> boot.crypto

以“+”符号开头的名称标记为可选。如果具有加号后面的名称的服务可用,则将被使用,如果不可用,则将被默认忽略。以 <和结尾为> 开头的单词是关键字。目前,<interactive> 是将服务标记为交互服务的唯一已知关键字,例如。一种服务,在启动或运行级别更改期间需要输入密码或密码。特殊工具$null 用于在 Should-Stop 和 Required-Stop 的情况下强制执行空依赖;

除了配置文件 /etc/insserv.conf 中定义的系统工具外,insserv 还知道特殊工具$all。$all 表明,启动时位于所有的服务最后,停止时位于所有的服务之前。显然,使用$all 的所有服务将被分组成一个起始或停止的顺序;

引入函数库

每个符合条件的 init 脚本都将执行当前环境文件 /lib/lsb/init-functions 中的命令(请参阅 shell 特殊内置命令点)。该文件将定义一些 shell 脚本命令;

动作(Actions)

一个脚本需要提供 start, stop, restart, force-reload, status 这几个动作。可以使用 case 语句来定义,结构如下:

case "$1" in
	start)
		do_something0
		;;
	stop)
		do_something1
		;;
	start)
		do_something2
		;;
	*)
		;;
esac

注意事项

脚本需要有执行权限,owner、group、anyone 都要有自行权限,否则执行 update-rc.d 时,会产生错误:insserv: script virtauto is not an executable regular file, skipped!

参考

man 8 insserv
runlevel,需要明白;
Debian LBSInitScripts: https://wiki.debian.org/LSBInitScripts
LSB: http://refspecs.linuxfoundation.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/tocsysinit.html