最近明月碰到一个 Linux 下 crontab 定时任务运行故障,本来是个非常常见的备份脚本而已(可参考【LNMP 环境下使用 Zstd 压缩优化网站备份脚本】一文),但就是在定时任务里定时运行就是不生效,生成的备份文件都是 0 字节。这个备份脚本在明月很多代维的服务器上都完美运行着,唯独这一个客户的服务器上定时任务出现问题,可以说是相当的诡异了。
昨天在跟一个客户处理【DDos/CC 攻击防御服务】的时候再次发现这个问题依旧,就想着还是解决掉为宜,毕竟不能每次备份都要自己手动运行脚本吧?(是的,单独运行脚本是没有任何问题的,就是让 crontab 定时运行就不行,诡异吧?)很明显,这不科学呀!
**管理员无敌通过/var/log/cron查看crontab日志发现,定时运行backup_zst.sh的时候出现了一个(CRON) EXEC FAILED (/usr/sbin/sendmail)的错误,排查是因为没有安装sendmail的原因,安装后这个错误提示就没有了,但脚本运行结果依旧备份出来的文件都是 0 字节,考虑到/var/log/cron只会记录是否执行了某些计划的脚本,但是具体执行是否正确以及脚本执行过程中的一些信息 Linux 会通过邮件形式发送到给用户。对于 root 用户该邮件记录位于/var/spool/mail/root,但 mail 邮件一般只会记录脚本执行成功与否,如果执行失败,无法给出进一步的错误信息,这时就需要将语句执行的错误信息重定向至文件中,这样可以很方便的查看错误信息。只需要在 crontab 里修改一下定时脚本的语句为:
0 0 * * * /bin/bash /bak/backup_zst.sh >> /tmp/mylog.log 2>&1
即可,表示把错误输出和标准输出都输出到/tmp/mylog.log中,在执行的时候会将命令执行的相关信息记录至 mylog.log 文件中。
通过修改定时时间让
crontab执行定时任务后查看 mylog.log 文件,终于发现脚本执行失败的原因了,原来是 Zstd 命令找不到造成(如上图所示)。
最后分析是升级 Zstd 压缩算法工具的时候因为路径没有在crontab需要的环境变量中造成找不到命令错误,在【Zstd(Zstandard)助力网站备份利器】一文里有专门提到,需要将 Zstd 命令复制到/usr/bin/一下来规避这个问题的,看来是在升级 Zstd 的时候给疏忽了。
正好通过这次排查也学到了一个困惑很久的排查crontab定时运行脚本错误排查难题的方法,特意总结出来给大家分享改一下,不得不说 Linux 的crontab还是非常强大的,几乎是无所不能了,基本上你能想到的都可以定时运行,反正明月是经常用,爱不释手的那种。