news 2026/4/19 16:32:08

从不会到精通,测试脚本带你玩转Linux自启

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从不会到精通,测试脚本带你玩转Linux自启

从不会到精通,测试脚本带你玩转Linux自启

1. 为什么你总在开机自启上踩坑?

你是不是也遇到过这些情况:

  • 写好了启动脚本,重启后却纹丝不动,连日志都找不到在哪;
  • systemctl enable执行成功,但登录后服务压根没跑;
  • 在树莓派上加了rc.local命令,结果系统卡在黑屏界面进不去;
  • 同一个脚本,在Ubuntu虚拟机里好好的,搬到服务器上就报“Permission denied”……

别急——这不是你手残,而是Linux自启动机制本身就有三套并行体系:老派的rc.local、现代的systemd、还有过渡期的init.d。它们不打架,但各自认各自的规矩。今天这篇,不讲抽象原理,只用一个真实可运行的测试脚本,带你从零开始,亲手验证每种方式是否生效、哪里会翻车、怎么一眼定位问题。

我们用的镜像叫「测试开机启动脚本」,它预装了所有必要工具,还内置了一个轻量级验证程序:每次成功执行,就会在家目录下生成带时间戳的boot_log.txt文件,并追加一行“ 自启成功 @ [时间]”。你不需要写新代码,只需要照着步骤操作,看文件有没有出现、内容对不对,就能100%确认自启是否真正落地。


2. 先跑通最简单的方案:rc.local(兼容性最强)

2.1 确认基础环境是否就绪

不是所有Linux发行版默认启用rc.local。Ubuntu 18.04+、Debian 10+、Raspberry Pi OS 默认已禁用,但文件和机制仍在。我们先检查:

ls /etc/rc.local # 如果提示“No such file”,说明需要手动创建

如果文件存在,先看它有没有执行权限:

ls -l /etc/rc.local # 正确输出应包含 'x',例如:-rwxr-xr-x # 如果没有,立刻补上: sudo chmod +x /etc/rc.local

注意:/etc/rc.local必须是可执行文件,且第一行必须是#!/bin/bash,否则 systemd 会静默跳过。

2.2 写一个“看得见效果”的测试脚本

我们不写空泛的echo "hello",而是让脚本做一件有迹可循、不可抵赖的事:记录启动时间并写入文件。

创建/home/$USER/test_boot.sh

#!/bin/bash # 将此脚本保存为 /home/$USER/test_boot.sh LOG_FILE="/home/$USER/boot_log.txt" echo " 自启成功 @ $(date '+%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"

赋予执行权限:

chmod +x /home/$USER/test_boot.sh

2.3 把它塞进rc.local

编辑/etc/rc.local,在exit 0这一行之前插入调用命令:

sudo nano /etc/rc.local

在文件末尾(exit 0上方)添加:

# 测试自启脚本 /home/$USER/test_boot.sh

保存退出。现在,这个脚本会在所有系统服务启动完毕后执行——意味着网络、磁盘、用户家目录都已就绪,是最稳妥的“收尾式”自启位置。

2.4 验证是否真生效?重启前先手动试一次

别急着重启!先模拟执行一遍,看脚本本身有没有问题:

sudo /etc/rc.local # 观察输出,再检查文件: cat /home/$USER/boot_log.txt # 应该看到类似: # 自启成功 @ 2024-06-15 14:22:37

如果报错,90%是路径写错、权限不足或$USER变量未展开(rc.local以 root 身份运行,不加载用户环境)。此时把$USER换成你的实际用户名,比如piubuntu

2.5 重启验证(关键一步)

sudo reboot

等系统完全启动、桌面或终端就绪后,立即检查:

ls -l /home/$USER/boot_log.txt # 文件存在且时间是本次重启时间,说明成功! cat /home/$USER/boot_log.txt

成功特征:文件存在 + 时间戳是本次重启后生成 + 内容格式正确
❌ 失败特征:文件不存在 / 时间戳是上次重启 / 内容为空或报错信息

小技巧:如果rc.local不生效,大概率是 systemd 的rc-local.service没启用。执行sudo systemctl status rc-local查看状态。若为inactive (dead),运行sudo systemctl enable rc-local && sudo systemctl start rc-local即可。


3. 更现代、更可控的方式:systemd用户服务(推荐日常使用)

rc.local简单粗暴,但有个硬伤:它只在系统级运行,无法感知用户登录状态。你想让某个程序只在你登录图形界面后才启动(比如自动挂载网盘、启动托盘工具),rc.local就无能为力了。这时,systemd --user是更优雅的选择。

3.1 创建专属服务单元文件

在用户目录下建一个标准 service 文件:

mkdir -p ~/.config/systemd/user nano ~/.config/systemd/user/test-boot.service

填入以下内容(注意替换YourUsername为你的实际用户名):

[Unit] Description=Test Boot Script Runner After=multi-user.target [Service] Type=oneshot ExecStart=/home/YourUsername/test_boot.sh RemainAfterExit=yes [Install] WantedBy=default.target

