news 2026/2/10 4:42:55

刚试完就成功了!测试开机启动脚本真实反馈

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
刚试完就成功了!测试开机启动脚本真实反馈

刚试完就成功了!测试开机启动脚本真实反馈

你是不是也经历过这样的时刻:写好一个自动化脚本,满心期待它能在系统重启后自动运行,结果一 reboot,发现什么都没发生?别急,这不是你代码的问题,大概率是启动流程没走对。今天这篇内容,不讲抽象理论,不堆参数配置,就用最直白的语言,复盘我刚做完的一次真实测试——从写脚本、放位置、加链接,到重启验证,全程无坑、一步到位。整个过程不到5分钟,连中间查文档的时间都算上,也才12分钟。

这篇文章不是教科书式的“标准答案”,而是我把操作台前的真实动作、终端里敲出的每条命令、看到的每一行输出,原原本本地记录下来。你会看到:哪里容易手误、哪个提示容易被忽略、为什么选rc5.d而不是rc3.d、软链接名字里的S99到底意味着什么……所有这些,都不靠猜,全靠实测。

如果你用的是 CentOS 或 Ubuntu(包括 Debian 系发行版),那下面的内容,你照着做,大概率也能“刚试完就成功”。

1. 先写一个能被系统认出来的脚本

很多人卡在第一步:脚本写好了,但系统压根不把它当“服务”看。关键不在功能多炫酷,而在格式是否规范。

我写的测试脚本叫mytest.sh,放在/etc/init.d/目录下——这是传统 SysV init 系统认服务的“法定地址”。注意,不是随便哪个目录都行,也不是.sh后缀就能自动生效。

这个脚本内容极简,只做一件事:每次开机时,在/var/log/下生成一个带时间戳的标记文件。这样重启后,只要去翻日志目录,一眼就能确认它有没有跑过。

#!/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 verify boot execution ### END INIT INFO case "$1" in start) echo "Starting mytest at $(date)" >> /var/log/mytest.log touch /var/log/mytest_started_$(date +%Y%m%d_%H%M%S).flag ;; stop) echo "Stopping mytest at $(date)" >> /var/log/mytest.log ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0

为什么必须加INIT INFO块?
很多教程省略这一步,但 Ubuntu(尤其较新版本)和部分 CentOS 镜像会依赖它来判断脚本是否合规。少了它,update-rc.d可能直接跳过,或者chkconfig报错。这不是可有可无的注释,是 init 系统读取的元数据。

保存后,别忘了给执行权限:

sudo chmod +x /etc/init.d/mytest.sh

2. 确认你的系统到底走哪条“启动通道”

Linux 启动时,并不是一股脑把所有脚本全拉起来。它按“运行级别”(runlevel)分组加载,不同级别对应不同用途:比如单用户模式、多用户模式、图形界面模式等。

我们不需要背级别含义,只需要知道一件事:图形桌面环境通常运行在 runlevel 5,纯命令行多用户环境在 runlevel 3,而大多数现代桌面版 Ubuntu 和带 GUI 的 CentOS 默认就是 5

所以,先敲这一行,看自己系统当前和上次启动的级别:

runlevel

我的输出是:

N 5

N表示“未切换”(即开机后没手动改过),后面的5就是关键——它告诉我们,系统启动时会去/etc/rc5.d/这个目录里找要执行的脚本。

小知识卡片:rcx.d是什么?

  • /etc/init.d/是“脚本仓库”,存所有服务脚本原件;
  • /etc/rc5.d/(x=0~6)是“调度清单”,里面全是软链接,指向/etc/init.d/里的脚本;
  • 名字以S开头的,表示“Start”(启动);以K开头的,表示“Kill”(停止);
  • 后面的两位数字(如S99)决定执行顺序:数字越小越早执行,越大越晚。数据库服务一般要等网络就绪,所以常设为S99;而基础网络服务可能设为S10

3. 进入调度目录,准备加链接

既然runlevel显示是5,那就直奔主题:

cd /etc/rc5.d/

进来看看现在有什么:

ls -l S*

你会看到一堆类似S10sysklogdS20rsyslog这样的链接。它们都是系统自带服务,按序号排好队,等着开机时被挨个调用。

