news 2026/3/24 8:30:35

Ubuntu开机脚本不会配?这个测试镜像手把手教你

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ubuntu开机脚本不会配?这个测试镜像手把手教你

Ubuntu开机脚本不会配?这个测试镜像手把手教你

你是不是也遇到过这样的问题:服务器重启后,自己写的程序没跟着起来,得手动登录、cd到目录、再敲一遍启动命令?每次都要重复操作,既浪费时间又容易出错。更糟的是,万一半夜服务挂了,没人及时处理,业务就断了。

别急——其实只要一个简单的开机启动脚本,就能让程序在系统一启动时就自动运行。但很多新手卡在第一步:脚本怎么写?放哪?怎么注册成服务?为什么写了却没生效?

这篇博客不讲抽象概念,不堆术语,就用「测试开机启动脚本」这个轻量镜像,带你从零开始,一行一行敲、一步一验证,真正把开机自启这件事搞明白。不需要你懂 init.d、systemd 的底层原理,只需要你会复制粘贴、会敲几条命令,15分钟内就能让自己的脚本稳稳跑在开机第一秒。


1. 先搞清楚:我们到底要解决什么问题

1.1 开机自启 ≠ 简单丢个.sh文件就完事

很多人以为,把启动命令写进/etc/rc.local或者扔个start.sh在桌面,再加个chmod +x就能开机运行——结果重启后发现:

  • 脚本根本没执行;
  • 执行了但报“找不到命令”或“权限被拒绝”;
  • 程序启动了,但立刻退出,日志里只有一行nohup: ignoring input
  • 多个服务之间启动顺序错乱,依赖的服务还没起来,上游就先启动失败。

这些问题的根源,不是脚本写得不对,而是缺少系统级的生命周期管理。Linux 不是 Windows,它不会“看到脚本就执行”,而是通过一套服务管理机制(比如 SysV init 或 systemd)来统一调度、校验依赖、记录状态。

1.2 这个镜像帮你绕过所有坑

「测试开机启动脚本」镜像不是一堆现成代码的打包,而是一个可交互、可验证、带反馈的实操环境

  • 预装了完整 Ubuntu 22.04 系统(兼容主流云服务器和本地虚拟机);
  • 内置一个已配置好的test服务示例(含启动/停止/重启逻辑);
  • 所有路径、权限、依赖项都提前调通,你只需关注“怎么做”,不用纠结“为什么不行”;
  • 每步操作后都有明确验证方式(比如sudo service test status返回active (running)才算成功);
  • 支持两种主流方式:传统update-rc.d(适合老项目/兼容性要求高场景)和现代systemctl(推荐新部署)。

换句话说:你不用再百度“ubuntu 开机启动脚本 权限错误”,也不用反复重启试错。镜像就是你的沙盒实验室。


2. 动手实操:用镜像一步步配好你的第一个开机脚本

2.1 启动镜像并进入终端

如果你还没拉取镜像,执行这条命令(已适配国内源加速):

docker run -it --rm --privileged -p 2222:22 csdn/mirror-test-startup:latest

提示:镜像已预装openssh-servervim,支持 SSH 连接(默认用户ubuntu,密码ubuntu),也支持直接docker exec -it <容器ID> /bin/bash进入。

进入后,先确认当前用户有sudo权限:

whoami && sudo -n true && echo " sudo 权限正常"

如果提示sudo: a password is required,输入密码ubuntu即可。

2.2 查看预置的测试服务脚本

镜像中已准备好完整的test服务脚本,位置在/etc/init.d/test。我们先用cat快速浏览结构:

sudo cat /etc/init.d/test

你会看到类似这样的开头(关键部分已加注释):

#!/bin/bash ### BEGIN INIT INFO # Provides: test # 服务名,必须和文件名一致 # Required-Start: $local_fs $network # 启动前必须就绪的系统资源 # Required-Stop: $local_fs # 停止前必须保持的资源 # Default-Start: 2 3 4 5 # 在哪些运行级别启动(2~5 是多用户图形/网络模式) # Default-Stop: 0 1 6 # 在哪些级别停止(0关机、1单用户、6重启) # Short-Description: test service # 简短描述,显示在 service list 中 # Description: A demo service for startup script testing ### END INIT INFO

注意:### BEGIN INIT INFO### END INIT INFO之间的注释块不是可选的。它是update-rc.d工具识别服务依赖和启动顺序的唯一依据。少一个#或格式错位,注册就会失败。

再往下看,是实际的启动逻辑:

