实测记录:测试开机启动脚本在CentOS上的表现
实测记录:测试开机启动脚本在CentOS上的表现
你有没有遇到过这样的问题:写好了一个监控脚本、日志清理工具,或者服务健康检查程序,每次重启服务器后都得手动运行一次?既麻烦又容易遗漏,还可能影响业务连续性。其实,Linux系统早就提供了成熟的机制来解决这个问题——通过系统级的开机自启动脚本,让关键任务在系统就绪后自动运行。
本文不是泛泛而谈的概念介绍,而是基于真实环境的一次完整实测记录。我们使用的是标准CentOS系统(具体为CentOS 7),全程不依赖systemd服务单元文件(避免混淆传统SysV init与现代systemd的区别),专注验证最经典、最兼容、也最容易被新手理解的/etc/init.d+rc*.d软链接方式。所有步骤均经过反复验证,每一步都有明确目的和可观察结果,确保你照着做就能成功。
整个过程不需要安装额外软件,不修改内核参数,不调整SELinux策略,只用系统自带命令完成。如果你正在维护一台老版本CentOS服务器,或者需要确保脚本在多种init风格下稳定运行,这篇实测记录就是为你准备的。
1. 明确目标与环境前提
在动手前,先理清我们要达成什么,以及系统当前处于什么状态。
1.1 本次实测的核心目标
- 验证一个自定义Shell脚本能否在CentOS系统启动完成后自动执行
- 确认脚本执行时机是否合理(即:网络已就绪、磁盘已挂载、基础服务已启动)
- 排查常见失败原因:权限问题、路径错误、依赖未就绪、启动顺序不当
- 提供可复用的最小可行模板,而非复杂配置
注意:本文聚焦SysV init风格的传统启动流程,适用于CentOS 6及CentOS 7(即使默认使用systemd,仍完全兼容
/etc/init.d脚本调用)。不涉及systemctl enable或.service文件写法,避免概念交叉干扰。
1.2 当前系统环境确认
我们先快速确认几个关键信息,避免后续操作踩坑:
# 查看系统版本(确认是CentOS) cat /etc/redhat-release # 输出示例:CentOS Linux release 7.9.2009 (Core) # 查看默认运行级别(CentOS 7中,systemd使用target替代runlevel,但兼容runlevel命令) runlevel # 输出示例:N 3 → 表示当前运行级别为3(多用户文本模式) # 查看默认启动target(补充验证) systemctl get-default # 输出示例:multi-user.target这里特别说明:虽然CentOS 7默认使用systemd,但它完全保留并兼容SysV init机制。/etc/rc.d/rc脚本会按需加载/etc/rc3.d/(对应multi-user.target)或/etc/rc5.d/(对应graphical.target)中的链接。因此,我们仍可沿用熟悉的rc*.d目录逻辑,无需切换思维模式。
2. 编写一个可验证的测试脚本
脚本不能只是“能跑”,更要“可追踪”——我们需要清楚知道它是否真的被执行、何时执行、执行结果如何。
2.1 创建脚本文件/etc/init.d/mytest.sh
直接在终端中执行以下命令创建脚本(注意:必须保存在/etc/init.d/目录下,且有执行权限):
sudo tee /etc/init.d/mytest.sh << 'EOF' #!/bin/bash # # mytest A simple test script for boot startup # chkconfig: 35 99 01 # description: Test script to verify boot execution timing and behavior # processname: mytest # Source function library . /etc/rc.d/init.d/functions start() { echo -n "Starting mytest: " # 记录启动时间、主机名、IP地址到日志 echo "[$(date '+%Y-%m-%d %H:%M:%S')] STARTED on $(hostname) at $(ip -4 addr show eth0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)" >> /var/log/mytest.log # 模拟一个轻量级操作:创建标记文件 touch /tmp/mytest_started success echo } stop() { echo -n "Stopping mytest: " echo "[$(date '+%Y-%m-%d %H:%M:%S')] STOPPED" >> /var/log/mytest.log rm -f /tmp/mytest_started success echo } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) if [ -f /tmp/mytest_started ]; then echo "mytest is running." else echo "mytest is stopped." fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 EOF # 设置执行权限 sudo chmod +x /etc/init.d/mytest.sh这个脚本做了几件关键的事:
- 使用标准SysV init函数库(
/etc/rc.d/init.d/functions),保证输出格式统一、支持success/failure提示 chkconfig行声明了它适用于运行级别3和5,启动序号99(最后启动),关闭序号01(最早停止)- 启动时记录精确时间、主机名和主网卡IP到
/var/log/mytest.log,并创建/tmp/mytest_started作为运行标记 - 支持
start/stop/restart/status四类操作,方便手动调试
2.2 手动运行一次,验证脚本本身无误
sudo /etc/init.d/mytest.sh start sudo /etc/init.d/mytest.sh status # 应输出:mytest is running. # 查看日志是否写入 sudo tail -n 1 /var/log/mytest.log # 应看到类似:[2024-06-15 14:22:33] STARTED on centos7-test at 192.168.1.100 # 清理测试痕迹 sudo /etc/init.d/mytest.sh stop只有这一步成功,才能进入下一步。否则所有开机启动都是空谈。
3. 将脚本注册为系统服务
CentOS不会自动扫描/etc/init.d/下的所有脚本。我们必须显式告诉系统:“这个脚本需要在启动时运行”。
3.1 使用chkconfig命令注册(推荐方式)
chkconfig是CentOS管理SysV服务的官方工具,比手动建软链接更安全、更可维护:
# 将脚本添加到服务列表 sudo chkconfig --add mytest.sh # 设置在运行级别3和5下开机自启 sudo chkconfig mytest.sh on # 验证是否注册成功 sudo chkconfig --list mytest.sh # 输出应包含:mytest.sh 0:off 1:off 2:off 3:on 4:off 5:on 6:off为什么推荐
chkconfig而不是手动ln -s?
- 它会自动在
/etc/rc3.d/和/etc/rc5.d/下创建正确的S99mytest.sh和K01mytest.sh链接- 自动处理符号链接命名规范(S开头+两位数字+脚本名)
- 支持
chkconfig --del一键卸载,避免残留链接- 兼容性更好,尤其在混合systemd/SysV环境中
3.2 (备选)手动创建软链接(仅作原理理解)
如果你希望彻底理解底层机制,可以跳过chkconfig,手动操作:
# 进入对应运行级别的rc目录(以3为例) cd /etc/rc3.d/ # 创建启动链接:S99mytest.sh(99表示最后启动) sudo ln -s /etc/init.d/mytest.sh S99mytest.sh # 创建停止链接:K01mytest.sh(01表示最早停止) sudo ln -s /etc/init.d/mytest.sh K01mytest.sh # 验证链接存在且指向正确 ls -l S99mytest.sh # 应输出:S99mytest.sh -> /etc/init.d/mytest.sh注意:手动创建时,务必确保链接名符合SxxName或KxxName格式,否则rc脚本不会识别。
4. 验证启动时机与执行效果
光注册还不够,我们必须确认它真的在正确的时间点执行了,并且执行结果符合预期。
4.1 检查启动链接是否生效
# 查看rc3.d目录下是否有我们的链接 ls -l /etc/rc3.d/S99* # 查看脚本是否被chkconfig识别 sudo chkconfig --list | grep mytest4.2 模拟一次“伪重启”进行快速验证(不真正重启)
频繁重启服务器既耗时又影响其他服务。我们可以用systemctl触发一次rc-local式的手动启动,模拟开机流程:
# 在CentOS 7中,/etc/rc.d/rc3.d/下的S*脚本由/etc/rc.d/rc脚本统一调用 # 我们可以直接运行rc脚本(指定运行级别3) sudo /etc/rc.d/rc 3此命令会按顺序执行
/etc/rc3.d/S*下所有脚本。请确保你了解其影响(它会启动所有S*服务,包括网络、sshd等)。如不确定,建议直接重启测试。
4.3 最终验证:重启系统并检查结果
# 执行重启(生产环境请谨慎!) sudo reboot等待系统完全启动后,登录并立即检查:
# 检查标记文件是否存在 ls -l /tmp/mytest_started # 应存在,且时间戳接近系统启动时间 # 查看日志内容 sudo cat /var/log/mytest.log # 应看到类似: # [2024-06-15 14:30:22] STARTED on centos7-test at 192.168.1.100 # 检查网络是否已就绪(验证执行时机) ip addr show eth0 | grep 'inet ' # 应能正常显示IP,证明脚本是在网络服务启动后执行的 # 检查脚本状态 sudo /etc/init.d/mytest.sh status # 应输出:mytest is running.如果以上全部满足,恭喜你——开机启动脚本已成功落地。
5. 常见问题与排查指南
实测过程中,90%的问题都出在几个固定环节。以下是高频故障点及对应解法:
5.1 脚本根本没执行?
检查点1:脚本权限
ls -l /etc/init.d/mytest.sh→ 必须有x执行权限(-rwxr-xr-x)检查点2:脚本首行shebang
必须是#!/bin/bash或#!/bin/sh,不能是Windows换行符(^M),可用dos2unix /etc/init.d/mytest.sh修复检查点3:chkconfig元数据缺失
脚本头部必须包含# chkconfig:行,否则chkconfig --add会失败
5.2 脚本执行了,但功能异常(如无法访问网络、找不到命令)?
原因:执行环境过于精简
开机脚本运行时,PATH变量极短(通常只有/sbin:/usr/sbin:/bin:/usr/bin),很多常用命令(如jq、curl、python3)不在其中。解法:在脚本中显式声明PATH
# 在脚本开头添加 export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"解法:使用绝对路径调用命令
# 不要写 curl -s http://api.example.com/health # 要写 /usr/bin/curl -s http://api.example.com/health
5.3 日志为空,或时间戳异常?
原因:脚本在系统日志服务(rsyslog)启动前就运行了
导致>> /var/log/mytest.log重定向失败(目录不存在或无权限)解法:添加延迟或依赖检查
# 在start()函数中加入等待 while [ ! -f /var/log/messages ]; do sleep 1 done更优解:使用
logger命令写入系统日志logger "mytest: service started successfully" # 日志将出现在 /var/log/messages 中,且时机更可靠
6. 总结:一条可复用的开机启动实践路径
回顾整个实测过程,我们走通了一条从零开始、稳扎稳打的开机脚本落地路径。它不依赖任何第三方工具,不修改系统核心配置,完全基于CentOS原生机制,具备强兼容性和可维护性。
6.1 关键结论
- SysV init机制在CentOS 7中依然健壮有效,
chkconfig是注册服务的首选工具 - 脚本执行时机取决于运行级别:
rc3.d对应文本模式,rc5.d对应图形界面;选择哪个取决于你的服务器用途 - 启动序号(如99)决定执行顺序:数值越大越晚执行,适合依赖数据库、网络等后置服务的脚本
- 日志是排错的第一依据:务必在脚本中记录时间、环境、关键状态,避免“黑盒”执行
6.2 下一步建议
- 将此模板扩展为实际业务脚本:例如定时清理
/tmp、监控磁盘使用率、上报服务器心跳 - 结合
cron实现“启动后延时执行”(如@reboot sleep 60 && /path/to/script.sh),应对需要更晚时机的场景 - 对于新项目,可逐步迁移到
systemd服务单元,但本方案仍是维护旧系统的黄金标准
你不需要记住所有命令,只需要记住这个最小闭环:
写脚本 → 加权限 → 写chkconfig头 → chkconfig --add → chkconfig on → reboot验证。
剩下的,就是把它用在真正需要的地方。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
