工作中我们常常需要在某些时候执行一些任务,Windows 下有定时任务管理, Linux 下则有 Crontab, 接触过 Linux 的童鞋一定不陌生。


Table of Contents

  1. 认识 crontab
  2. Crontab 命令
  3. Crontab 例子
    1. 备份系统
    2. 会议提醒
    3. 记录 IP
  4. Crontab 使用补充
    1. 系统设定
    2. 系统资源
    3. 使用限制
    4. 关闭邮件通知
    5. 环境变量
    6. 安全检测
    7. 周与日
    8. 执行关机期间的任务

Cron 是 Unix,Solaris, Linux 等系统下的可以自动在后台执行定时任务的工具,比如在某一天 9 点提醒你开会, 某一天 6 点去给女票买礼物等等, 这是由 cron 守护进程定期执行的。 如果启用了 cron(一般默认启用), cron 守护进程 会在系统启动后自动启动, 并按时执行任务。 cron 也能手动启用、关闭、重启等。

认识 crontab

Crontab 是 cron 的任务库文件,它存储了 cron 要执行的计划任务项目。 不同系统下该文件的位置可能不同。

  • macOS: /usr/lib/cron/tabs/
  • BSD Unix: /var/cron/tabs/
  • Solaris, Debian: /var/spool/cron/crontabs/
  • RHEL, CentOS, Fedora: /var/spool/cron/

cron 任务是一个包含特定日期,特定时间和要执行的命令的集合, 存储在 crontab 里。一个 crontab 条目如下图所示,指定了在每个月的所有周日凌晨 2 点 36 分 执行 /usr/local/sbin/ 下的 backup.sh 脚本。

CrontabCrontab

Crontab 命令

crontab 命令很简单,

1
[root@localhost ~]$ crontab [-u username] [-l|-r|-e] [-n <host>|-c] [-s] [-x <mask>]

各选项含义如下:

  • -u: 指定 crontab 的用户名, 此选项只能 root 使用
  • -e: 编辑 crontab 文件, 如果没有,会新建一个
  • -l: 打印出 crontab 文件内容,列出计划任务
  • -r: 移出 crontab 文件
  • -n : 设定在 集群中的 host 主机上执行用户 crontabs
  • -c: 获取用户在集群上的 crontabs
  • -s: selinux 相关内容
  • -x : 开启 debug
    执行 crontab -e 后就会进入 crontab 编辑环境。
1
2
3
4
5
6
7
8
# # 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
| | | | |
* * * * * command to be executed

时间格式为 min hour day_of_month month day_of_week, 每一项都是一定范围的整数或者数组或者范围。 一些辅助的字符有特别的意义。

特殊字符 代表含义
* 代表任何可能的值
, 代表分隔时段, 0 3,6 * * * command 表示在每天 3:00, 6:00 执行任务
- 代表时间范围, 0 10-20 * * * command 表示在每天10:00 到 20:00 执行任务
/n 代表 每隔 n 单位时间 重复一次

下面举几个 Crontab 的使用例子。

Crontab 例子

备份系统

每天 00:00 准时备份系统

1
0 0 * * * /usr/local/bin/backup.sh

会议提醒

提醒每周五下午 2:30 开会

1
20 14 * * 5 /path/to/alert.sh

记录 IP

每隔 3 小时记录 IP 并发送到指定邮箱

1
0 */3 * * * echo "$(date) : $(hostname -I)" | mutt -s "your ip" your_email_address > /dev/null 2>&1

Crontab 使用补充

系统设定

如果你要做的是系统的例行性任务,则可以使用 /etc/crontab, 在里面加入你的定时任务就好。

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]$ cat /etc/crontab
SHELL=/bin/bash <==使用哪种 shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin <==执行程序搜索路径
MAILTO=root <==若有額外STDOUT,以 email 将输出发送给谁

# 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

可以按照这个格式添加任务, 其中相对于 crontab -e, 多了一个 user-name, 即运行任务的用户。

系统资源

若定期运行的任务很多, 有时候会在某一时候运行很多任务, 系统资源会比较紧张,可以将任务分散开,使得系统负载相对平稳。

1
2
3
4
5
6
[root@localhost ~]$ cat /etc/crontab
0,5,10,15,20,25,30,35,40,45,50,55 * * * * root scripts_1.sh
1,6,11,16,21,26,31,36,41,46,51,56 * * * * root scripts_2.sh
2,7,12,17,22,27,32,37,42,47,52,57 * * * * root scripts_3.sh
3,8,13,18,23,28,33,38,43,48,53,58 * * * * root scripts_4.sh
4,9,14,19,24,29,34,39,44,49,54,59 * * * * root scripts_5.sh

使用限制

如果你的用户名在 /etc/cron.allow 中, 那是可以使用 crontab 的,但如果是在
/etc/cron.deny 中, 则无法使用并安排定时任务的。 /etc/cron.allow 的优先级高于 /etc/cron.deny

关闭邮件通知

cron 任务默认会在执行一个 cronjob 后发送一封邮件的,如果执行任务勤了,会产生大量的邮件。如果输出不是必要的, 则可以通过在任务结尾加上重定向:

1
>/dev/null 2>&1

或者重定向到一个日志文件:

1
> /path/to/your/log/file 2>&1

环境变量

cron 会在用户 HOME 文件夹下执行命令,默认的环境变量有:

  • HOME=user-home-directory
  • LOGNAME=user-login-id
  • PATH=/usr/bin:/usr/sbin
  • SHELL=/usr/bin/sh
    要是你想要任务开始时执行 ~/.profile 里的命令, 需要显示地在脚本里执行 source ~/.profile

安全检测

有可能服务器会被人入侵,植入的木马一般都会以定时任务的形式运行,可以检查 /var/spool/cron/ 有没有问题。

周与日

day_of_monthday_of _week 一般不能同时设定,若同时设定了,系统会在所有符合一个或两个的日期都执行命令。

执行关机期间的任务

如果关机有任务没有执行, 开机后 cron 也不会执行过期的任务。想要执行过期任务,可以使用 anacron。 它作为定时会每小时被执行一次, 执行 cron 没有执行的任务。