Ubuntu闲置自动关机需用系统级机制而非TMOUT;推荐cron配合xprintidle检测空闲并调用shutdown,或虚拟机中启用宿主机空闲策略。

Ubuntu系统闲置时自动关机,和终端闲置自动关闭是两回事:前者是整机断电,后者只是关掉一个 shell 会话。直接设 TMOUT 对系统关机完全无效,必须用系统级定时/事件机制。
用 cron 设置基于时间的自动关机
这是最通用、兼容性最好的方案,适合桌面和服务器环境。关键点在于:关机命令必须以 root 权限执行,且不能依赖用户会话。
- 运行
sudo crontab -e编辑系统级 crontab(避免用普通用户 crontab,/sbin/shutdown会被拒绝) - 添加一行,例如每天凌晨 2 点关机:
0 2 * * * /sbin/shutdown -h now - 若想“闲置”而非“固定时间”,需配合脚本检测空闲状态(见下一条)
- 注意:cron 不感知用户活动,它只按时间跑;所谓“闲置关机”,本质是“在用户长时间未操作后,由脚本判断并触发关机”
检测用户空闲后触发关机(推荐方案)
真正的“闲置关机”需要判断用户是否真没操作——比如键盘、鼠标无输入,且无活跃图形会话或 SSH 连接。Ubuntu 桌面默认用 gnome-session,可借助 loginctl 和 xprintidle。
- 先安装空闲检测工具:
sudo apt install x11-utils(提供xprintidle) - 写一个检测脚本,如
/usr/local/bin/check-idle-shutdown:
#!/bin/bash # 检测当前图形会话是否空闲超过 30 分钟(单位:毫秒) IDLE_MS=$(xprintidle 2>/dev/null) if [ -n "$IDLE_MS" ] && [ "$IDLE_MS" -gt 1800000 ]; then # 检查是否有其他用户登录或 SSH 会话 if ! loginctl list-sessions --no-legend | grep -q "seat"; then /sbin/shutdown -h now "System idle for 30 minutes" fi fi
- 给脚本加执行权限:
sudo chmod +x /usr/local/bin/check-idle-shutdown - 用
sudo crontab -e每 5 分钟检查一次:*/5 * * * * /usr/local/bin/check-idle-shutdown - 注意:
xprintidle只对当前 X11 会话有效;Wayland 用户需改用dbus-monitor监听org.gnome.ScreenSa ver信号
虚拟机场景下更稳妥的替代方案
如果你在 VirtualBox 或 VMware 中运行 Ubuntu 虚拟机,宿主机通常已提供“空闲关机”策略,比 guest 内部实现更可靠。
- VirtualBox:启用“自动捕获键盘”+“空闲超时”设置(在 VM 设置 → 系统 → 加速 → “启用空闲超时”)
- VMware Workstation:在虚拟机设置 → 选项 → 电源 → 勾选“当客户机空闲时挂起”或“关机”
- 这样可绕过 guest 系统中 GUI 会话检测的复杂性,也避免因屏保、锁屏导致误判
实际上,真正的难点并非在于“如何编写命令”,而是在于如何精准定义“闲置”的概念:究竟是指无人触碰键盘鼠标?还是不存在活跃的SSH连接?亦或是所有TTY都没有登录用户?在不同的应用场景中,loginctl、who、systemctl list-units --type=service --state=active 这些命令的组合逻辑会全然不同——千万不要直接抄袭脚本,而是应该先用 loginctl show-session $(loginctl | grep -m1 'seat' | awk '{print $1}') 来清晰地了解你当前会话的实际状态。