当前位置: 首页 > news >正文

Ubuntu 24.04环境下的挂起转休眠

       使用systemd的sleep钩子实现的电源管理脚本,合盖首先是挂起,5分钟检查电源状态如果是电池供电则进行休眠,否则还是挂起。系统需已经支持休眠,可执行systemctl hibernate查看休眠是否已启用。

       脚本如下,需放到/usr/lib/systemd/system-sleep下,并有执行权限。

#!/bin/bashLOG_FILE="/tmp/smart-suspend.log"
WAKEUP_TIME_FILE="/var/run/suspend-wakeup-time"
SUSPEND_MODE_FILE="/var/run/suspend-mode"# 确保日志文件可写入
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"echo "==========================================" >> "$LOG_FILE"
echo "$(date): systemd-sleep hook: $1 $2" >> "$LOG_FILE"# 函数:检查是否是RTC唤醒
is_rtc_wakeup() {# shell function return 0 is true 1 is false# 检查alarm_IRQ状态if [ -f "/proc/driver/rtc" ]; thenRTC_INFO=$(cat /proc/driver/rtc)ALARM_IRQ=$(echo "$RTC_INFO" | grep -oP 'alarm_IRQ\s*:\s*\K(yes|no|true|false|[01])')echo "$(date): Raw alarm_IRQ value: '$ALARM_IRQ'" >> "$LOG_FILE"case "$ALARM_IRQ" inyes|true|1)echo "$(date): Detected RTC wakeup (alarm_IRQ positive)" >> "$LOG_FILE"return 1;;no|false|0)echo "$(date): No RTC wakeup (alarm_IRQ negative)" >> "$LOG_FILE"return 0;;*)echo "$(date): Unknown alarm_IRQ format: '$ALARM_IRQ'" >> "$LOG_FILE"return 0;;esacfi# 备用检查方法if [ -f "/sys/class/rtc/rtc0/device/power/wakeup" ]; thenWAKEUP_STATUS=$(cat "/sys/class/rtc/rtc0/device/power/wakeup")if [ "$WAKEUP_STATUS" = "enabled" ]; thenecho "$(date): Fallback check: RTC wakeup enabled" >> "$LOG_FILE"return 1fifireturn 0
}case "$1" inpre)# 挂起之前执行if [ "$2" = "suspend" ]; then# 检查是否需要设置RTC唤醒if [ ! -f "$SUSPEND_MODE_FILE" ]; thenecho "$(date): First suspend - setting RTC wakeup in 5 minutes" >> "$LOG_FILE"echo "rtc_wakeup" > "$SUSPEND_MODE_FILE"# 设置RTC唤醒(5分钟后)WAKEUP_TIME=$(($(date +%s) + 300))echo "$WAKEUP_TIME" > "$WAKEUP_TIME_FILE"rtcwake -m no -s 300echo "$(date): RTC wakeup scheduled at $(date -d @$WAKEUP_TIME)" >> "$LOG_FILE"elseecho "$(date): Continuing suspend without RTC wakeup" >> "$LOG_FILE"# 这是继续挂起,不设置RTC唤醒fifi;;post)# 恢复之后执行if [ "$2" = "suspend" ]; thenecho "$(date): Resumed from suspend" >> "$LOG_FILE"# 等待系统稳定sleep 2# 检查唤醒原因IS_RTC_WAKEUP=falseif is_rtc_wakeup; thenIS_RTC_WAKEUP=trueecho "$(date): Confirmed RTC wakeup" >> "$LOG_FILE"elseecho "$(date): Not RTC wakeup (likely user wakeup)" >> "$LOG_FILE"fi  if [ -f "$SUSPEND_MODE_FILE" ] && [ -f "$WAKEUP_TIME_FILE" ]; thenSUSPEND_MODE=$(cat "$SUSPEND_MODE_FILE")SCHEDULED_TIME=$(cat "$WAKEUP_TIME_FILE")CURRENT_TIME=$(date +%s)TIME_DIFF=$((CURRENT_TIME - SCHEDULED_TIME))echo "$(date): Scheduled: $(date -d @$SCHEDULED_TIME), Current: $(date -d @$CURRENT_TIME)" >> "$LOG_FILE"echo "$(date): Time difference: $TIME_DIFF seconds" >> "$LOG_FILE"echo "$(date): RTC wakeup detected: $IS_RTC_WAKEUP" >> "$LOG_FILE"# 判断是否是RTC定时唤醒if [ "$TIME_DIFF" -ge -30 ] && [ "$TIME_DIFF" -le 30 ] && $IS_RTC_WAKEUP; thenecho "$(date): Woke up by RTC timer" >> "$LOG_FILE"# 检查当前电源状态if on_ac_power; thenecho "$(date): On AC power - preparing to resume suspend" >> "$LOG_FILE"# 修改挂起模式标记,表示这是继续挂起echo "continue_suspend" > "$SUSPEND_MODE_FILE"# 清除RTC时间文件但保留模式标记rm -f "$WAKEUP_TIME_FILE"# 使用正确的时间格式echo "$(date): Resuming suspend without RTC" >> "$LOG_FILE"echo "systemctl suspend" | at now + 0 min 2>/dev/nullelseecho "$(date): On battery power - switching to hibernate" >> "$LOG_FILE"# 清除所有状态rm -f "$SUSPEND_MODE_FILE" "$WAKEUP_TIME_FILE"# 转为休眠echo "systemctl hibernate" | at now + 0 min 2>/dev/nullfielseecho "$(date): Woke up by user (not RTC timer) - cleaning up" >> "$LOG_FILE"# 用户提前唤醒,清除所有状态rm -f "$SUSPEND_MODE_FILE" "$WAKEUP_TIME_FILE"rtcwake -m disablefielseecho "$(date): Normal resume or state inconsistent - cleaning up" >> "$LOG_FILE"rm -f "$SUSPEND_MODE_FILE" "$WAKEUP_TIME_FILE"fifi;;
esacecho "$(date): systemd-sleep hook completed" >> "$LOG_FILE"

