原来这么简单!测试开机启动脚本五分钟上手
你是不是也遇到过这样的问题:写好了一个监控脚本、日志清理工具,或者服务健康检查程序,每次重启服务器后都要手动运行一次?反复操作不仅费时,还容易遗漏。其实,让脚本在系统启动时自动运行,根本不需要复杂配置,也不用改内核、编译源码——只要五分钟左右,就能搞定。
这篇文章不讲抽象概念,不堆术语,全程用最直白的操作步骤带你完成一个真实可用的开机启动脚本测试。无论你是刚接触Linux的新手,还是想快速验证某个自动化任务的老手,都能照着做、立刻见效。我们用的是最通用的SysV init方式(CentOS 6/7兼容模式、Ubuntu 16.04+仍默认支持),不依赖systemd高级语法,确保你在绝大多数主流发行版上都能一步到位。
1. 先准备好你的脚本
别急着改系统配置,第一步永远是:先有脚本。
我们以一个极简但实用的示例开始——一个会在开机时自动创建时间戳文件的脚本。它不干别的,就证明“脚本能跑起来”,后续你可以轻松替换成自己的业务逻辑。
1.1 创建脚本文件
打开终端,执行以下命令:
sudo nano /etc/init.d/mytest.sh把下面这段内容完整粘贴进去(注意保留每行缩进和空格):
#!/bin/bash ### BEGIN INIT INFO # Provides: mytest # Required-Start: $local_fs $network # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Test startup script # Description: A simple script to create a timestamp file on boot ### END INIT INFO case "$1" in start) echo "Starting mytest script..." mkdir -p /var/log/mytest date >> /var/log/mytest/boot.log echo "Boot time recorded at $(date)" > /var/log/mytest/last_boot.txt ;; stop) echo "Stopping mytest script..." ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 01.2 设置可执行权限
保存退出后(Ctrl+O → Enter → Ctrl+X),给脚本加上执行权限:
sudo chmod +x /etc/init.d/mytest.sh小提示:这个脚本里已经包含了标准的LSB头(
### BEGIN INIT INFO那段),它告诉系统这个脚本该在哪些运行级别启动、依赖什么服务。虽然现代系统不一定严格校验它,但加上能避免警告,也方便未来迁移到其他环境。
2. 确认你的系统运行级别
Linux启动时会进入一个“运行级别”(runlevel),不同级别对应不同的服务集合。我们要让脚本在图形界面或标准多用户模式下自动运行,通常就是级别2、3、4、5中的某一个。
2.1 查看当前运行级别
输入命令:
runlevel你会看到类似这样的输出:
N 5其中第二个数字5就是当前系统的默认运行级别(N 表示“从无状态启动”,可忽略)。如果你看到的是N 3,说明系统默认以文本模式启动;如果是N 5,则是带图形界面的模式。两者都支持我们的脚本启动,只是对应的启动目录略有不同。
补充说明:
/etc/init.d/是所有服务脚本的“源代码仓库”,放在这里的脚本本身不会自动执行;/etc/rcX.d/(X 是数字)才是“启动清单目录”,里面全是软链接,指向/etc/init.d/中的真实脚本;- 名字以
S开头的链接表示“Start”,以K开头的表示“Kill”(停止);后面的两位数字决定执行顺序,比如S20nginx比S99mytest更早运行。
3. 进入对应的 rcX.d 目录
既然刚才runlevel显示结果是5,我们就去/etc/rc5.d/目录操作:
cd /etc/rc5.d/如果显示的是3,那就换成:
cd /etc/rc3.d/进入后,用ls看一眼现有链接:
ls -l你会看到一堆类似S20rsyslog、S50apache2的文件。它们都是软链接,指向/etc/init.d/下的真实脚本。
关键点记住:
- 我们要加的是
Sxx开头的链接,不是Kxx;- 数字建议选
99,代表“最后启动”,这样能确保数据库、网络等基础服务已就绪,避免因依赖未加载而失败。
4. 创建软链接,真正启用启动项
现在,我们为刚才写的/etc/init.d/mytest.sh创建一个启动链接:
sudo ln -s /etc/init.d/mytest.sh S99mytest再执行一次ls -l,你应该能看到新增的一行:
S99mytest -> /etc/init.d/mytest.sh这就完成了最关键的一步:系统在进入运行级别5时,会按顺序执行这个链接指向的脚本。
注意事项:
- 链接名必须以
S或K开头,后面紧跟两位数字(01–99),再跟任意名称;- 不要漏掉
sudo,否则没有权限写入/etc/rc5.d/;- 如果你之前用过
update-rc.d(Ubuntu)或chkconfig(CentOS),它们底层也是在做这件事——只是帮你自动选目录、加链接、加LSB头而已。
5. 手动测试,不用重启也能验证
很多人以为必须重启才能测,其实完全没必要。我们可以直接模拟启动流程,快速验证脚本是否写对、权限是否正确、路径是否存在。
5.1 手动触发启动
回到终端,执行:
sudo /etc/init.d/mytest.sh start如果看到输出:
Starting mytest script...并且/var/log/mytest/目录下生成了boot.log和last_boot.txt,说明脚本本身完全正常。
5.2 检查日志内容
查看生成的记录:
cat /var/log/mytest/last_boot.txt应该显示类似:
Boot time recorded at Mon Jun 10 14:22:35 CST 2024这说明:脚本能执行、路径可写、时间能获取——三要素全部满足。
小技巧:如果某次测试失败,先检查
/var/log/syslog或/var/log/messages,搜索mytest,往往能直接看到报错原因,比如权限不足、路径不存在、命令未找到等。
6. 最后一步:重启验证(可选)
当你确认手动启动没问题后,就可以放心重启了。这是最终检验“开机即生效”的唯一方式。
sudo reboot等待系统重新启动并登录后,立即检查:
cat /var/log/mytest/last_boot.txt如果时间戳是本次重启后的新时间,恭喜你——你的开机启动脚本已经成功落地。
🧩 进阶小贴士(非必需,但很实用):
- 想让脚本在多个运行级别都生效?除了
/etc/rc5.d/,还可以同时在/etc/rc3.d/和/etc/rc2.d/下创建相同链接;- 想取消开机启动?直接删掉对应
S99mytest链接即可,不影响原始脚本;- 想改成 systemd 方式(如 CentOS 8+/Ubuntu 20.04+)?只需把脚本包装成
.service文件,我们后续可以单独写一篇对比教程。
7. 常见问题与速查指南
实际操作中,新手最容易卡在这几个地方。我们把高频问题整理成一张表,方便你快速定位:
| 问题现象 | 可能原因 | 快速解决方法 |
|---|---|---|
sudo: /etc/init.d/mytest.sh: command not found | 脚本没加执行权限 | sudo chmod +x /etc/init.d/mytest.sh |
S99mytest: No such file or directory | 软链接路径写错或目标脚本被移动 | ls -l S99mytest查看链接是否有效,重新创建链接 |
手动执行start成功,但重启后没记录 | 运行级别不匹配(比如脚本放在rc5.d,但系统默认是runlevel 3) | 用runlevel确认,然后在对应rcX.d目录下创建链接 |
/var/log/mytest/目录不存在导致写入失败 | 脚本中mkdir -p没生效,或权限受限 | 在脚本start分支开头加mkdir -p /var/log/mytest并确保有写权限 |
启动时报错Permission denied | 脚本第一行#!/bin/bash缺失或换行符异常(Windows编辑器保存) | 用file /etc/init.d/mytest.sh检查格式,推荐用nano或vim编辑 |
再强调一遍:所有操作都不需要修改系统核心配置,不涉及
/etc/fstab、/etc/default或内核参数。你只是在标准框架内,做了三件事——写脚本、设权限、加链接。这就是 Linux 启动机制设计得足够清晰的地方。
8. 总结:你刚刚完成了什么
回顾这五分钟,你其实已经掌握了 Linux 系统级自动化中最基础也最可靠的一环:
- 学会了如何编写一个符合 LSB 规范的 init 脚本;
- 理解了
runlevel、rcX.d、init.d三者之间的关系; - 掌握了通过软链接控制服务启动顺序的方法;
- 实现了无需重启即可验证的本地测试流程;
- 积累了一套排查启动失败的实用 checklist。
这不是一个“玩具实验”,而是你今后部署任何后台服务、定时巡检、日志归档、API健康守护的通用起点。接下来,你可以把mytest.sh里的date >> ...替换成python3 /opt/myapp/health_check.py,或者curl -s http://localhost:8080/readyz,整个流程完全复用。
真正的运维能力,从来不是记住多少命令,而是清楚每一步为什么这么做、出了问题往哪查。你现在,已经站在了这个起点上。
--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。