如何编写基于 LSB 初始化标准的 Linux 初始化脚本

举报
Tiamo_T 发表于 2022/06/09 14:27:09 2022/06/09
【摘要】 LSB 是由 Linux Foundation 启动的,目的是减少几个 Linux 发行版之间的差异,从而降低不同发行版之间移植所涉及的成本。初始化脚本是其中需要标准化的脚本之一。

LSB 代表 Linux 标准基础。

LSB 是由 Linux Foundation 启动的,目的是减少几个 Linux 发行版之间的差异,从而降低不同发行版之间移植所涉及的成本。初始化脚本是其中需要标准化的脚本之一。

在本文中,我们将了解如何编写符合 LSBInit 标准的 Init 脚本。

初始化脚本用于启动|停止软件|服务。例如,如果您使用的是 postgresql 软件,我们将有一个名为 '/etc/init.d/postgresql' 的初始化脚本,可用于 'start|stop|restart|reload|force-reload|status'。

符合 LSB 的初始化脚本需要:

  • 至少提供“启动、停止、重启、强制重新加载和状态”
  • 返回正确的退出代码
  • 记录运行时依赖项

或者,他们可以使用“log_success_msg”、“log_failure_msg”等 init.d 函数来记录消息。

LSB 提供了默认的函数集,位于 /lib/lsb/init-functions。我们可以在我们的初始化脚本中使用这些函数。默认情况下,所有 Init 进程都会将进程的 pid 记录在 /var/run/ 目录下的文件中。这对于 Init 脚本查找进程状态很有用。

现在让我们开始编写一个初始化脚本。首先,我们需要向 Init 脚本添加一个标头,如下所示,


### BEGIN INIT INFO
# Provides:          my_daemon
# Required-Start:    postgresql networking
# Required-Stop:     postgresql networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is a test daemon
# Description:       This is a test daemon
#                    This provides example about how to
#                    write a Init script.
### END INIT INFO

提供指定此 Init 脚本提供的功能。名称应该是唯一的。

required-start指定在启动此服务之前应启动的设施集。在我们的例子中,postgresql 和网络必须在启动 my_daemon 之前启动。请记住,这里的“postgresql”将有一个单独的初始化脚本,上面写着“提供:postgresql”。这确保了基于依赖的引导。基于此依赖关系,“inserv”命令或“update-rc.d”会将条目放在具有适当序列号的运行级目录中。例如,条目可以如下所示

/etc/rc2.d/S12postgresql
/etc/rc2.d/S03networking
/etc/rc2.d/S13my_daemon

这表明,网络将首先启动,然后是 postgresql,然后是 my_daemon。

Required-Stop指定仅在停止该设施后必须停止的设施列表。这里只有在 my_daemon 停止后,postgresql 和网络设施才会停止。

Default-Start Default-Stop定义了必须启动或停止服务的运行级别。

Short-DescriptionDescription用于对所提供的设施进行一些描述。描述可以跨越多行,简短描述仅限于单行。

让我们看一个实际的初始化脚本。

### BEGIN INIT INFO
# Provides:          my_daemon
# Required-Start:    postgresql networking
# Required-Stop:     postgresql networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is a test daemon
# Description:       This is a test daemon
#                    This provides example about how to
#                    write a Init script.
### END INIT INFO

# Using the lsb functions to perform the operations.
. /lib/lsb/init-functions
# Process name ( For display )
NAME=my-daemon
# Daemon name, where is the actual executable
DAEMON=/home/user1/my_daemon
# pid file for the daemon
PIDFILE=/var/run/my_daemon.pid

# If the daemon is not there, then exit.
test -x $DAEMON || exit 5

case $1 in
 start)
  # Checked the PID file exists and check the actual status of process
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON "$NAME process" && status="0" || status="$?"
   # If the status is SUCCESS then don't need to start again.
   if [ $status = "0" ]; then
    exit # Exit
   fi
  fi
  # Start the daemon.
  log_daemon_msg "Starting the process" "$NAME"
  # Start the daemon with the help of start-stop-daemon
  # Log the message appropriately
  if start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON ; then
   log_end_msg 0
  else
   log_end_msg 1
  fi
  ;;
 stop)
  # Stop the daemon.
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON "Stoppping the $NAME process" && status="0" || status="$?"
   if [ "$status" = 0 ]; then
    start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
    /bin/rm -rf $PIDFILE
   fi
  else
   log_daemon_msg "$NAME process is not running"
   log_end_msg 0
  fi
  ;;
 restart)
  # Restart the daemon.
  $0 stop && sleep 2 && $0 start
  ;;
 status)
  # Check the status of the process.
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON "$NAME process" && exit 0 || exit $?
  else
   log_daemon_msg "$NAME Process is not running"
   log_end_msg 0
  fi
  ;;
 reload)
  # Reload the process. Basically sending some signal to a daemon to reload
  # it configurations.
  if [ -e $PIDFILE ]; then
   start-stop-daemon --stop --signal USR1 --quiet --pidfile $PIDFILE --name $NAME
   log_success_msg "$NAME process reloaded successfully"
  else
   log_failure_msg "$PIDFILE does not exists"
  fi
  ;;
 *)
  # For invalid arguments, print the usage message.
  echo "Usage: $0 {start|stop|restart|reload|status}"
  exit 2
  ;;
esac

上面的脚本基本上提供了编写 LSBInit 脚本的模板。您可以更改 DAEMON、PIDFILE、NAME 变量和标题以使此脚本适合您自己的程序。

初始化脚本完成后,为了使脚本自动启动或停止,请执行以下命令。这将在给定的运行级别中添加适当的“S”和“K”条目。这还将通过考虑依赖关系添加适当的序列号。

update-rc.d filename defaults
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。