我已经在crontab上栽了很多次跟头了,我决定写个总结。

常用的命令

  1. crontab -l # 显示计划任务脚本
  2. crontab -e # 编辑计划任务

计划任务的格式

C1ECD8AA-0224-4578-9C1C-8C525C2A0BCC.png

时间格式

  1. * # 每个最小单元
  2. / # 时间步长,每隔多长时间执行 */10
  3. - # 区间,如 4-9
  4. , # 散列,如 4,9,10

几个例子

crontab 最小支持的时间单位是1分钟,不支持每个多少秒执行一次

  1. # 每分钟执行
  2. * * * * * cmd
  3. # 每小时的15,45分钟执行
  4. 15,45 * * * * cmd
  5. # 每个周一到周五,早上9点到下午6点之间,每隔15分钟喝一次水
  6. */15 9,18 * * 1-5 喝水

每个X秒执行

crontab的默认最小执行周期是1分钟,如果想每隔多少秒执行一次,就需要一些特殊的手段。

每隔5秒

  1. * * * * * for i in {1..12}; do /bin/cmd -arg1 ; sleep 5; done

每隔15秒

  1. * * * * * /bin/cmd -arg1
  2. * * * * * sleep 15; /bin/cmd -arg1
  3. * * * * * sleep 30; /bin/cmd -arg1
  4. * * * * * sleep 45; /bin/cmd -arg1

为什么crontab指定的脚本没有执行?

有以下可能原因

  • 没有权限执行某个命令
  • 某个命令不在环境变量中,无法找到对应命令

首先你必须测试一下,你的脚本不使用crontab能否正常执行。

大部分crontab执行不成功,都是因为环境变量的问题。

下面写个例子:

  1. #!/bin/bash
  2. now=`date`
  3. msg=`opensips -V`
  4. echo "$now $msg \n\n" >> /root/test.log
  1. cd /root
  2. sh test.sh

ctrontab -e将test.sh加入crontab中

  1. * * * * * sh /root/test.sh

centos crontab的执行日志在/var/log/cron中,可以查看执行日志。

我的机器是树莓派,没有这个文件,但是我是把执行输出到/root/test.log中的,可以查看这个文件

可以看到虽然输入了事件,但是并没有输出opensips的版本

  1. Mon 1 Jul 13:04:01 BST 2019
  2. Mon 1 Jul 13:05:01 BST 2019

将$PATH也加入输出,发现Mon 1 Jul 13:10:01 BST 2019 /usr/bin:/bin,而opensips这个命令是位于/usr/local/sbin下,所以无法找到执行文件,当然无法执行

  1. #!/bin/bash
  2. now=`date`
  3. msg=`opensips -V`
  4. echo "$now $PATH $msg \n\n" >> /root/test.log

那还不好办吗?

在当前工作目录执行 echo $PATH, 然后在脚本里设置一个环境变量就能搞定

  1. #!/bin/bash
  2. PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
  3. now=`date`
  4. msg=`opensips -V`
  5. echo "$now $PATH $msg \n\n" >> /root/test.log

也可以使用 journalctl -t CROND 查看crond的日志

检查crontab 是否运行

  1. systemctl status crond
  2. systemctl restart crond

在alpine中执行crontab

alpine中没有systemctl, 需要启动crond的守护进程,否则程序定时任务是不会执行的

  1. #!/bin/sh
  2. # start cron
  3. /usr/sbin/crond -f -l 8