我们的目标,就是在这里加一个属于自己的链接,名字得符合规则:S+ 两位数字 + 自定义名(比如S99mytest)。数字选99是因为——它足够靠后,确保前面的基础服务(网络、文件系统)都已就绪,不会因依赖未满足而失败。

为什么不用S01
曾经我试过S01mytest,结果重启后日志里只有报错:“cannot resolve hostname”、“no route to host”。原因很简单:脚本里如果涉及网络请求或域名解析,它比网络服务还早启动,自然失败。S99不是随意选的,是留足缓冲的安全位。

4. 创建软链接:一行命令,两个路径

现在,回到/etc/rc5.d/目录,执行这条命令:

sudo ln -s /etc/init.d/mytest.sh S99mytest

注意三点:

  • 必须用sudo,否则没权限写系统目录;
  • 源路径/etc/init.d/mytest.sh要写绝对路径,不能写../init.d/mytest.sh
  • 目标名S99mytest不能带斜杠,就是纯文件名。

执行完,再ls -l S99*看一眼:

S99mytest -> /etc/init.d/mytest.sh

箭头右边清晰显示它确实指向了我们刚放好的脚本。这就完成了最关键的“注册”动作。

常见手误提醒

  • 写成ln -s S99mytest /etc/init.d/mytest.sh(源和目标反了)→ 链接会损坏;
  • 忘了sudo→ 权限拒绝,但终端可能不报错,只静默失败;
  • 脚本名拼错,比如mytest.sh写成mytest→ 链接存在,但指向无效路径,开机时会报 “No such file”。

5. 验证:不重启,也能先看效果

很多新手一上来就reboot,其实大可不必。我们可以模拟一次启动调用,提前验证脚本逻辑是否通顺:

sudo /etc/init.d/mytest.sh start

然后检查日志和标记文件:

tail -n 1 /var/log/mytest.log ls -t /var/log/mytest_started_*.flag | head -n 1

如果看到类似:

Starting mytest at Mon Jun 10 14:22:35 CST 2024 /var/log/mytest_started_20240610_142235.flag

说明脚本本身完全没问题,执行权限、路径、语法全部过关。这时候再重启,心里就有底了。

6. 重启测试:真刀真枪见分晓

终于到了见证时刻。执行:

sudo reboot

等待系统重新启动、登录后,立刻检查:

ls -t /var/log/mytest_started_*.flag | head -n 1

如果输出一个新生成的、时间戳明显是本次重启之后的文件名(比如mytest_started_20240610_143822.flag),恭喜你,成功了。

再补一句确认:

grep "Starting mytest" /var/log/mytest.log

你会看到至少两行记录:一行是刚才手动start的,另一行是开机自动触发的。时间戳清清楚楚,毫无歧义。

如果没看到?别慌,三步快速定位

  1. 先确认runlevel是否仍是5(有些服务器默认是3);
  2. 检查/etc/rc5.d/S99mytest是否真实存在且指向正确;
  3. 查看系统启动日志:sudo journalctl -b | grep mytest,看有没有报错信息,比如“permission denied”或“not found”。

7. 进阶建议:让管理更省心

脚本跑通只是开始。日常维护中,你还会遇到这些问题:怎么临时禁用?怎么查看状态?怎么卸载?这里给出几条轻量但实用的建议:

7.1 用update-rc.d替代手动 ln(Ubuntu 推荐)

Ubuntu 系统提供了更规范的管理方式。如果你用的是 Ubuntu,可以不用手动ln,改用:

sudo update-rc.d mytest.sh defaults 99

defaults会自动为 runlevel 2~5 添加S99mytest,为 0/1/6 添加K01mytest(关机时停止)。它比手动建链接更安全,也方便后续移除:

sudo update-rc.d -f mytest.sh remove

7.2 给脚本加个状态查询功能

上面的脚本只支持start/stop/restart,但没status。加一行就能让它支持:

status) if [ -f /var/log/mytest_started_*.flag ]; then echo "mytest is running (last started: $(ls -t /var/log/mytest_started_*.flag | head -n1 | cut -d'_' -f3- | sed 's/\.flag//'))" else echo "mytest is not running" fi ;;

然后就能用sudo /etc/init.d/mytest.sh status实时查看。

7.3 日志轮转,避免日志撑爆磁盘

