如何设置 /etc/init.d 类型的服务开机自启
一、概述
/etc/init.d/ 是 SysV init 系统的服务脚本目录。设置这类服务开机自启主要使用 chkconfig 命令(RHEL/CentOS)或 update-rc.d 命令(Debian/Ubuntu)。
二、不同发行版的设置方法
1. RHEL/CentOS 6 及更早版本(使用 chkconfig)
基本用法
# 添加服务到管理列表
chkconfig –add myservice
# 设置服务在指定运行级别开机自启
chkconfig myservice on
# 设置服务在指定运行级别开机自启(更精确的控制)
chkconfig –level 2345 myservice on
# 关闭开机自启
chkconfig myservice off
# 从管理列表中移除服务
chkconfig –del myservice
# 查看所有服务的开机自启状态
chkconfig –list
# 查看特定服务的状态
chkconfig –list myservice
实际示例
# 添加自定义服务
chkconfig –add myapp
# 设置为开机自启(默认级别 2345)
chkconfig myapp on
# 查看设置结果
chkconfig –list myapp
# 输出示例:
# myapp 0:off 1:off 2:on 3:on 4:on 5:on 6:off
2. Debian/Ubuntu(使用 update-rc.d)
基本用法
# 设置服务开机自启(默认启动级别 2-5)
update-rc.d myservice defaults
# 设置服务开机自启并指定启动顺序
update-rc.d myservice defaults 90 10
# 90: 启动优先级(数字越小越早启动)
# 10: 停止优先级(数字越小越早停止)
# 设置服务开机自启(指定级别)
update-rc.d myservice start 90 2 3 4 5 . stop 10 0 1 6 .
# 禁用开机自启
update-rc.d myservice remove
# 移除所有符号链接
update-rc.d -f myservice remove
实际示例
# 添加服务并设置默认启动
update-rc.d myapp defaults
# 添加服务并指定优先级(在网络之后启动)
update-rc.d myapp start 90 2 3 4 5 . stop 10 0 1 6 .
# 查看生成的符号链接
ls -l /etc/rc?.d/*myapp*
# 输出示例:
# /etc/rc0.d/K10myapp -> ../init.d/myapp
# /etc/rc1.d/K10myapp -> ../init.d/myapp
# /etc/rc2.d/S90myapp -> ../init.d/myapp
# /etc/rc3.d/S90myapp -> ../init.d/myapp
# /etc/rc4.d/S90myapp -> ../init.d/myapp
# /etc/rc5.d/S90myapp -> ../init.d/myapp
# /etc/rc6.d/K10myapp -> ../init.d/myapp
3. SUSE Linux(使用 insserv)
# 设置开机自启
insserv myservice
# 禁用开机自启
insserv -r myservice
# 查看依赖关系
insserv –showall | grep myservice
三、手动创建符号链接(通用方法)
如果系统中没有上述命令,可以手动创建符号链接:
1. 理解运行级别目录
# 运行级别对应的目录
/etc/rc0.d/ # 关机级别
/etc/rc1.d/ # 单用户模式
/etc/rc2.d/ # 多用户模式(无网络)
/etc/rc3.d/ # 完整多用户模式(文本界面)
/etc/rc4.d/ # 未使用
/etc/rc5.d/ # 图形界面模式
/etc/rc6.d/ # 重启级别
2. 符号链接命名规则
- 启动脚本:S<数字><服务名> (例如 S90myapp)
- 停止脚本:K<数字><服务名> (例如 K10myapp)
数字范围通常 00-99,数字越小执行越早。
3. 手动创建示例
# 1. 确保脚本有执行权限
chmod +x /etc/init.d/myapp
# 2. 在运行级别 2,3,4,5 创建启动链接
cd /etc/rc2.d
ln -s ../init.d/myapp S90myapp
cd /etc/rc3.d
ln -s ../init.d/myapp S90myapp
cd /etc/rc4.d
ln -s ../init.d/myapp S90myapp
cd /etc/rc5.d
ln -s ../init.d/myapp S90myapp
# 3. 在运行级别 0,1,6 创建停止链接
cd /etc/rc0.d
ln -s ../init.d/myapp K10myapp
cd /etc/rc1.d
ln -s ../init.d/myapp K10myapp
cd /etc/rc6.d
ln -s ../init.d/myapp K10myapp
四、init.d 脚本的格式要求
为了让 chkconfig 或 update-rc.d 正确识别,init.d 脚本必须包含特定的头部信息:
1. RHEL/CentOS 格式
#!/bin/bash
# chkconfig: 2345 90 10
# description: My custom service description
# processname: myapp
# config: /etc/myapp/config
# chkconfig 行的含义:
# 2345: 在哪些运行级别启动
# 90: 启动优先级
# 10: 停止优先级
# 脚本内容…
2. Debian/Ubuntu 格式
#!/bin/bash
### BEGIN INIT INFO
# Provides: myapp
# Required-Start: $network $remote_fs
# Required-Stop: $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My custom service
# Description: My custom service long description
### END INIT INFO
# 脚本内容…
五、完整实战示例
示例:创建并设置一个自定义服务
1. 创建脚本 /etc/init.d/myapp
#!/bin/bash
#
# myapp – My custom application
#
# chkconfig: 2345 90 10
# description: My custom application service
# processname: myapp
# config: /etc/myapp.conf
# Source function library
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
fi
# 配置
APP_NAME="myapp"
APP_PATH="/usr/local/bin/$APP_NAME"
PID_FILE="/var/run/$APP_NAME.pid"
LOG_FILE="/var/log/$APP_NAME.log"
start() {
echo -n "Starting $APP_NAME: "
if [ -f $PID_FILE ]; then
echo "Already running (PID: $(cat $PID_FILE))"
return 1
fi
# 启动进程
$APP_PATH > $LOG_FILE 2>&1 &
echo $! > $PID_FILE
if [ $? -eq 0 ]; then
echo_success
else
echo_failure
fi
echo
}
stop() {
echo -n "Stopping $APP_NAME: "
if [ ! -f $PID_FILE ]; then
echo "Not running"
return 1
fi
kill –TERM $(cat $PID_FILE)
rm -f $PID_FILE
if [ $? -eq 0 ]; then
echo_success
else
echo_failure
fi
echo
}
status() {
if [ -f $PID_FILE ]; then
echo "$APP_NAME is running (PID: $(cat $PID_FILE))"
else
echo "$APP_NAME is stopped"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
2. 设置权限
chmod +x /etc/init.d/myapp
3. 在 RHEL/CentOS 上设置开机自启
# 添加到 chkconfig 管理
chkconfig –add myapp
# 设置开机自启
chkconfig myapp on
# 验证
chkconfig –list myapp
4. 在 Debian/Ubuntu 上设置开机自启
# 更新 init 脚本头部信息(添加 INIT INFO 块后)
update-rc.d myapp defaults
# 或指定优先级
update-rc.d myapp start 90 2 3 4 5 . stop 10 0 1 6 .
# 验证
ls -l /etc/rc?.d/*myapp*
六、验证开机自启设置
1. 检查符号链接
# 查看所有运行级别的链接
ls -la /etc/rc[0-6].d/* | grep myapp
# 特定级别
ls -la /etc/rc3.d/*myapp*
2. 使用 chkconfig 查看
# RHEL/CentOS
chkconfig –list | grep myapp
# 或直接查看
chkconfig –list myapp
3. 使用 systemctl 查看(如果系统同时支持 systemd)
# systemd 会读取 SysV init 脚本
systemctl status myapp
systemctl is-enabled myapp
七、常见问题解决
1. “service xxx does not support chkconfig”
原因:init 脚本缺少 chkconfig 头部信息
解决:在脚本开头添加
# chkconfig: 2345 90 10
# description: Service description
2. “insserv: warning: script ‘myapp’ missing LSB tags”
原因:缺少 LSB 头部信息
解决:添加 LSB 头部
### BEGIN INIT INFO
# Provides: myapp
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My app
### END INIT INFO
3. 服务无法启动
# 手动测试脚本
/etc/init.d/myapp start
# 检查脚本语法
bash -n /etc/init.d/myapp
# 查看错误日志
tail -f /var/log/messages
tail -f /var/log/syslog
八、现代 systemd 系统的兼容性
即使在 systemd 系统上,仍然可以使用 SysV init 脚本:
1. systemd 对 SysV 脚本的支持
# systemd 会自动为 /etc/init.d/ 下的脚本生成 .service 单元
ls /etc/init.d/myapp
# systemd 会自动创建 myapp.service 包装器
# 可以使用 systemctl 管理
systemctl status myapp
systemctl enable myapp
systemctl disable myapp
2. 转换 SysV 脚本到 systemd
# 创建 systemd 单元文件
cat > /etc/systemd/system/myapp.service << EOF
[Unit]
Description=My custom application
After=network.target
[Service]
Type=forking
PIDFile=/var/run/myapp.pid
ExecStart=/etc/init.d/myapp start
ExecStop=/etc/init.d/myapp stop
ExecReload=/etc/init.d/myapp restart
[Install]
WantedBy=multi-user.target
EOF
# 启用新服务
systemctl daemon-reload
systemctl enable myapp
systemctl start myapp
九、最佳实践建议
通过以上方法,您可以轻松地在任何 Linux 系统上设置 /etc/init.d/ 类型的服务开机自启。