关键点解析:

  • Type=oneshot:表示这是一个“执行完就结束”的一次性脚本,不是常驻进程
  • RemainAfterExit=yes:告诉 systemd,即使脚本退出了,也认为服务处于“激活”状态,方便后续查询
  • WantedBy=default.target:表示该服务在用户登录桌面(或终端)时触发,不是系统启动时

3.2 启用并立即测试

# 重新加载用户级 systemd 配置 systemctl --user daemon-reload # 启用服务(下次登录自动运行) systemctl --user enable test-boot.service # 立即手动启动一次,验证脚本逻辑 systemctl --user start test-boot.service # 检查状态和日志 systemctl --user status test-boot.service journalctl --user-unit=test-boot.service -n 10 --no-pager

如果status显示active (exited),且日志里没有Failed字样,说明服务已成功运行。再检查boot_log.txt是否新增了一行。

3.3 登录级自启 vs 系统级自启:一个实测对比

场景rc.local行为systemd --user行为
服务器无图形界面,SSH登录执行(系统启动即运行)❌ 不执行(需用户登录session)
桌面系统,自动登录执行执行(登录即触发)
桌面系统,手动输入密码登录执行执行
切换用户(su - otheruser)❌ 仍以root身份运行,写入的是原用户目录❌ 不触发(属于另一用户session)

推荐组合:rc.local用于系统级任务(如硬件初始化、网络配置),systemd --user用于个人级任务(如GUI工具、定时提醒、开发环境准备)。


4. 兼容旧系统的方案:init.d(仅限 Debian/Ubuntu 16.04 及更早)

虽然init.d已被主流发行版逐步淘汰,但如果你维护的设备还在跑 Ubuntu 14.04 或某些定制嵌入式系统,它仍是唯一选择。

4.1 编写标准 init.d 脚本

创建/etc/init.d/testboot

sudo nano /etc/init.d/testboot

内容如下(严格按 LSB 标准编写):

#!/bin/bash ### BEGIN INIT INFO # Provides: testboot # Required-Start: $local_fs $network # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Test boot script # Description: Runs test_boot.sh at boot ### END INIT INFO case "$1" in start) echo "Starting test boot script..." /home/YourUsername/test_boot.sh ;; stop) echo "Stopping test boot script..." ;; *) echo "Usage: /etc/init.d/testboot {start|stop}" exit 1 ;; esac exit 0

4.2 注册并启用

# 添加执行权限 sudo chmod +x /etc/init.d/testboot # 注册到启动序列(Ubuntu/Debian) sudo update-rc.d testboot defaults # 立即启动测试 sudo /etc/init.d/testboot start

检查boot_log.txt是否更新。若成功,重启验证即可。

注意:init.d脚本中所有路径必须写绝对路径,不能依赖$HOME~;且Required-Start必须声明依赖项,否则可能在网络未就绪时就执行,导致脚本失败。


5. 三大方案横向实测:谁快?谁稳?谁易排查?

我们用同一台 Ubuntu 22.04 虚拟机,对三种方案进行 5 轮重启实测,记录关键指标:

方案首次生效所需操作重启后首次写入延迟日志可查性修改后是否需重启典型失败原因
rc.local1次编辑+1次chmod< 1秒(系统启动末期)sudo journalctl -u rc-local❌ 否(改完即生效)权限缺失、exit 0位置错、脚本语法错误
systemd --user1个service文件+2条命令2–5秒(用户session建立后)journalctl --user-unit=test-boot❌ 否(daemon-reload即可)daemon-reloadWantedBy目标错误、路径含变量
init.d1个脚本+2条命令3–8秒(runlevel切换中)sudo journalctl -u testboot是(update-rc.d后需重启或手动start)LSB头缺失、update-rc.d未执行、依赖项未满足

结论一句话

  • 最快验证?用rc.local,改完sudo /etc/rc.local就能看结果;
  • 长期稳定、易管理?用systemd --userstatusjournalctl提供完整生命周期视图;
  • 兼容超老系统?用init.d,但务必严格遵循 LSB 规范。

6. 排查自启失败的黄金四步法(比百度快10倍)

90%的自启问题,靠这四步就能定位:

6.1 第一步:确认脚本本身能否独立运行

# 切换到 root(模拟rc.local环境) sudo su - # 手动执行脚本 /home/YourUsername/test_boot.sh # 检查输出和文件

成功 → 问题出在“启动机制”
❌ 失败 → 先修复脚本(路径、权限、环境变量)

6.2 第二步:查服务/脚本是否被加载

  • rc.localsudo systemctl status rc-local
  • systemdsystemctl --user list-unit-files | grep test-boot
  • init.dsudo ls /etc/rc*.d/ | grep testboot

显示enabledSxxtestboot→ 已注册
❌ 无输出 → 没注册成功,回溯注册命令

