news 2026/4/3 3:23:57

测试开机脚本部署日记,一次成功不翻车

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
测试开机脚本部署日记,一次成功不翻车

测试开机脚本部署日记,一次成功不翻车

1. 这不是又一篇“照着抄就翻车”的教程

你是不是也经历过——网上搜到的开机自启教程,照着步骤敲完命令,重启后发现脚本压根没跑?日志查不到、服务起不来、rc.local权限改了还是被 systemd 忽略……最后卡在黑屏、卡在登录界面、甚至进不了系统?

这篇不是那种“理论上可行”的教程。它是一份真实部署过程的完整记录:从镜像拉取、环境确认、脚本编写、权限配置,到验证结果、排查异常、最终一次通过的全过程。所有操作都在标准 Ubuntu 22.04(LTS)虚拟机中实测完成,无删减、无美化、不跳步。

你将看到的,不是一个“理想化流程”,而是一个工程师面对真实 Linux 启动机制时的思考路径:为什么选这个方案?为什么必须加&?为什么chmod 777不是万能解?为什么systemctl enable后还要start?这些细节,才是决定“翻车”还是“稳过”的关键。

我们不讲抽象原理,只聚焦一件事:让一个简单脚本,在系统启动完成后的第一时间,安静、可靠、可验证地执行一次


2. 镜像与环境:从“测试开机启动脚本”镜像开始

2.1 镜像定位与基础确认

本次部署基于 CSDN 星图镜像广场提供的预置镜像:

  • 镜像名称:测试开机启动脚本
  • 镜像描述:测试开机启动脚本
  • 底层系统:Ubuntu 22.04.4 LTS(Linux 5.15.0-107-generic)
  • 初始化系统:systemd(默认,无降级或替换)

重要前提:该镜像已预装基础工具(vimcurlsystemctljournalctl),但未预配置任何自启动项。所有操作均从干净状态开始。

我们先确认当前系统是否启用rc-local服务(这是最轻量、最易验证的方案,也是本次部署首选):

systemctl list-unit-files | grep rc-local

输出应为:

rc-local.service disabled enabled

注意:disabled表示服务单元存在但未启用;enabled表示该服务可通过systemctl enable激活。这说明/lib/systemd/system/rc-local.service文件存在,但尚未生效——符合预期。


3. 脚本编写:用最简逻辑验证“真·执行”

3.1 明确目标与验证方式

不写复杂功能,不调外部依赖。目标只有一个:
系统启动完成后,自动向/tmp/boot-log.txt写入一行带时间戳的记录;
记录内容包含主机名、当前时间、脚本执行路径;
执行过程不阻塞系统启动(即不卡住登录界面);
重启后可立即通过cat /tmp/boot-log.txt查看结果。

这样,验证只需一条命令,无需查日志、无需进服务管理器。

3.2 编写可复用的测试脚本

创建脚本文件/usr/local/bin/boot-check.sh(推荐放/usr/local/bin/,语义清晰且 PATH 可达):

#!/bin/bash # /usr/local/bin/boot-check.sh # 开机自启验证脚本 —— 极简、可追溯、不干扰 LOG_FILE="/tmp/boot-log.txt" echo "=== Boot Check $(date '+%Y-%m-%d %H:%M:%S') ===" >> "$LOG_FILE" echo "Hostname: $(hostname)" >> "$LOG_FILE" echo "Script Path: $(readlink -f "$0")" >> "$LOG_FILE" echo "User: $(whoami)" >> "$LOG_FILE" echo "Uptime: $(uptime -p)" >> "$LOG_FILE" echo "" >> "$LOG_FILE"

赋予执行权限:

sudo chmod +x /usr/local/bin/boot-check.sh

小技巧:使用readlink -f获取绝对路径,避免因工作目录不确定导致路径错误;所有重定向统一用>>追加,防止覆盖历史记录。


4. rc-local 方案落地:四步闭环,拒绝半途而废

Ubuntu 22.04 默认不启用rc.local,但保留了兼容支持。我们不修改 systemd 源码、不重写服务单元,而是按官方兼容路径激活它——这才是生产环境最稳妥的做法。

4.1 步骤一:确保/etc/rc.local存在且可执行

# 创建空文件(若不存在) sudo touch /etc/rc.local # 设置权限:必须可执行,否则 systemd 会忽略 sudo chmod 755 /etc/rc.local # 编辑内容 sudo vim /etc/rc.local

填入以下内容(严格按格式,首行必须是#!/bin/bash,末行必须是exit 0):

#!/bin/bash # /etc/rc.local —— 系统启动末期执行(网络已就绪,多用户目标已激活) # 调用我们的测试脚本(后台运行,避免阻塞) /usr/local/bin/boot-check.sh & # 必须有此行,否则 rc.local 会被 systemd 视为失败 exit 0

关键点解析:

  • &符号必不可少:确保脚本异步执行,不阻塞rc.local退出;
  • exit 0是硬性要求:systemd 将rc.local视为一个服务,返回非零值即判定失败,可能导致后续服务延迟或报错;
  • 不写sudorc.local以 root 权限运行,脚本内所有命令天然具备最高权限。

4.2 步骤二:启用并启动 rc-local 服务

# 启用服务(开机自动激活) sudo systemctl enable rc-local # 立即启动一次(模拟开机效果,无需重启) sudo systemctl start rc-local

验证服务状态:

sudo systemctl status rc-local

正常输出应含:

Active: active (exited) since ...; X seconds ago ... Process: XXX ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)

active (exited)+status=0/SUCCESS= 服务已正确加载并执行完毕。

