news 2026/4/18 8:03:59

用测试脚本做了个开机提醒程序,附完整过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用测试脚本做了个开机提醒程序,附完整过程

用测试脚本做了个开机提醒程序,附完整过程

你有没有过这样的经历:早上急着出门,电脑还在后台跑着重要任务,却忘了设置提醒?或者远程服务器重启后,不确定某个关键服务是否已就绪?其实,一个轻量、可靠、不依赖图形界面的开机提醒程序,就能解决这类问题——它能在系统启动完成的第一时间,用最直接的方式告诉你:“我醒了”。

本文不讲抽象理论,不堆砌术语,只带你从零开始,亲手打造一个真正能用的开机提醒程序。它不依赖桌面环境,不占用大量资源,支持声音播报、日志记录、网络状态检测,且适配主流Linux发行版(Ubuntu/Debian系及树莓派)。整个过程只需15分钟,所有命令可直接复制粘贴,每一步都有明确反馈。

我们用的不是黑盒工具,而是一个经过验证的、结构清晰的测试镜像:测试开机启动脚本。它已预置基础环境和调试机制,让你跳过90%的兼容性踩坑环节,专注在“怎么做对”这件事上。


1. 明确目标:这个提醒程序到底要做什么

在动手前,先说清楚:我们要做的不是一个“玩具脚本”,而是一个具备生产可用性的轻量提醒工具。它的核心能力有三项,全部通过纯Shell实现,无需Python或额外依赖:

  • 声音提醒:系统启动完成后,自动播放一段语音(如“系统已就绪”),适用于本地设备或带音频输出的树莓派
  • 日志留痕:将启动时间、主机名、IP地址写入固定日志文件,方便后续排查或监控
  • 状态确认:可选检测网络连通性(ping网关或DNS),避免在网卡未就绪时误报

这三点看似简单,但组合起来,就能覆盖绝大多数“开机后需人工确认”的场景。比如:

  • 实验室里多台树莓派同时部署,靠声音快速定位哪台已启动成功
  • 家庭NAS重启后,不用SSH登录就能知道服务是否正常
  • 远程工控设备断电恢复,通过日志判断是否完成自检流程

所有功能都封装在一个不到30行的Shell脚本中,没有魔法,只有清晰逻辑。


2. 准备工作:三步搞定环境与权限

别被“开机自启”吓到——它本质只是让系统在特定时机执行你的命令。我们采用最通用、最易调试的rc.local方案(兼容Ubuntu 20.04+、Debian 11+、Raspberry Pi OS),并全程使用普通用户权限操作,仅在必要步骤提权。

2.1 确认系统支持 rc.local

现代Linux发行版默认禁用rc.local,但并未删除它。我们先检查是否存在并启用:

# 查看 rc-local.service 是否存在(存在即支持) ls /lib/systemd/system/rc-local.service 2>/dev/null && echo " rc-local.service 已存在" || echo "❌ 需手动创建" # 检查当前状态 sudo systemctl status rc-local 2>/dev/null | grep -q "active" && echo " rc-local 已启用" || echo " 将启用 rc-local"

如果输出显示❌ 需手动创建,请执行以下命令补全(仅首次需要):

