crontab 定时执行 Python 脚本踩坑记录
背景
换过几个云服务器,每次都要在 crontab 这折腾一会儿,这次索性把问题记录下来,力求详尽。
笔者的云服务器:腾讯云 2C4G;
Linux 系统: Ubuntu 20.04 LTS 64bit。
crontab 是 Linux 下周期性执行的指令,常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为 cron jobs。(摘自百度百科)
必备知识
1、cron 的配置文件可在三个地方存放
/var/spool/cron/crontabs/root
/etc/crontab
/etc/cron.d/
一般情况下,通过 crontab -e 命令编辑的是第一个路径下的配置文件,在这里的命令不需要指定用户为 root;后两个则需要,比如命令 0 3 * * 1 root python test.py
,其中的 root 不可少。
需要注意的是,如果使用 crontab -e 编辑,修改后使用 Ctrl+X,提示:save modified buffer ...?
,选择 :yes,又提示:file name to write
,选择:Ctrl+T,在最后一个界面使用左右箭头切换至 crontab。
2、虽然说编辑完 crontab 文件后不需要重启 cron 服务,但是包括重启在内的一些命令最好还是了解下。
- 重启,各种资料都说是 service crond restart,在笔者的环境上实测是 service cron restart;在 centos 上是 systemctl restart crond,笔者暂未考证。
- 状态,笔者亲测为 service cron start;其他环境同上。
问题记录
使用命令定时执行 python 脚本,每个小时的第 15 分钟运行一次,无任何反应。命令如下:
15 * * * * /mypath/venv/bin/python3 /mypath/monitor.py >> /mypath/execute.log 2>&1
python 脚本输出的 execute.log 亦无输出。
问题解决
第一步想着查看 crontab 的日志,才知道默认是不打开的需要手动配置。命令如下:
1 | sudo vim /etc/rsyslog.d/50-default.conf |
然后 vi /var/log/cron.log
查看日志,能够发现脚本确实运行了,除此之外没有任何有用信息,看其他博主(参考文末链接2)说是需要安装 postfix,正安装着不知道怎么配置邮件服务器的域名,又看到如果 python 脚本输出配置了重定向日志,不用配这个也行。遂作罢。
排除了 crontab 的问题,那只有是 python 脚本的问题了,偶然间发现(参考文末链接 3):python 脚本中涉及到读写文件的动作,一般定时任务都不会执行.;脚本在执行时,由于是通过 crontab 去执行的,它的执行目录会变成当前用户的根目录,如果是root,就会在/root/下执行。
但是我们读写的文件路径在 root 下吗,大概率不是,一种解决办法是将 python 脚本中的文件路径全部换成服务器绝对路径,但是这样可移植性差;更好的办法是使用 shell 脚本,shell 脚本第一行使用命令 cd 到我们的目的路径,然后第二行修改我们原来的命令(py 脚本的绝对路径也可以简化成相对路径),如下:
1 | !/usr/bin/bash |
使用 chmod a+x test.sh
赋予执行权限,然后在 crontab 配置定时运行这个 shell 脚本,
1 | 15 * * * * /bin/sh /mypath/test.sh >> /mypath/execute.log 2>&1 |
最后可能还有一个坑,查看 execute.log,发现无法 cd 到 mypath,这是因为这个 test.sh 是通过 rz 上传的,不是在服务器上通过 touch 创建的,无法识别,解决办法就在原因中,touch 创建再复制命令就行。