Linux/init.d script

Linux/init.d script

Runlevel

0    Off Turns off the device.
1    Single-user mode    Mode for administrative tasks.[2][b]
2    Multi-user mode Does not configure network interfaces and does not export networks services.[c]
3    Multi-user mode with networking Starts the system normally.[1]
4    Not used/user-definable For special purposes.
5    Full mode   Same as runlevel 3 + display manager.
6    Reboot  Reboots the device.

默认(default)的启动级别是 2。

Manage init.d services

CLI

# status | start | stop | restart | reload
/etc/init.d/apache2 status
service apache2 status

rc-update

# 列出所有已安装的服务 (/etc/init.d/*)
rc-service --list

# 列出当前系统的自启动服务
rc-update

# 将 apache2 服务设为自启动
rc-update add apache2
rc-update add apache2 default

# 禁用服务自启动
rc-update del apache2

chkconfig

chkconfig on apache2
chkconfig off apache2

Template

Use start-stop-daemon

大部分现代 Linux 都有 start-stop-daemon,这是启动服务进程的标准方式

以一个 rclone webdav 开机自动启动脚本为例。保存为 /etc/init.d/rclone 文件即可。在 Alpine Linux 里测试通过。

#!/sbin/openrc-run

export PATH=$PATH:/root/files/scripts:/root/files/bin

command="rclone"
command_user="root"
command_args="serve webdav --addr 0.0.0.0:5005 --read-only onedrive:/"

pidfile="/run/$RC_SVCNAME.pid"

depend() {
   need net
}

start() {
   ebegin "Starting $RC_SVCNAME"
   start-stop-daemon --background \
        --exec "$command" \
        --make-pidfile --pidfile $pidfile --user $command_user -1 /var/log/$RC_SVCNAME.log -2 /var/log/$RC_SVCNAME.log \
        --start -- $command_args
   eend $?
}

stop() {
   ebegin "Stopping $RC_SVCNAME"
   start-stop-daemon --stop \
        --exec "$command" \
        --pidfile $pidfile --user $command_user
   eend $?
}

reload() {
    ebegin "Reloading $RC_SVCNAME"
    start-stop-daemon --exec "$command" \
        --pidfile $pidfile --user $command_user \
        -s 1
    eend $?
}

说明

  • start-stop-daemon 的 -1 和 -2 分别指定程序 stdout /stderr 输出文件。
  • init.d 无法跟踪自行退出的进程。

Raw (bash)

#!/bin/bash

DAEMON_PATH="/home/wes/Development/projects/myapp"

DAEMON=myapp
DAEMONOPTS="-my opts"

NAME=myapp
DESC="My daemon description"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
start)
    printf "%-50s" "Starting $NAME..."
    cd $DAEMON_PATH
    PID=`$DAEMON $DAEMONOPTS > /dev/null 2>&1 & echo $!`
    #echo "Saving PID" $PID " to " $PIDFILE
        if [ -z $PID ]; then
            printf "%s\n" "Fail"
        else
            echo $PID > $PIDFILE
            printf "%s\n" "Ok"
        fi
;;
status)
        printf "%-50s" "Checking $NAME..."
        if [ -f $PIDFILE ]; then
            PID=`cat $PIDFILE`
            if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
                printf "%s\n" "Process dead but pidfile exists"
                exit 1
            else
                echo "Running"
            fi
        else
            printf "%s\n" "Service not running"
            exit 1
        fi
;;
stop)
        printf "%-50s" "Stopping $NAME"
            PID=`cat $PIDFILE`
            cd $DAEMON_PATH
        if [ -f $PIDFILE ]; then
            kill -HUP $PID
            printf "%s\n" "Ok"
            rm -f $PIDFILE
        else
            printf "%s\n" "pidfile not found"
        fi
;;

restart)
      $0 stop
      $0 start
;;

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

Last update: 2023-02-18 11:44:23 UTC