最稳妥的Linux定时关机方案是用root权限编辑crontab,添加绝对路径的/sbin/shutdown -h +0命令并重定向日志;普通用户无权执行关机,sudo在cron中会因缺少TTY而失败,now参数在部分发行版中不可靠,应使用+0,shutdown -c无法取消cron触发的关机任务。

直接用 cron 配合 /sbin/shutdown 是最稳妥、最通用的系统级定时关机方案。其他方式要么不持久(shutdown -h +30)、要么不跨重启(at)、要么过度复杂(systemd timer),对“每天固定时间关机”这类需求,cron 就是标准答案。
为什么必须编辑 root 的 crontab
普通用户没有权限调用关机命令,shutdown -h 会直接拒绝执行。即使你用 sudo 在终端里能跑通,cron 环境里不会读取你的用户 shell 配置,sudo 权限也不会自动继承。
- 必须运行
sudo crontab -e,而不是crontab -e - 不能写
sudo /sbin/shutdown -h now—— cron 里sudo会卡在密码输入环节,直接失败 - 路径必须用绝对路径:
/sbin/shutdown,不能只写shutdown;cron 的PATH极窄,找不到命令就静默失败
crontab 规则里该用 now 还是 +0
now 在 cron 里不可靠,部分发行版(如 Debian 12+、UOS 20)的 cron 环境下会报错或忽略。真正安全的写法是 +0,它明确表示“0 分钟后执行”,等价于立即关机,且兼容所有主流 Linux 发行版。
- ✅ 推荐:
0 23 * * * /sbin/shutdown -h +0(每天 23:00 关机) - ❌ 避免:
0 23 * * * /sbin/shutdown -h now(可能失败,无提示) - 别信“
now更直观”——直观不等于可用,实测失败率高
如何验证和调试 cron 关机任务
cron 不报错、不弹窗,任务失败时只会默默丢弃输出。没加日志重定向,等于“设了等于没设”。
- 务必追加日志:例如
0 23 * * * /sbin/shutdown -h +0 >> /var/log/shutdown.log 2>&1 - 检查 cron 是否运行:
systemctl status cron(Ubuntu/Debian)或systemctl status crond(CentOS/RHEL) - 手动触发测试:
sudo run-parts --report /etc/cron.hourly类似方式模拟,但更简单的是临时改时间为 1 分钟后,观察日志是否写入 -
sudo crontab -l只显示内容,不校验语法;错一个空格、多一个字母,整行就失效
shutdown -c 能否取消 cron 触发的关机
不能。shutdown -c 只能取消由当前 shell 直接发起的、尚未执行的 shutdown 计划(比如你刚输完 sudo shutdown -h +20)。cron 是独立进程 fork 出来的子进程,它的 shutdown 是全新的一次调用,shutdown -c 对它完全无效。
- 要停掉 cron 关机任务,唯一办法是编辑
sudo crontab -e,删掉或注释掉对应行 - 改完保存后,cron 会自动加载,无需重启服务
- 如果已到触发时间且关机开始倒计时(比如看到 “System shutdown in 60 seconds”),
shutdown -c仍可生效 —— 但这是 shutdown 进程自身的倒计时,不是 cron 的问题
真正容易被忽略的点是:cron 任务一旦写错,它不会提醒你,也不会留下痕迹。你得自己加日志、自己查服务状态、自己用 run-parts 或改时间测试。没人替你兜底。


















