Uncategorized

Linuxmint/Ubuntu with Cinnamon/XFCE auto-hibernate

把 service 放到 user 目录

mkdir -p ~/.config/systemd/user
vi ~/.config/systemd/user/auto-hibernate.service

[Unit]
Description=Auto Hibernate (xprintidle)
After=graphical-session.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/auto-hibernate.sh

主脚本(关键点)

vi /usr/local/bin/auto-hibernate.sh

#!/bin/bash
#
# Auto hibernate for NAS / server style desktop
# Triggered by user systemd timer every N minutes
#

############################
# Config
############################

# GUI activity threshold (ms)
# If xprintidle < this, treat as ACTIVE immediately
GUI_THRESHOLD_MS=$((60 * 1000))          # 60 seconds

# Logical idle limit before hibernate (seconds)
LOGICAL_IDLE_LIMIT=$((4 * 60 * 60))           # 30 minutes

# Cooldown after wake (seconds)
WAKE_COOLDOWN=$((15 * 60))                # 15 minutes

# Logical idle state file
STATE_FILE="$HOME/.auto_hibernate_idle"

# Log file
LOG_FILE="$HOME/auto-hibernate.log"

############################
# Environment for xprintidle
############################

export DISPLAY=:0
export XAUTHORITY="$HOME/.Xauthority"

############################
# Logging helper
############################

log() {
    echo "[$(date '+%F %T')] $*" >> "$LOG_FILE"
}

############################
# Step 0: uptime / wake cooldown
############################

# UPTIME_SEC=$(awk '{print int($1)}' /proc/uptime)
NOW=$(date +%s)
LAST_RESUME=$(cat "$HOME/.last_resume" 2>/dev/null || echo 0)
UPTIME_SEC=$((NOW - LAST_RESUME))
if [ "$UPTIME_SEC" -lt "$WAKE_COOLDOWN" ]; then
    log "Wake cooldown active (${UPTIME_SEC}s < ${WAKE_COOLDOWN}s), reset idle"
    echo 0 > "$STATE_FILE"
    exit 0
fi

############################
# Step 1: SSH activity (human interaction)
############################

if who | grep -q pts; then
    log "SSH session detected, reset idle"
    echo 0 > "$STATE_FILE"
    exit 0
fi

############################
# Step 2: GUI activity
############################

IDLE_MS=$(xprintidle 2>/dev/null || echo 0)

if [ "$IDLE_MS" -lt "$GUI_THRESHOLD_MS" ]; then
    log "GUI active (idle ${IDLE_MS}ms < ${GUI_THRESHOLD_MS}ms), reset idle"
    echo 0 > "$STATE_FILE"
    exit 0
fi

############################
# Step 3: accumulate logical idle
############################

# Load previous logical idle
if [ -f "$STATE_FILE" ]; then
    LOGICAL_IDLE=$(cat "$STATE_FILE")
else
    LOGICAL_IDLE=0
fi

# How often this script runs (seconds)
# systemd timer should be fixed interval
INTERVAL=120

LOGICAL_IDLE=$((LOGICAL_IDLE + INTERVAL))
echo "$LOGICAL_IDLE" > "$STATE_FILE"

log "Idle accumulating: logical_idle=${LOGICAL_IDLE}s, gui_idle=${IDLE_MS}ms"

############################
# Step 4: final decision
############################

if [ "$LOGICAL_IDLE" -ge "$LOGICAL_IDLE_LIMIT" ]; then
    log "Idle limit reached (${LOGICAL_IDLE}s), hibernating"
    systemctl hibernate
fi

定时器:user timer

vi ~/.config/systemd/user/auto-hibernate.timer

[Unit]
Description=Check idle time every 5 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=2min

[Install]
WantedBy=default.target

最后启用:

systemctl --user daemon-reload
systemctl --user enable --now auto-hibernate.timer

查看状态:

systemctl --user list-timers
George

Geek for fun.

https://jimy.fun

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top