起因
Crontab 是类Unix 操作系统下基于时间的任务管理器,被广泛应用在各种场景下。但 crontab 任务有时会出现一些奇怪的错误。这周在写的一个 node 图像处理定时脚本没有按照预期执行,但是报错内容跟 cron 没有关系,而且不使用 cron ,直接 run 也没有问题。
从症状上来看,大概率环境变量的原因导致的。通过单步调试,最终定位到是一个第三方库里用到 cross-spwan 执行了一个命令 gm,但这个第三方库并没有对没找到 gm 命令的错误情况进行处理。
找到了原因之后,就开始用 where gm 来找到 gm 命令的位置,在执行脚本或者 crontab 配置文件头部中声明PATH ,cron 就可以正常运行了。
总结
cron 是一个非常成熟的工具,一般出现没有按照预期运行的,可以按照以下几个思路去排查。
环境变量
cron 中的环境变量可能和系统中的是不一样的,我们需要验证来确定,可以使用
* * * * * env > /tmp/env.output
将环境变量打印输出到 /tmp/env.output,将 env.output 的内容与终端中直接执行 env 得到的环境变量进行比较就可以知道有哪些区别了。比如前面遇到的这个问题,也是通过这样的方式确定 gm 在 cron 的环境变量中不存在。
解决方法
可以在 crontab file 或者 shell 脚本的文件顶部声明正确的 PATH 变量,区别在于 crontab file 中声明的 PATH 对文件中所有 cron 任务都适用。
cron 守护进程
需要注意 cron 守护进程是否启动,输入 pgrep cron,如果没有显示数字(cron 的 pid),则说明 cron 的守护进程没有启动。
解决方法
可以使用 sudo systemctl start cron 来启动。
cron 换行符
Crontab file 是否以空行结束。
解决方法
检查 crontab file ,并在末尾加上换行。
权限问题
非root用户执行 cron,需要注意权限问题,cron 用户对操作的文件或目录是否存在权限,如果权限不够,则 cron 会拒绝执行。
解决方法
最好不要把所有任务全部使用 root 权限执行,这样虽然看起来规避了问题,引发了更多关于权限管理的问题。 具体命令参考cron - cannot access crontab after changing uid - Ask Ubuntu
以上总结了几个遇到过的关于 cron 的问题,希望给大家提供一些排错思路。