在 Linux 中使用 Cron 执行定时任务
工作中我们常常需要在某些时候执行一些任务,Windows 下有定时任务管理, Linux 下则有 Crontab, 接触过 Linux 的童鞋一定不陌生。
Table of Contents
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
脚本。
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 | # # Example of job definition: |
时间格式为 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 | [root@localhost ~]$ cat /etc/crontab |
可以按照这个格式添加任务, 其中相对于 crontab -e
, 多了一个 user-name, 即运行任务的用户。
系统资源
若定期运行的任务很多, 有时候会在某一时候运行很多任务, 系统资源会比较紧张,可以将任务分散开,使得系统负载相对平稳。
1 | [root@localhost ~]$ cat /etc/crontab |
使用限制
如果你的用户名在 /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_month
与 day_of _week
一般不能同时设定,若同时设定了,系统会在所有符合一个或两个的日期都执行命令。
执行关机期间的任务
如果关机有任务没有执行, 开机后 cron 也不会执行过期的任务。想要执行过期任务,可以使用 anacron
。 它作为定时会每小时被执行一次, 执行 cron 没有执行的任务。