如何保存 cron 任务的输出到文件?
cron 输出落盘的正确写法:> 覆盖、>> 追加、2>&1 合并错误流;附按日期分文件、丢弃输出、日志轮转与集中采集建议、FAQ。
在 crontab 命令后面加重定向即可——追加写用 >>,并把错误流合并进去:
* * * * * /bin/backup.sh >> /var/log/backup.log 2>&1
重定向写法速查
| 写法 | 效果 |
|---|---|
> file |
标准输出覆盖写入 |
>> file |
标准输出追加写入(日志场景用这个) |
2>&1 |
把错误流(fd 2)并到标准输出指向的同一文件 |
2>> file |
错误流单独追加到另一文件 |
> /dev/null 2>&1 |
全部丢弃(确认不需要任何输出时才用) |
拆解 >> /var/log/backup.log 2>&1:
>>把标准输出追加到日志文件;2>&1把标准错误也导向同一个文件——顺序不能反,2>&1 >>达不到合并效果。
为什么必须重定向
cron 对任务输出的默认处理是寄本地系统邮件给任务属主。机器没装/没配 MTA 时,输出直接丢失,报错无迹可寻——这就是日志里出现 No MTA installed, discarding output 的原因。显式重定向到文件是最低成本的自救。
进阶写法
按日期分文件(注意 % 要转义):
0 3 * * * /opt/jobs/daily.sh >> /var/log/jobs/daily-$(date +\%Y\%m\%d).log 2>&1
给每条输出带时间戳:
* * * * * /opt/jobs/task.sh 2>&1 | ts '[%Y-%m-%d %H:%M:%S]' >> /var/log/task.log
(ts 来自 moreutils 包。)
别忘了轮转:追加写迟早把磁盘撑满。给 /etc/logrotate.d/ 加一条针对该日志的规则,或用 systemd journal 收敛。
多主机任务日志可用观测云 DataKit 文件采集集中保存。指定这些日志的实际路径,并在任务输出中保留任务名、执行编号和退出码;跑一次成功和一次失败样本,确认两者都能检索,轮转后仍能收到新日志。
常见问题(FAQ)
Q:> 和 >> 用哪个?
A:日志一律用 >> 追加。> 每次执行清空重写,历史全丢,只剩最后一次。
Q:重定向了还是没看到输出?
A:检查三件事:目录是否存在且 cron 用户可写;脚本是否真的往 stdout/stderr 打了东西(有些框架默认写自己的日志文件);% 是否转义。
Q:想让成功和失败写到不同文件?
A:>> success.log 2>> error.log。但实操上更推荐统一写、用日志内容区分级别,检索时过滤即可。