长期运行的脚本,日志会越积越多。简单起见,可以在/etc/logrotate.d/下新建一个配置:

sudo tee /etc/logrotate.d/mytest << 'EOF' /var/log/mytest.log { daily missingok rotate 7 compress delaycompress notifempty } EOF

这样,日志每天切一份,保留最近7天,自动压缩,完全无感。

8. 总结:一次成功的背后,是四个确定性

这次“刚试完就成功”,不是运气,而是踩准了四个关键确定性:

  • 脚本确定性:有标准头、有完整 case 分支、有执行权限;
  • 路径确定性/etc/init.d/存原件,/etc/rc5.d/加链接,路径一分不差;
  • 时机确定性runlevel确认是5S99确保依赖就绪;
  • 验证确定性:重启前手动start测试逻辑,重启后ls+grep双重确认结果。

你不需要记住所有 runlevel 数字,也不必背熟每个rcx.d目录的用途。只要养成三个习惯:
① 每次操作前,先runlevel看一眼;
② 加链接时,用ls -l立刻确认指向是否正确;
③ 重启后,第一件事不是打开浏览器,而是ls /var/log/翻标记文件。

剩下的,就交给系统吧。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/3 19:08:46

万物识别+弹性GPU部署方案:AI企业提效降本新选择

万物识别弹性GPU部署方案&#xff1a;AI企业提效降本新选择 你是否遇到过这样的问题&#xff1a;每天要处理成百上千张商品图、文档扫描件、工业检测样本&#xff0c;却只能靠人工一张张标注、分类、核对&#xff1f;招一个图像识别工程师成本动辄三四十万&#xff0c;而采购整…

作者头像 李华
网站建设 2026/2/4 8:15:35

亲测阿里Z-Image-Turbo:8步生成高清图,效果惊艳

亲测阿里Z-Image-Turbo&#xff1a;8步生成高清图&#xff0c;效果惊艳 你有没有试过在AI绘图工具里输入一段描述&#xff0c;然后盯着进度条等上五六秒&#xff0c;结果生成的图不是手多一只&#xff0c;就是建筑歪斜、文字糊成一片&#xff1f;更别说中文提示词经常被“意译…

作者头像 李华
网站建设 2026/2/8 17:58:09

5分钟部署VibeThinker-1.5B-WEBUI,轻松搞定LeetCode算法题

5分钟部署VibeThinker-1.5B-WEBUI&#xff0c;轻松搞定LeetCode算法题 你是否经历过这样的场景&#xff1a;深夜刷LeetCode&#xff0c;卡在一道动态规划题上&#xff0c;反复推导状态转移方程却始终缺一个关键灵感&#xff1b;面试前突击准备&#xff0c;想快速验证自己设计的…

作者头像 李华
网站建设 2026/2/8 19:16:56

格式枷锁的终极破解:科研文档工具如何重塑学术创作流程

格式枷锁的终极破解&#xff1a;科研文档工具如何重塑学术创作流程 【免费下载链接】iNSFC An awesome LaTeX template for NSFC proposal. 项目地址: https://gitcode.com/gh_mirrors/in/iNSFC 痛点诊断&#xff1a;格式规范为何成为科研绊脚石&#xff1f; 您是否也曾…

作者头像 李华
网站建设 2026/2/6 9:27:53

嵌入式3年:外包 vs 自研,年薪差距竟达15万?

很多初入职场的嵌入式工程师都会面临这样一个选择&#xff1a;1. Offer A 来自一家知名的外包公司&#xff08;或者大厂OD&#xff09;&#xff0c;起薪不错&#xff0c;面试简单&#xff1b;2. Offer B 来自一家规模中等的自研产品公司&#xff0c;起薪平平&#xff0c;面试还…

作者头像 李华
网站建设 2026/2/8 12:42:51

声纹识别入门第一步:理解CAM++的Embedding含义

声纹识别入门第一步&#xff1a;理解CAM的Embedding含义 你有没有想过&#xff0c;为什么一段几秒钟的语音&#xff0c;就能让系统准确说出“这是张三的声音”&#xff1f;背后真正起作用的&#xff0c;不是整段音频波形&#xff0c;而是一个192维的数字向量——它就是CAM系统…

作者头像 李华