一、crontab简介
crontab是Unix和Linux用于设置需要周期性被执行的指令,是Linux服务器很常用的技术,很多任务都会设置在crontab循环执行。
如果不使用crontab,那么任务就是常驻程序,这对你的程序要求比较高,一个要求你的程序是24X7小时不宕机,一个是要求你的调度程序比较可靠。
实际工作中,90%的程序都没有必要花这么多时间和精力去解决上面的两个问题的,只需要写好自己的业务逻辑,通过crond这个工业级程序去调度就行了。crond的可靠性,健壮性,大家应该心里有数。
crond : 控制周期性任务计划调度的后台进程,daemon。
crontab : 提供给用户控制任务计划的命令,创建、删除、编辑任务计划等。
该命令从标准输入设备读取指令,并将其存放于“crontab”文件中(/var/spool/cron/以用户命名的文件),以供之后读取和执行。
二、问题背景
在 CentOS上设置了一个 crontab 的定时任务,每天凌晨2点执行一个数据库备份脚本。
# su - mysql
$ crontab -u mysql -l
#########################################################
* 2 * * * /usr/local/mysql/bin/mysql_backup.sh & > /dev/null 2>&1
#########################################################
早上检查定时任务执行日志,发现并没有成功执行,报错 "mysqldump: 未找到命令" 。
因为不是在 root 用户下安装的mysql,是在mysql 用户下,然后一开始没注意,应该是用 root 用户配置的定时任务,导致定时任务找不到 mysqldump,这个可以理解,但是当我在 mysql用户下,手动执行mysqldump备份脚本没问题,重新配置了定时任务,发现还是报同样的错误。
三、解决办法
经过查阅得知,crontab 有自己的环境变量配置,在 /etc/crontab 文件中,并不会自动加载当前用户的环境变量,所以在执行命令之前,应该先配置好环境变量。
在/home/mysql/.bash_profile
export PATH=/usr/local/mysql/bin/:$PATH
那么,在 crontab 执行用户下,执行命令前先载入环境变量:
#######################################################################################
* 2 * * * source $HOME/.bash_profile && /usr/local/mysql/bin/mysql_backup.sh & > /dev/null 2>&1
#######################################################################################
如果直接修改 /etc/crontab 文件
这样不行,因为这样只是指定了运行的用户,并没有修改 环境变量,倒不如在当前用户下添加定时任务,同时修改环境变量。
修改完之后,最好执行命令 sudo systemctl restart crond.service 使立即生效。
四、设置crontab的两种方法
以相应的用户交互式设置
# crontab -e
$ crontab -e
##############################################
*/5 * * * * /path/to/shell.sh args > /dev/null 2>&1
###############################################
以相应的用户非交互式设置
# (crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/shell.sh args") | crontab -
$ (crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/shell.sh args") | crontab -
注:使用这种方式可用 crontab -u root -l 直接查看设置的定时任务。
# crontab -u USER_NAME -l
添加任务到配置文件 /etc/crontab
注:使用/etc/crontab 添加定时任务,那么 使用 crontab -u USER_NAME -l 无法直接显示用户的定时任务,无法检查定时任务的语法。
使用 crontab -e 添加定时任务,无需指定用户
##############################################
*/5 * * * * /path/to/shell.sh args> /dev/null 2>&1
###############################################
使用 /etc/crontab 添加定时任务,需指定用户
五、参考
https://www.jianshu.com/p/98542ad49a60
https://zcdll.github.io/2018/01/30/own-crontab
http://blog.51cto.com/skypegnu1/1428632