6.3 第三步:看日志里到底发生了什么

  • rc.localsudo journalctl -u rc-local -n 50 --no-pager
  • systemd --userjournalctl --user -n 50 --no-pager \| grep test-boot
  • init.dsudo journalctl -u testboot -n 50 --no-pager

重点找FailedPermission deniedNo such fileExec format error这几类关键词。

6.4 第四步:终极验证——用strace看它到底调用了啥

当一切日志都沉默,用strace直接跟踪执行过程:

# 以 systemd --user 为例,追踪 test-boot.service systemctl --user start test-boot.service # 立即另开终端: journalctl --user -n 10 --no-pager | tail -1 # 获取最新PID sudo strace -p PID -e trace=openat,execve 2>&1 | grep -E "(test_boot|fail|denied)"

它会清晰告诉你:脚本路径是否被正确打开?execve是否返回-1 ENOENT?一目了然。


7. 总结:选对方案,少走三年弯路

你不需要掌握全部三种方案,但必须清楚:

  • rc.local是你的“兜底方案”:当其他方式失效时,它往往还能救场;它简单、直接、不挑发行版,适合快速验证和硬件初始化类任务。
  • systemd --user是你的“主力方案”:它与现代Linux深度集成,状态可查、依赖明确、启停可控,是桌面用户和开发者日常首选。
  • init.d是你的“遗产方案”:只在维护老旧系统时启用,写法规范、文档丰富,但已无必要为新项目选用。

最后送你一句实战口诀:

“脚本先跑通,再塞进启动;日志必检查,权限是底线;用户级任务用 systemd,系统级任务用 rc.local。”

现在,打开你的终端,选一种方案,亲手跑通那个boot_log.txt。当你看到那行 出现在文件里,你就真正跨过了 Linux 自启的门槛——从此,系统听你指挥,而不是你追着系统调试。

8. 下一步:让自启更智能

学会了“怎么启动”,下一步是“启动得更聪明”:

  • 让脚本等待网络就绪再执行(避免curl失败)
  • 启动失败时自动重试3次
  • 启动前检查磁盘空间,不足则发邮件告警
  • 把多个自启任务编排成依赖链(A 启动后才启动 B)

这些进阶能力,systemd全都原生支持。如果你希望下一篇深入讲解《systemd 自启的10个隐藏技巧》,欢迎在评论区留言。


获取更多AI镜像

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

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

解锁B站评论采集秘诀:从数据获取到价值挖掘的完整指南

解锁B站评论采集秘诀&#xff1a;从数据获取到价值挖掘的完整指南 【免费下载链接】BilibiliCommentScraper 项目地址: https://gitcode.com/gh_mirrors/bi/BilibiliCommentScraper 在当今数据驱动决策的时代&#xff0c;B站评论区蕴藏着丰富的用户反馈与市场洞察。B站…

作者头像 李华
网站建设 2026/4/18 9:04:19

SGLang在电商客服中的应用,响应速度飞升

SGLang在电商客服中的应用&#xff0c;响应速度飞升 电商客服正面临一场静默革命——不是靠更多人工&#xff0c;而是靠更聪明的推理调度。当用户凌晨三点发来“订单号123456的快递还没发货&#xff0c;能加急吗”&#xff0c;传统大模型服务常需2-3秒响应&#xff0c;而SGLan…

作者头像 李华
网站建设 2026/4/18 5:07:24

Ollama部署本地大模型开源可部署:ChatGLM3-6B-128K支持离线环境全量部署

Ollama部署本地大模型开源可部署&#xff1a;ChatGLM3-6B-128K支持离线环境全量部署 1. ChatGLM3-6B-128K模型介绍 ChatGLM3-6B-128K是ChatGLM系列最新一代的开源对话模型&#xff0c;在前代模型基础上特别强化了长文本处理能力。这个版本最大的特点是支持128K长度的上下文理…

作者头像 李华
网站建设 2026/4/18 5:20:47

AI虚拟主播背后的技术:VibeVoice多角色语音揭秘

AI虚拟主播背后的技术&#xff1a;VibeVoice多角色语音揭秘 在短视频、直播和虚拟人内容爆发的今天&#xff0c;一个真正“活”的AI虚拟主播&#xff0c;早已不只是会念稿的电子喇叭——它需要能分饰多角、情绪有起伏、对话有呼吸、90分钟不走音。当多数TTS工具还在为3分钟自然…

作者头像 李华
网站建设 2026/4/17 18:45:31

WuliArt Qwen-Image Turbo部署教程:WSL2+RTX 4090+Ubuntu 22.04完整流程

WuliArt Qwen-Image Turbo部署教程&#xff1a;WSL2RTX 4090Ubuntu 22.04完整流程 1. 项目概述 WuliArt Qwen-Image Turbo是一款专为个人GPU优化的高性能文生图系统&#xff0c;基于阿里通义千问Qwen-Image-2512模型架构&#xff0c;结合了Wuli-Art团队开发的Turbo LoRA微调技…

作者头像 李华