# 定义要管理的子服务目录(模拟多个微服务) files=(file opt merchant) deploy=/home/ubuntu/deploy/ start() { echo "Starting test services..." for var in "${files[@]}"; do cd "$deploy$var" || { echo "❌ Failed to enter $deploy$var"; exit 1; } # 检查是否存在 start.sh 并执行 if [ -x "start.sh" ]; then ./start.sh & else echo " No executable start.sh in $deploy$var" fi done }

关键点:

  • 使用"${files[@]}"而不是$files,避免空格路径出错;
  • cd ... || exit 1保证任一目录失败就中断,不静默跳过;
  • ./start.sh &后台运行,但不加nohup—— 因为 init.d 脚本本身由系统守护进程管理,无需自行守护。

2.3 验证脚本语法与权限

在注册前,先手动执行一次,确保脚本能跑通:

sudo /etc/init.d/test start sleep 2 sudo /etc/init.d/test status

你应该看到类似输出:

● test.service - LSB: test service Loaded: loaded (/etc/init.d/test; generated) Active: active (running) since ...

如果报错command not found,大概率是start.sh缺少执行权限。镜像中已修复,但你自己写时务必检查:

sudo chmod +x /home/ubuntu/deploy/file/start.sh

2.4 注册为开机服务(两种方式任选)

方式一:使用update-rc.d(SysV init 兼容方式)

这是最经典、兼容性最强的方式,适用于 Ubuntu 16.04~22.04(即使 systemd 主导,仍完全支持):

sudo update-rc.d test defaults 95
  • defaults表示按Default-Start/Stop注释里的级别启用;
  • 95是启动优先级(0~99),数字越大越晚启动。这里设为 95,确保网络、磁盘等基础服务已就绪。

验证是否注册成功:

