为什么用 at 而不是自己等
需要临时在某个时间点执行一次操作(改配置、夜里重启服务、半小时后回滚)时,不要留在 SSH 会话里干等:把操作写成幂等脚本交给 at 排队,时间一到由守护进程执行,即使会话断开也不受影响。脚本里要有日志与健康检查,任务结束后能凭日志判断成败,而不是靠印象。
基本信息
| 适用平台 | Linux(需要安装 at 并运行 atd 服务) |
|---|---|
| 常用命令 | at -m -f 脚本 时间、atq 查看队列、atrm 删除任务 |
| 依赖服务 | atd(用 systemctl enable --now atd 启动并开机自启) |
| 时间写法 | 03:00、now + 1 hour、tomorrow 等自然写法 |
| 留痕方式 | -m 在任务完成时发邮件;更可靠的是脚本内重定向日志 |
典型使用场景
- 夜间低峰重启服务或切换版本
- 半小时后自动回滚配置(先改后观察再决定)
- 一次性数据迁移或清理
- 临时打开调试开关并到点关闭
- 维护窗口里错开多个操作的执行顺序
幂等维护脚本与提交
幂等维护脚本与提交
#!/usr/bin/env bash
set -euo pipefail
exec >> /var/log/maint.log 2>&1 # 统一留痕
echo "$(date -Is) maint start"
systemctl restart app.service
for i in $(seq 1 30); do curl -fsS http://127.0.0.1:8080/health && break; sleep 2; done
echo "$(date -Is) maint done"
chmod +x /opt/scripts/maint-restart.sh
at -m -f /opt/scripts/maint-restart.sh 03:00 # 提交到队列
sudo systemctl enable --now atd # at 依赖 atd 服务
atq # 查看待执行任务
atrm 7 # 取消编号 7 的任务
at -m -f /opt/scripts/rollback.sh now + 30 minutes # 半小时后回滚
tail -n 20 /var/log/maint.log # 到点后验收结果常用操作
| 操作 | 命令 | 注意 |
|---|---|---|
| 提交一次性任务 | at -m -f 脚本 时间 | 时间支持 03:00、now + 1 hour 等写法 |
| 查看队列 | atq | 确认任务已登记且时间正确 |
| 删除任务 | atrm 编号 | 编号来自 atq 的输出 |
| 依赖服务 | atd 必须运行 | 用 systemctl enable --now atd 保证开机自启 |
| 留痕 | 脚本内重定向到日志文件 | 比依赖邮件通知更可靠 |
| 避免撞车 | 脚本加并发保护 | 与定时备份等任务错开窗口 |
关键操作前留好回滚:改配置类任务先复制备份,重启类任务确认健康检查地址与超时时间;脚本保持幂等,才能在出问题时安全重跑。
维护脚本没有并发保护时可能与 cron 任务撞车(例如备份还在进行就重启服务):窗口要错开,必要时在脚本里加锁。