Linux 定时关机怎么设置?shutdown 时间参数、at/cron/timer 与取消方法
服务器要重启补丁、开发机要夜里自动跑任务、家里 NAS 想定时休眠——这些需求在 Linux 上主要由一条命令 shutdown 完成。但它的时间参数格式、-h 与 -P 的区别、以及“如何取消一个已经安排好的关机”,是新手最容易踩的三个坑。本文按参数、场景、排错三层把它讲透。

一、shutdown 的参数结构
标准语法是:shutdown [选项] 时间 [警告信息]。关键选项:
-hhalt,关机后停止(最常用的“关机”);-r关机后重启。-Ppoweroff,切断电源;-c配合使用。注意-P是“停止时切断电源”,而-h会按系统默认策略决定是 poweroff 还是 halt。-k只发警告广播、并不真的关机,用来演练非常适合。-t 秒设置从广播到真正执行之间的宽限时间(默认 60 秒)。+分钟或HH:MM指定触发时间,这是本文的核心。now等价于+0,立即执行。
二、时间参数的三种写法
- 相对时间:
sudo shutdown -h +30—— 30 分钟后关机。数字后面不带空格,也不能写30min。 - 绝对时间:
sudo shutdown -r 02:30—— 当天(次日)凌晨 2:30 重启。若现在已是 03:00,则安排到第二天 03:00 之前,不是“立刻”。 - 立即:
sudo shutdown -h now。
想给在线用户留一句提示,直接追加字符串:sudo shutdown -h +15 "服务器将于15分钟后重启,请保存工作"。这段文字会通过 wall 广播到所有已登录终端(TTY 和 SSH 会话都能看到)。
三、查看与取消:最容易出事的环节
很多人安排完关机就忘了,等回来发现机器已经关了。正确做法是:
- 查计划:
who -b显示上次启动时间;last shutdown或last -x shutdown看历史关机记录。要看“未来”的计划,systemd 系统用systemctl list-timers看 timer,或直接cat /run/systemd/shutdown/scheduled—— 这个文件里有USEC=(微秒时间戳)和MODE=(halt/poweroff/reboot),是判断“有没有安排过关机”最可靠的证据。 - 取消:
sudo shutdown -c,后面可带一句取消说明。老式 SysVinit 系统同样支持-c。 - 反例:
killall shutdown或重启 systemd-logind 都属于强行动作,可能把系统留在中间状态,除非-c无效,否则不要用。
四、systemd 时代的等价写法
CentOS 7/RHEL 7 及之后、Ubuntu 16.04 之后,shutdown 实际是调用 systemd 的接口。等价命令:
- 立即关机:
systemctl poweroff;立即重启:systemctl reboot。 - 挂起 / 休眠:
systemctl suspend/systemctl hibernate/systemctl hybrid-sleep。 - 进入救援模式:
systemctl rescue;图形/多用户切换:systemctl isolate multi-user.target。 - 取消计划:
systemctl cancel,效果等同shutdown -c。
要设置“空闲自动关机”,可以用 systemd-inhibit 查看谁阻止了关机(常见是包管理器、备份脚本持有锁):systemd-inhibit --list。
五、需要更灵活的计划:at / cron / systemd timer
shutdown 只能表达“一个未来时刻”。跨天、周期、条件触发就换工具:
- at(一次性、最贴近人话):
sudo at now + 2 hours回车后输入shutdown -h now,再按Ctrl+D结束。也支持sudo at 03:00 tomorrow、sudo at 10:00 Jan 5。查看队列atq,删除atrm 3(前面的数字是 job 号)。前提是服务在跑:sudo systemctl start atd。 - cron(周期性):编辑
sudo crontab -e,加一行0 3 * * 6 /sbin/shutdown -h now表示每周六凌晨 3 点关机。字段顺序是「分 时 日 月 周」。测试时先改成* * * * *每分钟跑一次确认能生效,再改回去。 - systemd timer(推荐给服务化任务):写一个
nightly-off.service与同名.timer,用OnCalendar=Sat *-*-* 03:00:00表达时间,好处是可以用systemd-analyze calendar 'Sat *-*-* 03:00'先验证表达式解析出的下一次触发时间,出错概率远低于手写 cron。
注意权限边界:cron 里必须写命令的绝对路径(/sbin/shutdown 或 /usr/sbin/shutdown),因为 cron 执行环境的 PATH 极简,写成 shutdown 会出现“任务执行了但报 command not found”。用 which shutdown 先确认本机路径。
六、其它相关命令与常见故障
poweroff、halt:本质是shutdown的符号链接,可作快捷方式,但不带广播。reboot:同上。需要强制时可reboot -f,它会跳过正常服务停止流程,仅用于系统已经无响应的场景。init 0/init 6:SysV 运行级别写法,在 systemd 上仍可用(映射到poweroff.target/reboot.target),但不推荐新脚本使用。- 提示 Failed to create shutdown modulator:
systemd-logind未运行或 dbus 异常,sudo systemctl restart systemd-logind后重试。 - 到点没关机:依次排查——(1) 有没有被
systemd-inhibit列出的程序锁住;(2) 时区是否与你以为的一致,timedatectl查看,绝对时间是按本地时区解释的;(3) cron 的环境变量与路径;(4) 服务器 BIOS 里是否有断电恢复策略干扰。 - 远程 SSH 会话里安排关机后自己掉线:属正常。用
-t 120拉长宽限时间,或把命令写成nohup sh -c 'sleep 1800; shutdown -h now' &交给后台,再用shutdown -c兜底取消。
七、常见问题 FAQ
问:shutdown -h now 与 poweroff 有什么区别?
答:现代发行版上几乎没有区别,最终都走 systemd 的 poweroff.target。差别在于 shutdown 会提前广播、给在线用户留出保存时间,poweroff 则直接进入流程。
问:定时关机能不能不用 root?
答:默认不行,关机属于特权操作。如果确实要普通用户触发,可用 polkit 规则精确授权某条命令,但生产环境强烈建议只开放给运维账号。
问:虚拟机里 shutdown 卡在 “A stop job is running for ...” 90 秒怎么办?
答:某个服务停止超时。可编辑 /etc/systemd/system.conf 里的 DefaultTimeoutStopSec=10s 缩短等待(改完需 systemctl daemon-reload),根治方案仍是找到那个停不干净的服务单独处理。
问:怎么让机器每次开机后自动 N 小时关机?
答:用 systemd timer 配 OnBootSec=2h + Unit= 指向一个执行 poweroff 的服务,比在 rc.local 里塞 sleep 稳定得多。
小结:临时用 shutdown +分钟、指定时刻用 shutdown HH:MM、一次性人话计划用 at、周期任务用 cron 或 systemd timer;安排完记得用 /run/systemd/shutdown/scheduled 复核,取消就一条 shutdown -c。
生产内容,同时打通搜索引擎(SEO)与AI搜索引擎(GEO)流量入口的软件! 点击进入365建站器 »
