Linux上使用crontab
设置定时任务
简单介绍
很喜欢bing的首页图,想要实现一个简单的定时下载脚本,脚本使用python中的urllib
和re
模块实现,因为都是内置模块,每个python环境都会包含。但是如何设置定时运行呢?网上搜索得知,可以使用crontab
来制定定时任务。这里简单记录其用法,之后会写个帖子记录下这次经历。
在介绍crontab
命令之前,我们首先要介绍一下crond
,因为crontab
命令需要crond
服务支持。crond
是Linux下用来周期地执行某种任务或等待处理某些事件的一个守护进程,和Windows
中的计划任务有些类似。
crond
服务的启动和自启动方法如下:
$ service crond restart
停止 crond: [确定]
正在启动 crond: [确定]
#重新启动crond服务
$ chkconfig crond on
#设定crond服务为开机自启动
其实,在安装完成操作系统后,默认会安装crond
服务工具,且crond
服务默认就是自启动的。crond
进程每分钟会定期检查是否有要执行的任务,如果有,则会自动执行该任务。
最后,请保证需要执行的这条指令单独是可以运行并实现你的目标的,并且没有副作用。
选项
usage: crontab [-u user] file
crontab [ -u user ] [ -i ] { -e | -l | -r }
(default operation is replace, per 1003.2)
-e (edit user's crontab)
-l (list user's crontab)
-r (delete user's crontab)
-i (prompt before deleting user's crontab)
当crontab -e
编辑完成之后,一旦保存退出,那么这个定时任务实际就会写入/var/spool/cron/
目录中,每个用户的定时任务用自己的用户名进行区分。而且crontab
命令只要保存就会生效,只要crond
服务是启动的。
语法
Schedule cron jobs to run on a time interval for the current user.
Job definition format: (min) (hour) (day_of_month) (month) (day_of_week) command_to_execute
.(用空格隔开)
书写时,有一些特殊符号有自己的含义,可以适当使用来灵活设定时间:
特殊符号 | 含义 |
---|---|
* | 代表任何时间。比如第一个”*”就代表一小时种每分钟都执行一次的意思。 |
, | 代表不连续的时间。比如”0 8,12,16*命令”就代表在每天的 8 点 0 分、12 点 0 分、16 点 0 分都执行一次命令。 |
- | 代表连续的时间范围。比如”0 5 ** 1-6命令”,代表在周一到周六的凌晨 5 点 0 分执行命令。 |
/ | 代表每隔多久执行一次。比如”*/10命令”,代表每隔 10 分钟就执行一次命令。 |
来自http://c.biancheng.net/view/1092.html的几个例子:
时间指令 | 含义 |
---|---|
45 22 *命令 | 在 22 点 45 分执行命令 |
0 17 ** 1命令 | 在每周一的 17 点 0 分执行命令 |
0 5 1,15**命令 | 在每月 1 日和 15 日的凌晨 5 点 0 分执行命令 |
40 4 ** 1-5命令 | 在每周一到周五的凌晨 4 点 40 分执行命令 |
*/10 4 命令 | 在每天的凌晨 4 点,每隔 10 分钟执行一次命令 |
0 0 1,15 * 1命令 | 在每月 1 日和 15 日,每周一个 0 点 0 分都会执行命令,注意:星期几和几日最好不要同时出现,因为它们定义的都是天,非常容易让管理员混淆 |
简单实例
来自tldr的例子:
# Edit the crontab file for the current user:
crontab -e
# Edit the crontab file for a specific user:
sudo crontab -e -u user
# View a list of existing cron jobs for current user:
crontab -l
# Remove all cron jobs for the current user:
crontab -r
# 下面这些
# Sample job which runs at 10:00 every day (* means any value):
0 10 * * * command_to_execute
# Sample job which runs every minute on the 3rd of April:
* * 3 Apr * command_to_execute
# Sample job which runs a certain script at 02:30 every Friday:
30 2 * * Fri /absolute/path/to/script.sh
来自http://c.biancheng.net/view/1092.html的几个例子:
在“执行的任务”字段中既可以定时执行系统命令,也可以定时执行某个 Shell 脚本,这里举几个实际的例子。
首先crontab -e
进入编辑界面:
让系统每隔 5 分钟就向
/tmp/test
文件中写入一行“11”,验证一下系统定时任务是否会执行。
*/5 * * * * /bin/echo "11" >> /tmp/test
这个任务在时间工作中没有任何意义,但是可以很简单地验证我们的定时任务是否可以正常执行。如果觉得每隔 5 分钟太长,那就换成“”,让它每分钟执行一次。而且和at
命令一样,*如果我们定时执行的是系统命令,那么最好使用绝对路径。
让系统在每周二的凌晨 5 点 05 分重启一次。
5.5 * * 2 /sbin/shutdown -r now
如果服务器的负载压力比较大,则建议每周重启一次,让系统状态归零。比如绝大多数游戏服务器每周维护一次,维护时最主要的工作就是重启,让系统状态归零。这时可以让我们的服务器自动来定时执行。
在每月 1 日、10 日、15 日的凌晨 3 点 30 分都定时执行日志备份脚本 autobak.sh。
30.3 1,10,15 * * /root/sh/autobak.sh
这些定时任务保存之后,就可以在指定的时间执行了。
我们可以使用命令crontab -l
和crontab -r
来查看和删除当前用户设置的定时任务,其中如果只想删除某个定时任务,则可以执行crontab -e
命令进入编辑模式手工删除。
在书写crontab
定时任务时,需要注意以下几个事项:
- 6 个选项都不能为空,必须填写。如果不确定,则使用“*”代表任意时间。
crontab
定时任务的最小有效时间是分钟,最大有效时间是月。像 2018 年某时执行、3 点 30 分 30 秒这样的时间都不能被识别。- 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都以天为单位,非常容易让管理员混淆。
- 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。
:::info
一般第一次使用crontab -e
的时候,执行crontab
会要求你设置编辑器,如果选的不合适,可以退出后重新执行select-editor
重新选择。
:::
crontab
开启日志
由于Ubuntu默认没有开启crontab
的日志记录,所以对于crontab
的执行情况是看不到的。为了开启这个,我们可以编辑/etc/rsyslog.d/50-default.conf
文件,将cron.* /var/log/cron.log
这一句对应的注释去掉。重启服务即可。主要指令如下:
sudo vim /etc/rsyslog.d/50-default.conf
cron.* /var/log/cron.log #将cron前面的注释符去掉
#重启rsyslog
sudo service rsyslog restart
sudo service cron restart
这样就可以用tail -f /var/log/cron.log
查看日志了。