前言 这是一篇丢失在时间长河又突然回归的文章,被scp基金会在几个月前收容,又在2020年10月14日确认无危险性,因此回归本公众号。 参考文档: 1、【Linux定时任务Crontab命令详解】https://www.cnblogs.com/intval/p/5763929.html 2、【Linux crontab命令详解】https://www.cnblogs.com/ftl1012/p/crontab.html 3、【Linux crontab 命令】https://www.runoob.com/linux/linux-comm-crontab.html 4、【在线工具】https://tool.lu/crontab/ 正文 怎么在Linux下定时启动某个任务? 例如自动备份mysql数据库,每天更新外部接口数据? 在Linux下有个与windows下的计划任务类似的工具,即crond。 crond 是linux下一般默认安装并自启动的服务工具,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。 如果你的Linux系统中没有此服务,可以安装一下。 yum install crontabs 在Linux下的任务调度分为两类,系统任务调度和用户任务调度。 系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。 用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。所有用户定义的crontab 文件都被保存在 /var/spool/cron目录中。其文件名与用户名一致。 而使用crond的控制命令则是crontab。 什么是crontab? 首先看下cronttab的使用说明 [root@localhost ~]# crontab --help crontab:无效选项 -- - crontab: usage error: unrecognized option Usage: crontab [options] file crontab [options] crontab -n [hostname] Options: -u <user> define user -e edit user's crontab -l list user's crontab -r delete user's crontab -i prompt before deleting -n <host> set host in cluster to run users' crontabs -c get host in cluster to run users' crontabs -s selinux context -x <mask> enable debugging Default operation is replace, per 1003.2 crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。 常用参数 | 说明 – | – -u user | 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。 -e | 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe) -r | 删除目前的时程表 -l | 列出目前的时程表 查看下/etc/crontab 文件,内容如下: [root@izbp117mtgmllet9ryobawz ~]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) 分钟 # | .------------- hour (0 - 23) 小时 # | | .---------- day of month (1 - 31) 一个月中的第几天 # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... 月份 # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat 星期 # | | | | | # * * * * * user-name command to be executed 第一行SHELL变量指定了系统要使用哪个shell,这里是bash; 第二行PATH变量指定了系统执行命令的路径; 第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户。 星号(*):代表所有可能的值,如month字段为星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9” 连字符(-):连字符定义范围。例如,2000-2010 表示2000年至2010年期间的每年,包括2000年和2010年。 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。 小 结: 周和日最好不要同时用 定时任务要加注解 可以定向到日志文件或者空文件 定时任务一定是绝对路径,且目录必须存在才能出结果 crontab 服务一定要开启运行 cron表达式工具 我们有时很容易记错或弄混crontab的表达式,这时我们可以借助工具来进行验证。 在线工具:https://tool.lu/crontab/ 如每隔12小时执行一次任务: 0 */12 * * * 接下来7次的执行时间: 2020-10-14 12:00:00 2020-10-15 00:00:00 2020-10-15 12:00:00 2020-10-16 00:00:00 2020-10-16 12:00:00 2020-10-17 00:00:00 2020-10-17 12:00:00 添加cron任务 crontab -e 使用此命令会直接打开/var/spool/cron/下与用户名相同的文件,如是root,就相当于 vim /var/spool/cron/root 添加cron任务,编辑内容,按i插入(其实就是使用vi来操作文本)。 0-59/2 * * * * ls /home > home.log :wq保存。 等同于下面这个命令 echo "*/2 * * * * ls /home > home.log" >> /var/spool/cron/root 添加完crontab任务后,可使用下面命令查看任务是否添加成功 crontab -l 重启crond生效 systemctl restart crond 查看服务运行情况 systemctl status crond 等了一分钟,发现任务没有运行,我以为home.log会出现在/var/spool/cron目录下 查看下cron的运行情况 cat /var/log/cron 或 tail -fn100 /var/log/cron /var/log/cron记录了所有cron的运行记录 查看信息如下 Oct 14 10:38:01 mail CROND[25295]: (root) CMD (ls /home > home.log) You have new mail in /var/spool/mail/root 修改crontab任务 crontab -e # 打开/var/spool/cron/root 文件 # 编辑 0-59/2 * * * * ls /home > /var/log/home.log crontab -l # 查看 systemctl restart crond # 重启定时任务管理器,立即生效 观察cron记录,tail -fn100 /var/log/cron,发现执行 Oct 14 10:46:55 mail crond[29898]: (CRON) INFO (running with inotify support) Oct 14 10:46:55 mail crond[29898]: (CRON) INFO (@reboot jobs will be run at computer's startup.) Oct 14 10:47:01 mail CROND[29956]: (root) CMD (/usr/bin/ls /home > /var/log/home.log) 再查看日志,果然已经有了内容 cat /var/log/home.log 其他cron实例参考 意思是每两个小时重启一次apache 0 */2 * * * /sbin/service httpd restart 每天22:50关闭ssh服务 50 22 * * * /sbin/service sshd stop 每天7:50开启ssh服务 50 7 * * * /sbin/service sshd start 每月1号和15号检查/home 磁盘 0 0 1,15 * * /usr/sbin/fsck /home 每小时的第一分执行 /home/bruce/backup这个文件 1 * * * * /home/bruce/backup 每周一至周五3点钟,在目录/home中,查找文件名为*.xxx的文件,并删除4天前的文件。 00 03 * * 1-5 find /home "*.log" -mtime +4 -exec rm {} \; 每月的1、11、21、31日是的6:30执行一次ls命令 30 6 */10 * * ls FAQ 如果我们使用 crontab 来定时执行脚本,无法执行,但是如果直接通过命令(如:./test.sh)又可以正常执行,这主要是因为无法读取环境变量的原因。 解决方法: 1、所有命令需要写成绝对路径形式,如: /usr/local/bin/docker。 2、在 shell 脚本开头使用以下代码: #!/bin/bash source /etc/profile source ~/.bash_profile 3、在 /etc/crontab 中添加环境变量,在可执行命令之前添加命令 . /etc/profile;/bin/sh 使得环境变量生效,例如: 20 03 * * * . /etc/profile;/bin/sh /var/www/runoob/test.sh 注意事项 1、新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。 2、当crontab突然失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错tail -f /var/log/cron。 3、千万别乱运行crontab -r。它从Crontab目录(/var/spool/cron)中删除用户的Crontab文件。删除了该用户的所有crontab都没了。 4、在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义\%,如经常用的date ‘+%Y%m%d’在crontab里是不会执行的,应该换成date ‘+\%Y\%m\%d’。