http://www.dtcms.com/a/494422.html

相关文章:

  • 【从0开始学习Java | 第21篇】网络编程综合练习
  • OpenCL初级教程
  • 【Spring AI】基于 sse 实现 MCP Server
  • vue使用限制仅允许上传 Excel 文件
  • dataease开发环境搭建
  • 一个网站开发周期wordpress导航条
  • 湖南城乡建设厅网站夜蝶直播app
  • list,咕咕咕!
  • iOS 混淆实战,多工具组合完成 IPA 混淆与加固(源码 + 成品 + 运维一体化方案)
  • Vue + Element UI 实现 el-scroll 滚动与鼠标滚轮监听全攻略
  • vue2版本的ruoyi-ui中使用vxe-table插件
  • 全国建设网站郑州seo优化公司
  • 用观察者模式通知UI刷新数据
  • 基于 AI 大模型的 UI 元素定位浏览器插件
  • Prism框架核心对象全解析
  • 阿里云服务器上部署Mosquitto
  • Android 设计模式实战手册(Kotlin 实战版)
  • Android thermal (5)_cooling device(下)
  • 活字格低代码平台实现移动端应用(安卓 /iOS)打包的技术方案与实践指南
  • SpringBoot电子商城系统
  • 解析 Qt Remote Objects:从框架原理到 Repcs 实践,以正点原子 RK3588 UI 系统为例
  • 【底层机制】【Android】Binder架构与原理
  • 揭阳市住房和城乡建设局网站网站类游戏网站开发
  • DeviceNet 转 MODBUS TCP罗克韦尔 ControlLogix PLC 与上位机在汽车零部件涂装生产线漆膜厚度精准控制的通讯配置案例
  • 【STM32项目开源】基于STM32的智能衣柜系统
  • python基于web的汽车班车车票管理系统/火车票预订系统/高铁预定系统 可在线选座
  • ssh终端管理多个k8s集群,快速切换配置
  • 景德镇建站公司全国建筑四库一平台
  • 奥运网站模板wordpress在 分栏
  • toLua[七] Examples 06_LuaCoroutine2分析