用测试脚本做了个开机提醒程序,附完整过程
你有没有过这样的经历:早上急着出门,电脑还在后台跑着重要任务,却忘了设置提醒?或者远程服务器重启后,不确定某个关键服务是否已就绪?其实,一个轻量、可靠、不依赖图形界面的开机提醒程序,就能解决这类问题——它能在系统启动完成的第一时间,用最直接的方式告诉你:“我醒了”。
本文不讲抽象理论,不堆砌术语,只带你从零开始,亲手打造一个真正能用的开机提醒程序。它不依赖桌面环境,不占用大量资源,支持声音播报、日志记录、网络状态检测,且适配主流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/bash和exit 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.sh5.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-x5.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命令控制亮灭作为视觉提醒 - 邮件告警:集成
ssmtp或msmtp,启动失败时发邮件 - 多语言支持:用
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/null7. 总结:你刚刚完成了一件很有价值的事
回顾整个过程,你并没有在“折腾系统”,而是在构建一个确定性的反馈回路:
- 当硬件加电 → 系统启动 → 服务就绪 → 你收到明确信号
这个闭环,消除了不确定性,把运维从“猜”变成了“确认”。
你掌握的不仅是几个命令,而是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),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。