您现在的位置: 365建站网 > 365文章 > Linux 定时关机怎么设置?shutdown 时间参数、at/cron/timer 与取消方法

Linux 定时关机怎么设置?shutdown 时间参数、at/cron/timer 与取消方法

文章来源:365jz.com 点击数:11 更新时间:2025-08-13 07:44

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

Linux 定时关机 shutdown 命令与计划任务

一、shutdown 的参数结构

标准语法是:shutdown [选项] 时间 [警告信息]。关键选项:

  • -h halt,关机后停止(最常用的“关机”);-r 关机后重启。
  • -P poweroff,切断电源;-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建站器 »