家用住宅主机UPS断电自动备份关机脚本
很多家用主机(比如跑NAS、家庭服务器或开发机)都配了UPS,但万一半夜断电,UPS电量耗尽后主机还是硬关机,数据容易损坏。
这篇文章从零开始,教你写一个能在断电后自动触发数据备份、然后安全关机的脚本,全程用命令行搞定,不需要图形界面。
你需要准备什么
在动手之前,确认以下几个条件:
- 一台装了 Linux 的主机(本文以 Ubuntu 22.04 为例,其他版本命令大同小异)。
- 一台 UPS,并且通过 USB 线连接到主机(多数家用UPS都支持)。
- 主机上能上网,以便安装工具包。
- 知道你的备份数据存在哪个目录,本文假设需要备份
/home/user/data到/backup。
如果UPS还没接线,先把它接到主机USB口,然后执行 lsusb 看看有没有新增的 USB 设备,有类似“CyberPower”或“APC”的字样就说明识别了。
第一步:安装并配置 UPS 监控软件
最常用的工具是 NUT(Network UPS Tools)。
它让Linux能读取UPS状态,并在断电时执行预设动作。
安装命令如下:
sudo apt update
sudo apt install nut nut-client nut-snmp # 如果只是简单家用,前两个就够了
安装完成后,需要配置两个关键文件:
1. 编辑 /etc/nut/ups.conf,告诉NUT你的UPS型号。
如果是常见USB型号(比如CyberPower CP1000AVRLCD),写入:
[myups]
driver = usbhid-ups
port = auto
desc = "Home UPS"
2. 启动UPS驱动程序并设置开机自启:
sudo systemctl enable nut-server
sudo systemctl start nut-server
然后用 upsc myups 查看UPS状态,如果能显示 battery.charge: 100 就说明连接成功。
第二步:编写自动备份与关机脚本
在 /usr/local/bin 下创建一个脚本,起名 ups-shutdown.sh,内容如下:
#!/bin/bash
# UPS断电后自动备份关键数据并安全关机
LOG="/var/log/ups-shutdown.log"
echo "$(date): UPS 断电,开始关机前备份" >> $LOG
# 写入你的备份命令,这里示例将 /home/user/data 压缩到 /backup
rsync -av /home/user/data /backup/ 2>> $LOG
# 备份完成后等待10秒让日志刷完
sync
sleep 10
# 通知所有用户,然后关机
echo "UPS 电量即将耗尽,系统将在30秒后关闭。" | wall
shutdown -h +0.5 "UPS 断电保护,系统即将关机"
赋予执行权限:
sudo chmod +x /usr/local/bin/ups-shutdown.sh
注意:脚本里的 rsync 路径、备份目标目录请根据你自己的环境修改。
如果要去掉 wall 命令的烦人提示,可以删除那一行。
第三步:设置NUT自动触发脚本
NUT 通过 upsmon 来监控UPS状态。
在 /etc/nut/upsmon.conf 里配置什么时候执行关机脚本。
找到这几行(可能被注释),修改或添加:
MONITOR myups@localhost 1 admin secret master
SHUTDOWNCMD "/sbin/shutdown -h +0.5"
NOTIFYCMD /usr/local/bin/ups-shutdown.sh
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
关键点:NOTIFYCMD 指定了当UPS进入电池供电(ONBATT)时执行的脚本;NOTIFYFLAG 告诉NUT不仅要写日志、发广播,还要执行脚本。
重启NUT服务:
sudo systemctl restart nut-monitor
避坑指南
1. 脚本没执行?先检查权限和路径
- 确认
/usr/local/bin/ups-shutdown.sh有可执行权限。 - 确认
upsmon.conf中NOTIFYCMD的路径写对了。 - 查看日志
/var/log/syslog或journalctl -u nut-monitor,看看有没有报错。
2. 备份命令失败?提前测试
手动执行一下脚本里的备份命令,确认能跑通。
比如 rsync -av /home/user/data /backup/ 可以先加 --dry-run 测试。
3. 断电后UPS电量很快耗尽,脚本没跑完?
建议在脚本开头增加电量判断:只有当电量低于 15% 时才做备份+关机,避免电量充足时直接关机。
但家用场景一般断电后UPS至少撑几分钟,默认足够完成备份。
4. 需要图形界面设置定时任务?
本方案用的是NUT被动触发,不是cron定时任务。
如果你更习惯cron,也可以写一个每5分钟检查UPS电量的脚本,但不如NUT实时。
新手建议用上述NUT方案,更省心。
如何验证脚本是否生效
方法一:模拟断电测试(不推荐直接拔电源)
如果你的UPS支持,在NUT中强制进入电池供电模式:
upsdrvctl -u root test shutdown
或者直接用 upsmon -c fsd 模拟掉电。
不过请注意,这样会触发真实关机,建议先注释掉 SHUTDOWNCMD,只测试脚本执行。
方法二:查看日志
等真实停电后,检查 /var/log/ups-shutdown.log,看是否有关机前备份的记录。
方法三:观察系统正常关机
你可以主动断开UPS电源(注意:主机仍由UPS供电,断开市电不会瞬间关机),等待UPS电量下降到临界值,主机自动执行脚本并关机。
确认下次开机时数据完整。
常见问题解答
Q:其他Linux发行版能用同样的脚本吗?
A:安装命令稍有不同,CentOS用yum/dnf,但NUT的配置文件结构基本一样。
Q:我的UPS不在NUT支持的列表里怎么办?
A:NUT官方驱动支持绝大多数USB HID协议的UPS,先试 lsusb 看厂商ID,再搜索 nut compat list 确认。没列出的也常有通用驱动。
Q:我想先备份到云盘再关机,脚本里能加吗?
A:完全可以,在 rsync 后面加上 rclone sync 等云备份命令即可,但注意网络是否还通(断电后路由器可能还能工作几分钟)。
如果你按照本文步骤配下来,基本能做到下次断电时自动备份并安全关机。
遇到任何报错,优先检查日志文件和文件权限,再对照避坑指南排查。
熟练之后还可以根据自己的数据量调整备份策略。