sudo tee /lib/systemd/system/rc-local.service << 'EOF' [Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local [Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99 [Install] WantedBy=multi-user.target EOF

2.2 创建提醒脚本:/usr/local/bin/boot-notify.sh

我们把脚本放在系统级路径,确保所有用户均可调用。用nano(比vim更友好)编辑:

sudo nano /usr/local/bin/boot-notify.sh

粘贴以下内容(已做中文注释,可直接运行):

#!/bin/bash # 开机提醒脚本 —— 简洁、可靠、可扩展 # 功能:语音播报 + 日志记录 + 网络检测(可选) LOG_FILE="/var/log/boot-notify.log" NOW=$(date '+%Y-%m-%d %H:%M:%S') HOSTNAME=$(hostname) IP_ADDR=$(ip -4 addr show up scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1) # 1. 记录基础信息到日志 echo "[$NOW] 系统启动完成 | 主机: $HOSTNAME | IP: ${IP_ADDR:-未获取}" >> "$LOG_FILE" # 2. 检测网络(可选:取消下面两行注释以启用) # if ping -c1 -W1 192.168.1.1 &>/dev/null; then # echo "[$NOW] 网络已连通(网关可达)" >> "$LOG_FILE" # else # echo "[$NOW] 网络未就绪(网关不可达)" >> "$LOG_FILE" # fi # 3. 语音播报(仅当系统有音频设备时生效) if command -v espeak >/dev/null 2>&1; then # 使用espeak播报(树莓派默认已安装) espeak "System ready. Host name is $HOSTNAME." 2>/dev/null & elif command -v aplay >/dev/null 2>&1 && [ -f /usr/share/sounds/ubuntu/stereo/desktop-login.ogg ]; then # Ubuntu桌面版:播放系统登录音效 aplay /usr/share/sounds/ubuntu/stereo/desktop-login.ogg >/dev/null 2>&1 & fi # 4. 清理临时文件(可选) rm -f /tmp/boot-notify.lock

保存退出(Ctrl+O → Enter → Ctrl+X)。

2.3 赋予执行权限并测试

# 添加可执行权限 sudo chmod +x /usr/local/bin/boot-notify.sh # 手动运行一次,检查是否正常工作 sudo /usr/local/bin/boot-notify.sh # 查看日志是否生成 tail -n 3 /var/log/boot-notify.log

正常输出应类似:

[2024-06-15 10:23:45] 系统启动完成 | 主机: ubuntu-pc | IP: 192.168.1.105

如果听到语音或看到日志,说明脚本本身完全OK。接下来,让它真正“开机就跑”。


3. 接入开机启动:三行命令搞定

rc.local是最接近传统习惯的方案——它在所有服务启动完毕后执行,时机稳定,调试直观。我们只需把它加入启动链。

3.1 编辑/etc/rc.local

sudo nano /etc/rc.local

确保文件内容如下(注意:必须保留#!/bin/bashexit 0):

#!/bin/bash # 在 exit 0 前插入你的命令 /usr/local/bin/boot-notify.sh exit 0

关键细节:

  • 第一行#!/bin/bash不可省略,否则脚本可能无法解析变量
  • boot-notify.sh后面不要加&(它内部已用&启动语音进程,加两次会导致异常)
  • exit 0必须在最后一行,否则系统可能卡在启动界面

3.2 启用 rc-local 服务

# 重新加载 systemd 配置 sudo systemctl daemon-reload # 启用 rc-local(开机自启) sudo systemctl enable rc-local # 启动一次(立即生效,无需重启) sudo systemctl start rc-local

验证是否启用成功:

sudo systemctl is-enabled rc-local # 应输出 "enabled" sudo systemctl status rc-local | grep "Active:" # 应显示 "active (exited)"

4. 树莓派特别适配:让小板子开口说话

树莓派(Raspberry Pi 4B等)是开机提醒的最佳载体——体积小、功耗低、自带3.5mm音频口。但默认系统可能未安装语音引擎,我们补全它。

4.1 安装 espeak(轻量级TTS引擎)

# 更新源并安装 sudo apt update && sudo apt install -y espeak # 测试发音(插上耳机或音箱) espeak "Hello from Raspberry Pi" 2>/dev/null

听到清晰语音,说明音频通路正常。

4.2 优化树莓派启动体验

树莓派启动时,音频驱动加载稍晚。为避免语音失败,我们在脚本中加入简短等待:

# 修改 /usr/local/bin/boot-notify.sh,在语音播报前添加: sleep 3 # 等待音频子系统就绪

同时,为防止多次启动重复写入日志,我们增强日志逻辑:

# 替换原脚本中的日志写入部分为: if [ ! -f "$LOG_FILE" ]; then echo "=== Boot Notify Log Start ===" > "$LOG_FILE" fi echo "[$NOW] 系统启动完成 | 主机: $HOSTNAME | IP: ${IP_ADDR:-未获取}" >> "$LOG_FILE"

这样每次重启都会在日志顶部标记新会话,便于追踪。

4.3 实际效果演示

完成配置后,给树莓派断电再上电。约30秒后,你会听到:

“System ready. Host name is raspberrypi.”

同时,/var/log/boot-notify.log中新增一行:

[2024-06-15 10:42:18] 系统启动完成 | 主机: raspberrypi | IP: 192.168.1.108

这就是一个真实、可用、可验证的开机提醒闭环。


5. 故障排查:遇到问题?按这四步检查

即使最简单的脚本,也可能因环境差异出错。以下是高频问题及解法,按顺序排查:

5.1 日志没生成?检查文件权限与路径

# 确认日志目录可写 sudo mkdir -p /var/log sudo chown root:root /var/log sudo chmod 755 /var/log # 确认脚本路径正确(无拼写错误) ls -l /usr/local/bin/boot-notify.sh

5.2 语音不响?聚焦音频子系统

# 检查音频设备是否识别 aplay -l # 应列出声卡(如 bcm2835) # 测试系统音效(Ubuntu) speaker-test -t wav -l 1 # 测试espeak(树莓派) espeak "test" 2>/dev/null && echo " espeak 正常"

提示:树莓派若用HDMI输出,需强制音频到3.5mm口:
sudo amixer cset numid=3 1(1=耳机口,2=HDMI)

5.3 rc.local 不执行?验证服务状态

# 查看rc-local执行详情 sudo journalctl -u rc-local --no-pager -n 20 # 检查rc.local文件权限(必须可读) sudo ls -l /etc/rc.local # 应显示 -rwxr-xr-x

5.4 网络检测总失败?调整超时与目标

# 将ping目标改为更稳定的DNS(如阿里DNS) # 替换脚本中的 ping 命令为: ping -c1 -W2 223.5.5.5 &>/dev/null

记住:所有修改后,务必执行sudo systemctl restart rc-local生效,无需重启整机。


6. 进阶思路:让提醒更智能(可选)

这个脚本是起点,不是终点。根据你的需求,可轻松扩展:

  • 微信通知:在脚本末尾添加curl调用Server酱API,推送消息到手机
  • LED闪烁:树莓派GPIO接LED,用gpio命令控制亮灭作为视觉提醒
  • 邮件告警:集成ssmtpmsmtp,启动失败时发邮件
  • 多语言支持:用espeak -v zh切换中文播报(需sudo apt install espeak-data

所有扩展都遵循同一原则:保持主脚本简洁,新功能以独立函数形式追加,不破坏原有逻辑。

例如,添加微信通知只需三行(替换原脚本末尾):

# 微信推送(需提前注册Server酱,获取SCKEY) SCKEY="your_sckey_here" MSG="【开机提醒】$(hostname) 已启动,IP:${IP_ADDR:-N/A}" curl -s "https://sc.ftqq.com/${SCKEY}.send?text=${MSG}" >/dev/null

7. 总结:你刚刚完成了一件很有价值的事

回顾整个过程,你并没有在“折腾系统”,而是在构建一个确定性的反馈回路

  • 当硬件加电 → 系统启动 → 服务就绪 → 你收到明确信号
    这个闭环,消除了不确定性,把运维从“猜”变成了“确认”。

你掌握的不仅是几个命令,而是Linux启动机制的实用切口:
知道rc.local的真实作用时机(所有服务之后)
学会用systemctl管理传统服务(rc-local
理解脚本权限与路径规范(/usr/local/bin/是最佳实践)
具备跨平台适配能力(Ubuntu桌面、Ubuntu Server、树莓派OS)

更重要的是,这个程序已经可以交付使用——它不依赖GUI、不消耗内存、不产生后台进程,纯粹、安静、可靠。

现在,你可以把它部署到实验室的每一台设备上,让它们在清晨第一缕阳光照进窗台时,齐声说一句:“我准备好了。”

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

微调花了多少钱?成本估算参考

微调花了多少钱&#xff1f;成本估算参考 你是不是也经常看到“十分钟微调大模型”这类标题&#xff0c;心里嘀咕&#xff1a;听起来很酷&#xff0c;但真上手时&#xff0c;电费、显卡损耗、时间成本到底要多少&#xff1f;有没有一个靠谱的账本可以翻一翻&#xff1f; 这篇…

作者头像 李华
网站建设 2026/4/18 7:49:38

TurboDiffusion天气变化模拟:光影流动效果生成实战

TurboDiffusion天气变化模拟&#xff1a;光影流动效果生成实战 1. 为什么天气变化模拟特别适合TurboDiffusion&#xff1f; 你有没有试过让AI生成一段“云层缓缓聚拢、阳光从缝隙中倾泻而下、雨滴开始在玻璃窗上蜿蜒滑落”的视频&#xff1f;传统视频生成模型往往卡在细节——…

作者头像 李华
网站建设 2026/4/13 21:54:03

如何在Orange Pi 5 Plus运行EmuELEC:实战案例

以下是对您提供的博文内容进行 深度润色与结构重构后的技术文章 。我以一位长期深耕嵌入式Linux游戏终端开发的工程师视角&#xff0c;彻底重写了全文&#xff1a;去除AI腔调、打破模板化章节、强化逻辑流与实战感&#xff0c;将“原理—适配—调试—延伸”自然融合为一篇有温…

作者头像 李华
网站建设 2026/4/18 2:13:55

ESP32 IDF入门指南:如何烧录固件并查看日志输出

以下是对您提供的博文内容进行深度润色与结构重构后的专业级技术文章。整体风格更贴近一位资深嵌入式工程师在技术博客中自然、流畅、有温度的分享&#xff0c;彻底去除AI腔调和模板化表达&#xff0c;强化逻辑递进、实战细节与教学引导性&#xff0c;同时严格遵循您提出的全部…

作者头像 李华
网站建设 2026/4/15 18:34:55

基于CMSIS的数字滤波器实现完整示例

以下是对您提供的技术博文进行深度润色与重构后的版本。我以一位资深嵌入式信号处理工程师兼技术博主的身份&#xff0c;摒弃所有模板化表达、AI腔调和空泛总结&#xff0c;用真实开发中的思考节奏、踩坑经验、权衡取舍与一线手感重写全文——它不再是一篇“介绍CMSIS-DSP有多好…

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

SGLang本地部署教程:单机GPU即可运行的实操方案

SGLang本地部署教程&#xff1a;单机GPU即可运行的实操方案 1. 为什么你需要SGLang——不只是另一个推理框架 你有没有遇到过这样的情况&#xff1a;好不容易下载好一个大模型&#xff0c;想在自己机器上跑起来&#xff0c;结果发现要么显存爆了&#xff0c;要么响应慢得像在…

作者头像 李华