Network UPS Tools upssched-cmd脚本时序与功能配置求助
NUT upssched-cmd 脚本优化方案
前置配置要求
- 先在DietPi的NUT服务账户(通常为nut用户)下配置SSH免密登录到RPi和EdgeRouter:执行
ssh-keygen生成密钥后,把公钥上传到两个设备对应用户的~/.ssh/authorized_keys文件中 - 在RPi和EdgeRouter上配置对应用户的sudo免密权限:编辑
sudoers文件,分别添加ControllerUser ALL=(ALL) NOPASSWD: /sbin/halt、RouterUser ALL=(ALL) NOPASSWD: /sbin/shutdown规则,避免执行关机命令时要求输入密码 - 确认EdgeRouter的关机命令有效性,EdgeOS默认关机命令为
sudo shutdown now
现有脚本问题修正
- 未定义
UPSNAME、HOST系统变量,执行时会出现空值报错 - FSD阶段命令顺序错误:先执行RPi的halt命令后,后续发往RPi的日志指令会执行失败
- 缺少lowbatt到FSD的60秒倒计时触发逻辑,需要配合upssched.conf实现
- commbad阶段message变量为空,会导致日志写入异常
- SSH命令缺少超时配置,设备离线时会卡住脚本执行
优化后完整脚本
#! /bin/sh # 基础配置项 ssh_host1='ControllerUser@ControllerIP' ssh_host2='RouterUser@RouterIP' SSH_OPTS='-o ConnectTimeout=10 -o StrictHostKeyChecking=no' UPS="apc" UPSNAME="APC UPS" # 替换为你的UPS自定义名称 HOST=$(hostname) # 状态采集 STATUS=$(upsc $UPS ups.status 2>/dev/null || echo "UNKNOWN") CHARGE=$(upsc $UPS battery.charge 2>/dev/null || echo "0") CHMSG="[$STATUS]:$CHARGE%" logger -i -t upssched-cmd "Calling upssched-cmd $1" case $1 in onbatt) message="UPS ${UPSNAME}检测到市电中断,已切换到电池供电!" echo -e "警告:UPS $UPSNAME 发生市电中断,当前剩余电量${CHARGE}%" | mail -s "警告:$message" root remote_cmd="log warning message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" ;; online) message="UPS ${UPSNAME}市电恢复" echo -e "通知:UPS $UPSNAME 市电已恢复,当前剩余电量${CHARGE}%" | mail -s "通知:$message" root remote_cmd="log info message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" ;; lowbatt) message="UPS ${UPSNAME}电池电量低,系统将在60秒后关闭!" echo -e "警告:UPS $UPSNAME 电池电量低,所有关联设备即将关机,当前剩余电量${CHARGE}%" | mail -s "警告:$message" root remote_cmd="log warning message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" # 关机指令在这里执行,不需要等FSD ssh $SSH_OPTS $ssh_host1 'sudo halt' & ssh $SSH_OPTS $ssh_host2 'sudo shutdown now' & ;; fsd) message="UPS ${UPSNAME}触发强制关机" echo -e "警告:UPS $UPSNAME 强制关机指令已触发,本机即将关闭" | mail -s "警告:$message" root # 这里执行本机关机,UPS会在所有负载关闭后自动重启 /sbin/halt ;; commok) message="与UPS ${UPSNAME}的通信恢复" echo -e "通知:与UPS $UPSNAME 的通信已恢复" | mail -s "通知:$message" root remote_cmd="log info message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" ;; commbad) message="与UPS ${UPSNAME}的通信中断" echo -e "警告:与UPS ${UPSNAME}的通信中断,无法监控UPS状态!" | mail -s "警告:$message" root remote_cmd="log warning message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" ;; replbatt) message="UPS ${UPSNAME}需要更换电池" echo -e "警告:UPS $UPSNAME 电池健康度异常,请更换电池" | mail -s "警告:$message" root remote_cmd="log warning message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" ;; nocomm) message="无法连接到UPS ${UPSNAME}进行监控" echo -e "警告:无法连接到UPS $UPSNAME,监控功能失效" | mail -s "警告:$message" root remote_cmd="log warning message=\"${message}\"" ssh $SSH_OPTS $ssh_host1 "$remote_cmd" ;; *) logger -t upssched-cmd "未识别的指令: $1" ;; esac [ -n "$message" ] && logger -i -t upssched-cmd "$message"
配套upssched.conf配置
需要修改/etc/nut/upssched.conf添加以下规则,实现lowbatt触发后60秒启动FSD,市电恢复后自动取消倒计时:
AT LOWBATT apc START-TIMER fsd 60 AT ONLINE apc CANCEL-TIMER fsd
配置完成后重启nut-server和upssched服务生效。
内容的提问来源于stack exchange,提问作者Fireman1224
相关产品推荐
相关产品推荐