sudo ls -l /etc/rc*.d/*test*

应看到类似:

/etc/rc0.d/K05test /etc/rc1.d/K05test /etc/rc2.d/S95test /etc/rc3.d/S95test ...

其中S表示 Start,K表示 Kill,数字代表顺序。

方式二:使用systemctl(推荐新项目)

虽然镜像默认用 SysV,但我们也提供.service文件模板(位于/opt/templates/test.service),可一键启用:

sudo cp /opt/templates/test.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable test.service

验证:

systemctl is-enabled test.service # 应返回 "enabled" systemctl status test.service # 查看当前状态

两种方式可共存,但建议新项目统一用systemctl—— 它支持依赖声明、日志聚合、自动重启策略等高级功能。


3. 自己写一个:从零创建属于你的开机脚本

3.1 明确需求:你想开机自动运行什么?

别急着写代码。先问自己三个问题:

  • 它是什么程序?(Python 脚本?Java jar?Node.js 服务?)
  • 它需要什么前置条件?(网络连通?某个目录存在?数据库已启动?)
  • 它是否需要持续运行?(还是只执行一次就退出?)

举个真实例子:你写了一个 Python 监控脚本monitor.py,需要每 5 秒检查一次磁盘空间,并把结果写入/var/log/disk.log。它依赖网络(发告警邮件)和磁盘写入权限。

那么你的脚本核心需求就是:
开机后自动启动;
确保/var/log可写;
如果崩溃,自动重启;
日志集中管理,方便排查。

3.2 模板化编写:抄作业也能抄明白

镜像中提供了通用模板/opt/templates/custom-startup.sh,你只需改 4 处:

#!/bin/bash ### BEGIN INIT INFO # Provides: mymonitor # Required-Start: $local_fs $network # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Disk monitor service # Description: Monitors disk usage and logs to /var/log/disk.log ### END INIT INFO # 👇 修改1:你的程序路径 APP_PATH="/home/ubuntu/monitor.py" # 👇 修改2:你的工作目录(Python 导入路径可能依赖) WORK_DIR="/home/ubuntu" # 👇 修改3:你的日志路径 LOG_FILE="/var/log/disk.log" # 👇 修改4:启动命令(根据语言调整) START_CMD="python3 $APP_PATH >> $LOG_FILE 2>&1 &" start() { echo "Starting mymonitor..." mkdir -p "$(dirname $LOG_FILE)" chown ubuntu:ubuntu "$LOG_FILE" cd "$WORK_DIR" # 检查是否已在运行 if pgrep -f "$APP_PATH" > /dev/null; then echo " mymonitor already running" return 0 fi eval "$START_CMD" echo " mymonitor started with PID $!" } stop() { echo "Stopping mymonitor..." pkill -f "$APP_PATH" || true echo " mymonitor stopped" } case "$1" in start) start ;; stop) stop ;; restart) stop; sleep 1; start ;; *) echo "Usage: $0 {start|stop|restart}"; exit 1 ;; esac

抄完记得:

  • 保存为/etc/init.d/mymonitor
  • sudo chmod +x /etc/init.d/mymonitor
  • sudo update-rc.d mymonitor defaults
  • sudo service mymonitor start测试。

3.3 高级技巧:让脚本更健壮

  • 防止重复启动:用pgrep -f检查进程是否存在(比pidfile更可靠);
  • 日志自动轮转:配合logrotate,避免日志撑爆磁盘;
  • 失败自动恢复:在systemd中加Restart=alwaysRestartSec=10
  • 环境变量隔离systemd服务中用Environment="PATH=/usr/local/bin:/usr/bin"避免command not found

镜像中/opt/guide/advanced-tips.md有详细说明,可随时查阅。


4. 排查常见问题:脚本写了,为啥不生效?

4.1 最常踩的 3 个坑

现象原因快速验证命令解决方案
sudo service xxx startunrecognized service脚本没放在/etc/init.d/,或文件名与Provides:不一致ls /etc/init.d/xxxgrep "Provides:" /etc/init.d/xxx确保路径正确、名称匹配、有执行权限
服务显示active (exited)但进程不存在脚本执行完就退出(比如忘了加&nohupsudo journalctl -u xxx.service -n 20改用&后台运行,或用systemdType=simple
重启后服务没启动update-rc.d未生效,或systemctl enable漏掉sudo ls /etc/rc2.d/ | grep xxxsystemctl is-enabled xxx.service重新执行注册命令,确认输出enabled

4.2 一条命令定位所有问题

镜像内置诊断脚本/opt/bin/diagnose-startup.sh,运行它:

sudo /opt/bin/diagnose-startup.sh mymonitor

它会自动检查:
脚本是否存在且可执行;
Provides名称是否匹配;
依赖服务($network等)是否就绪;
是否已注册到 rcN.d 目录;
当前运行状态与 PID 是否一致。

输出结果清晰标红/绿,直指病灶。


5. 总结:开机脚本的本质,是让机器听懂你的意图

写一个开机脚本,技术上只是几行 bash 和一次update-rc.d。但背后体现的,是一种工程思维:

  • 明确边界:知道程序需要什么、不能假设什么;
  • 尊重约定:init.d 的注释块、systemd 的 unit 文件,不是形式主义,而是系统沟通的语言;
  • 验证闭环:不以“写完”为终点,而以“重启后稳定运行 24 小时”为验收标准。

这个「测试开机启动脚本」镜像,就是帮你把这种思维落地的最小可行环境。它不教你怎么成为 Linux 内核专家,但能让你今天下午就配好生产环境的第一个自启服务。

现在,关掉这篇博客,打开终端,敲下第一行sudo vim /etc/init.d/myapp—— 你的自动化运维之旅,就从这一行开始。

--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/20 22:44:53

FactoryBluePrints蓝图库进阶应用指南

FactoryBluePrints蓝图库进阶应用指南 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints 在戴森球计划的浩瀚宇宙中&#xff0c;你是否曾因复杂的工厂布局而感到无从下手&…

作者头像 李华
网站建设 2026/3/24 11:16:31

3步实现零代码配置:让黑苹果安装像拼图一样简单

3步实现零代码配置&#xff1a;让黑苹果安装像拼图一样简单 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 传统黑苹果配置往往需要用户花费数小时甚至…

作者头像 李华
网站建设 2026/3/24 0:09:08

CAM++余弦相似度计算:Python代码实现详细教程

CAM余弦相似度计算&#xff1a;Python代码实现详细教程 1. 什么是CAM说话人识别系统 CAM是一个专注于中文语音场景的说话人验证工具&#xff0c;由开发者“科哥”基于达摩院开源模型二次开发而成。它不是简单的语音转文字系统&#xff0c;而是一个能“听声辨人”的智能工具—…

作者头像 李华
网站建设 2026/3/24 14:36:32

FSMN VAD智能剪辑应用:视频配音有效段落识别

FSMN VAD智能剪辑应用&#xff1a;视频配音有效段落识别 在视频后期制作中&#xff0c;一个常被忽视却极其关键的环节是——配音音频的有效性判断。你是否遇到过这样的情况&#xff1a;花几小时录完配音&#xff0c;导入剪辑软件后才发现前3秒是咳嗽、中间夹杂键盘声、结尾拖了…

作者头像 李华
网站建设 2026/3/21 7:08:22

5分钟上手Open-AutoGLM,手机AI助手一键部署实战

5分钟上手Open-AutoGLM&#xff0c;手机AI助手一键部署实战 你有没有想过&#xff0c;用一句话就能让手机自动完成一连串操作&#xff1f;比如“打开小红书搜最近爆火的咖啡店探店笔记”&#xff0c;说完这句话&#xff0c;手机自己点开App、输入关键词、滑动浏览——全程不用…

作者头像 李华