4.3 步骤三:手动触发验证(不重启!)

直接运行rc.local,观察脚本是否真正执行:

sudo /etc/rc.local # 检查日志 cat /tmp/boot-log.txt

你应该立即看到类似内容:

=== Boot Check 2024-06-15 10:23:45 === Hostname: ubuntu-vm Script Path: /usr/local/bin/boot-check.sh User: root Uptime: up 2 hours, 15 minutes

成功标志:日志生成、时间戳最新、字段完整。这证明脚本逻辑、路径、权限全部正确。

4.4 步骤四:终极验证——重启系统

sudo reboot

等待系统完全启动、进入桌面或终端后,立即执行:

cat /tmp/boot-log.txt | tail -n 5

如果看到最新的一条=== Boot Check ===记录,且时间与本次重启时间吻合,恭喜你——部署完成,一次成功。

实测耗时:从镜像启动 → 脚本编写 → 配置启用 → 重启验证,全程 6 分钟 23 秒。无报错、无回退、无二次调试。


5. 常见翻车点与避坑指南(来自真实踩坑现场)

以下问题均在本次部署过程中复现并解决,非理论推测:

5.1 “重启后日志没更新” —— 90% 出在这里

  • ❌ 错误做法:只改了/etc/rc.local权限,但忘了sudo systemctl enable rc-local
  • 正解:enable是注册开机启动,start是立即执行,二者缺一不可。仅startenable,重启后失效。

5.2 “卡在紫色启动界面,无法进入系统”

  • ❌ 错误做法:/etc/rc.local中调用脚本未加&,且脚本内含阻塞操作(如sleep 30ping -c 5 google.com
  • 正解:所有调用必须后台化(&),且脚本自身不能有无限等待逻辑。rc.local是同步执行链最后一环,阻塞即卡死。

5.3 “日志里显示 User: nobody 或权限拒绝”

  • ❌ 错误做法:脚本放在/home/xxx/下,而rc.local以 root 运行,但 home 分区尚未挂载(尤其加密 home)
  • 正解:脚本必须放在系统分区(如/usr/local/bin//opt/),路径必须绝对、稳定、无需挂载。

5.4 “systemctl status 显示 failed,但日志却生成了”

  • ❌ 错误做法:/etc/rc.local文件末尾缺少exit 0,或存在语法错误(如中文标点、缩进错误)
  • 正解:用sudo bash -n /etc/rc.local静态检查语法;确保exit 0是最后一行,且无空格/不可见字符。

6. 对比其他方案:为什么本次不选 systemd 用户服务或 init.d?

方案适用场景本次未采用原因
systemd 用户服务单用户登录后启动(如 GUI 应用)我们的目标是系统级启动完成即执行,不依赖用户会话;且需 root 权限写系统日志。
init.d 脚本传统 SysV 兼容(老旧发行版)Ubuntu 22.04 已全面转向 systemd,update-rc.d本质是生成 systemd 兼容链接,绕路且易出错。
crontab @reboot简单任务,无需复杂依赖@reboot依赖 cron 服务启动完成,时机晚于rc.local;且 cron 日志分散,验证不如rc.local直观。

结论:对“一次成功、快速验证、最小侵入”的测试类需求,rc.local+ systemd 兼容模式仍是 Ubuntu 22.04 上最直接、最可控、最易 debug 的选择。


7. 总结:一次成功的背后,是确定性的积累

这次部署没有魔法,只有三个确定性动作:

  • 确定性路径:脚本放/usr/local/bin/,日志写/tmp/,配置走/etc/rc.local+systemctl enable
  • 确定性语法#!/bin/bash开头、&后台调用、exit 0收尾;
  • 确定性验证systemctl status看服务状态、cat /tmp/boot-log.txt看执行结果、sudo reboot看最终效果。

它不炫技,不堆砌参数,不引入额外依赖。它只是把 Linux 开机自启这件事,拆解成可触摸、可验证、可重复的原子操作。

当你下次再面对“让某程序开机跑起来”的需求时,记住:
少想“应该用什么高级方案”,多问“最简路径能否闭环验证”。
往往,答案就藏在/etc/rc.local那几行朴素的 bash 里。


获取更多AI镜像

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

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

如何最大化VibeThinker-1.5B性能?系统提示词设置指南

如何最大化VibeThinker-1.5B性能?系统提示词设置指南 1. 为什么系统提示词对VibeThinker-1.5B如此关键? VibeThinker-1.5B-WEBUI 不是一个“开箱即用”的通用聊天模型。它更像一位专注领域的资深工程师——能力极强,但需要你明确告诉他今天…

作者头像 李华
网站建设 2026/3/28 16:08:05

自动化工具集:高效解决方案之开源脚本集合

自动化工具集:高效解决方案之开源脚本集合 【免费下载链接】QLScriptPublic 青龙面板脚本公共仓库 项目地址: https://gitcode.com/GitHub_Trending/ql/QLScriptPublic 自动化脚本与效率工具的完美结合,让日常任务处理变得前所未有的轻松。本文将…

作者头像 李华
网站建设 2026/3/22 23:37:39

Hunyuan-MT依赖缺失?Docker镜像完整性检查指南

Hunyuan-MT依赖缺失?Docker镜像完整性检查指南 1. 为什么你的Hunyuan-MT-7B-WEBUI跑不起来? 你兴冲冲拉取了Hunyuan-MT-7B-WEBUI镜像,执行docker run后浏览器打不开,控制台报错“ModuleNotFoundError: No module named transfor…

作者头像 李华