50

linux上配置计划任务(cron和crontab)

 5 years ago
source link: http://www.tracefact.net/tech/080.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

很多时候,我们需要定时执行某个应用或者某段脚本,在linux上,可以使用cron服务,它有点类似于Windows上的任务计划程序。这篇文章将简单介绍cron的使用。

crond和crontab

首先需要分清楚两个概念:crond和crontab。crond是后台守护进程的名称(d代表daemon),用来实际执行脚本,它在系统中是一直运行的。可以通过下面的方式查看到它:

# systemctl | grep crond
crond.service loaded active running Command Scheduler

crontab是一个工具,用来列出cron中当前运行的作业(应用或脚本等)、向cron中添加作业、编辑作业、删除作业。它并不是一直在后台运行的,是一个短时的命令行工具,执行完就结束了。

可以简单理解crond和crontab组合起来提供cron服务。

crontab的常用命令

因为crond是一个守护进程,所以在系统开机后,通过 systemctl start crond 启动一次以后(默认自动启动的),几乎就不需要再管它了,之后的操作都通过crontab来完成。

查看现有任务

# crontab -l
no crontab for root

因为现在没有任务,所以显示的是 no crontab for root,可见,任务是根据用户进行区分的。

添加定时任务

为了便于测试,我们可以创建这样一个简单的脚本(位于~/tmp/job1.sh):在一个文件末尾追加当前时间。脚本如下:

date +'%F %T' >> ~/tmp/job1.log

创建完成后记得赋予一下执行权限:

# chmod 755 job1.sh

接下来,需要配置多久运行一次。这里通过cron表达式来设置,它非常灵活,可以很简单也可以很复杂。cron表达式的应用广泛,不止用在系统层面,在其他各种编程语言的类库当中,都有类似的实现,语法略有不同。使用下面的命令可以查看linux系统中cron表达式的写法:

# 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

如果需要查看更详细的用法,可以使用 # man crontab 命令查看。

整理后如下表所示:

不同的cron应用存在很大差异,比如crontab不支持“秒”,特殊字符也支持的比较少(支持,-*/)。而其他一些应用,则支持“秒”和更多的特殊字符。这里为了更完备一些,所以全都列出来了,省的以后再去总结。

名称 必须 取值范围 可设置的特殊字符 分 是 0-59 ,-*/ 时 是 0-23 ,-*/ 日(月) 是 1-31 ,-*?/LW 月 是 1-12 或者 jan-dec ,-*/ 日(周) 是 0-7(0和7都是星期天)
或者 sun-sat ,-*?/L# 年 否 留空,1970-2099 ,-*/

几个特殊字符的含义:

字符 含义 * 全部。意思是在该时间的任意点都应当执行 ? 不指定,任意。仅用于 日(月)和日(周)。0 0 5 * ? 代表每个月的第5天零点,不论星期几。
0 0 ? * 1 代表每周一,不论是当月的哪天。 , 多个值的分隔符,例如1,5,10 - 代表连续值,例如1-20 / 步长。例如 5/15,代表从5开始,以15为步长。因此,当5/15位于分钟的位置时,表示小时内的第5、20、35和50分钟。 L 最后一天。可以是每月最后一天或者每周最后一天。如果用在 天(周)字段,并且前面加数字,则表示最后一个周N。例如5L,表示最后一个周五(5表示周五,L表示最后)。 W 工作日,指周一到周五的任意一天 # 表示第几个的意思,例如 6#3,表示当月第3个星期六(6表示周六,3表示第3个)

几个简单的例子:

表达式 含义 * * * * * 每分钟执行一次 30 * * * * 每小时的30分执行一次 */5 * * * * 每5分钟执行一次 0/5 * * * * 每5分钟执行一次,且仅在0,5,15,20...55分执行 5 0 * * * 每天的00:05执行一次

crontab中 日(周)不接受“?”的写法,在很多其他应用中则可以,例如Quartz.Net库: https://www.quartz-scheduler.net/

更多的用法,可以参考: https://crontab.guru

接下来,如果我们想要每分钟执行一下前面创建的job1.sh脚本,需要再创建一个crontab作业(jobs.cron,后缀名无所谓,这里只是为了便于识别),其中包含了cron表达式,用于表明job1.sh执行的周期:

* * * * * ~/tmp/job1.sh

使用crontab将它加入到计划中:

# crontab jobs.cron

再次查看当前计划,可以看到这样的结果:

# crontab -l
* * * * * ~/tmp/job1.sh

删除定时任务

先将job1.sh复制一份,稍作修改,然后编辑一下jobs.cron,将job2.sh也加入进去:

* * * * * ~/tmp/job1.sh
*/5 * * * * ~/tmp/job2.sh

然后重新加入到cron服务中。

# crontab jobs.cron

接着查看一下当前cron中的作业:

# crontab -l
* * * * * ~/tmp/job1.sh
*/5 * * * * ~/tmp/job2.sh

可以看到上面有job1.sh和job2.sh两个作业,其效果相当于将jobs.cron文件的内容拷贝进去。

如果想要删除作业,则执行:

# crontab -r

这样会删除所有作业,如果只想删除一个,或者想对作业进行编辑,可以使用下面的命令。

编辑定时任务

crontab -e 命令会调用编辑器(通常是vi或者vim),直接编辑计划作业,相当于编辑jobs.cron。只不过编辑完立即生效,不需要再执行crontab进行加载。

# crontab -e
crontab: installing new crontab

统一期间,个人不建议使用crontab -e编辑计划,而是编辑jobs.cron,然后进行加载。这样的话jobs.cron文件相当于一个备份,方便日后恢复。

查看作业日志

在作业执行出现异常(或作业脚本写日志)时,cron服务会输出日志,在我的CentOS7系统上,查看的地址位于/var/log下。

# ls /var/log | grep cron
cron
cron-20180819
cron-20180826
cron-20180902
cron-20180909

如果想让自己编写的作业输出日志,可以这样编写jobs.cron:

* * * * * ~/tmp/job1.sh >> /var/log/job1.log 2>&1

上面的意思是将stdout和stderr输出到/var/log/job1.log。

修改job1.sh,在底部加入 echo hello 。然后调用 crontab jobs.cron 重新加载,然后在/var/log目录下可以看到job1.log,其中包含了输出的文本“hello”。

至此,我们已经熟悉了cron相关的概念,并完成了常见的添加、删除、编辑操作,且学会了如何查看和输出作业日志。

感谢阅读,希望这篇文章能给你带来帮助!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK