linux下快速添加自己的定时任务

Posted 奇妙之二进制

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下快速添加自己的定时任务相关的知识,希望对你有一定的参考价值。

通过本文,你将了解到 Linux 中的定时任务cron job功能。你将通过学习编辑 crontab 文件来创建定时任务。

何为定时任务

cron 是一个用于按计划运行短小且快速的命令的实用命令行工具。该工具是一个便捷、经典的系统管理工具,通过和其他工具结合使用可以自动运行各式各样的任务。比如,有些人通过把 rsynccron 结合使用,在特定的时间自动创建每日备份和每周备份。也有些人使用 cron 来分析服务器日志,并且结合邮件功能,在日志检测到某种错误时自动发送告警邮件。

cron 就如同“瑞士军刀”一样,可以多场景多样化使用。尽可能发挥你的想象,去挖掘它的功能。

其实 cron 的使用很容易上手,只需要几秒钟。不过在我们开始上手之前,先来讨论下几个经常容易混淆的概念。

cron、cron job、crontab

有三个术语比较容易混淆:cron、cront job和 crontab,让我们来看看它们的含义:

术语含义
cron这是安装在系统上的实际执行定时任务的守护进程。
cron job“任务”是指一段启动并运行的程序。cron 可以按照约定的时间计划运行各种任务,这样的任务通常叫做“定时任务”。
crontab这是一个文件,用于定义定时任务。一个 crontab 文件可以通过表格形式(每一行就是一个定时任务)定义多个定时任务。

来看一个简单例子:创建一个定时任务,每小时向 crontabl_log.txt 文件追加打印 Linux is cool!

0 * * * *  echo "Linux is Cool!" >> ~/crontab_log.txt

是不是这么个简单定时任务的例子都让你感到惊恐,这是因为你需要懂得如何去读懂一个定时任务的属性。

我将在后文中讲述这个基础理论知识。

上手 cron

我们通过另一个例子来看看 cron 如何工作。

为了创建定时任务(或者说 cron 将要执行的命令任务),你只需要运行:

crontab -e

提示:该命令实际上是使用编辑器打开一个用户级的任务文件。第一次输入,会提示我们选择编辑器,我们选择熟悉的vim即可。

这将会打开一个文件,用于编辑定时任务:

其中,所有以 # 开头的行都是注释,用于指导你如何使用 cron,如果觉得没用可以删除它们。

我们将创建如下任务,作为我们的第一个定时任务:

* * * * * touch ~/crontab_test

让我快速看看该任务将会做什么:

定时任务都是以 “分钟 小时 天 月 周 命令” 形式呈现:

  • 分钟:指该任务在哪一分钟会被执行。所以,该值为 0 则代表在每个小时开始时运行,5 则代表在每个小时的第 5 分钟会运行。
  • 小时:指该任务在一天中的哪个小时会被执行,取值范围为 0-23。没有 24 的原因是 23 时的末尾是半夜 11:59,然后就是每天的开始 0 时。分钟的取值范围定义逻辑与之类似。
  • 天:指一个月中的哪一天执行该任务,取值范围是 1-31(不同于前面的分钟和小时从 0 开始取值)。
  • 月:指该任务在哪个月被执行,取值范围是 1-12
  • 周:指该任务在星期几被执行,从周日开始算起,取值范围是 0-6(分别对应周日、周一到周六)。
  • 命令:是你想要运行的命令任务。

如果想对 “分钟 小时 天 月 周” 部分有更详细的理解,可以参考 Crontab guru 网站,该网站可以帮助你理解正在执行什么。

事实上,有许多的小工具网站,支持直接编辑,最后得到一个你想要的cron表达式,比如下面这个网站就不错,在线编辑后给出了表达式的含义,并且还列举了每个字段的含义,每个字段的取值范围以及能使用的特殊字符。

我们看到上面是星号*,表示什么意思呢?除了*之外,还有一些特殊符号,含义如下:

  • *****星号:可以理解为每的意思,每秒,每分,每天,每月,每年…

  • **-**减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12点都会触发。

  • **,**逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四

  • **/**斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60。另外:*/y,等同于0/y。

注意:一些非标准的字符和实现,本文不会介绍,只介绍标准的cron实现。

字段是否必填允许值允许特殊字符备注
Minutes0–59*,-/
Hours0–23*,-/
Day of month1–31*,-/
Month1–12 or JAN–DEC*,-/
Day of week0–7 or SUN–SAT*,-/0和7表示星期天

下面列举几个例子供大家来验证:

每星期一半夜3点(可能是重启服务器):

每个月10号下午5点半(可能是发工资):

接着之前的例子 * * * * * touch ~/crontab_test,表示每分钟创建一次 ~/crontab_test 文件。

让我们将该任务编辑进 crontab 然后看看执行结果:

等到下一分钟,你就会发现你的家目录下多了文件 crontab_test:

这便是 cron 的基础应用示例。

深入了解cron

前面我们直接使用crontab -e创建了一个任务,crontab是cron提供的一个用于编辑用户级任务文件(crontab)的命令行工具。这些用户级别的任务文件保存在 /var/spool/cron/crontabs/。对于一个叫blue的用户,对应一个 /var/spool/cron/crontabs/blue文件。

cron后台服务会在主机进入多用户模式时自动启动,然后 cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron/crontabs 下面的crontab文件 。因此,只要你编辑完你的任务,并且保存之后, 就会在下一分钟被cron自动检测到!换句话说,cron服务的最低侦测限制是『分钟』。

/etc/crontab是系统级任务文件,里面预制了4条命令,分别用于每小时,每天,每周,每月执行**/etc/cron.hourly,/etc/cron.daily,/etc/cron.weekly,/etc/cron.monthly**下的可执行文件。换句话说,如果我们有想要每小时,每天,每周,每月执行的任务,只需把该任务脚本丢到对应的目录即可,就不用再自己去编辑任务文件了,相当于一个后门。

其实,ubuntu系统在上面的几个目录埋了很多定时任务,例如系统更新提示啦,文件备份等等。

提示:这里也埋了个坑,放在上面4个目录下的文件,必须是可执行文件才会被执行。

当然了,通过这种方式,没有办法苛刻任务执行的具体时间,下面预置的时间点别问我为啥是那样。

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

提示:run-parts命令用于执行指定目录下的所有可执行文件。/usr/sbin/anacron是一个改进版的cron,我们有机会再开一篇专门介绍。/etc/crontab的语法和普通crontab略有不同,多了个user列,即可以指定以什么用户来执行该任务,毕竟它是root用户,具有超级权限。

/etc/cron.d下的文件和/etc/crontab一样,也会被cron执行,也是系统级crontab文件。

crontab的语法如下:

crontab [-u username] [-l|-e|-r]
选项与参数:
-u  :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作排程;
-e  :编辑 crontab 的工作内容
-l  :查阅 crontab 的工作内容
-r  :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑

查询使用者目前的 crontab 内容:

$ crontab -l
*/5 * * * *  /home/blue/do/rsyncfile.sh
0 2 1 4 *  /home/blue/do/rsyncfile_day.sh

清空使用者目前的 crontab:

$ crontab -r
$ crontab -l
no crontab for blue

如果你想删除当前用户的某一个crontab任务,那么使用crontab -e进入编辑器,再删除对应的任务。

普通用户没法直接编辑/var/spool/cron下的文件,看下权限就知道了,其他人只有写入没有读取权限:

victory@ubuntu:~$ ls -al /var/spool/cron
total 12
drwxr-xr-x 3 root root    4096 Sep 15 13:17 .
drwxr-xr-x 7 root root    4096 Sep 15 13:21 ..
drwx-wx--T 2 root crontab 4096 Dec 25 03:38 crontabs

使用crontab -e进行编辑的好处时,在保存时会进行语法检查,如果语法非法,不会让你保存。

crontab限制哪些人能使用

  • /etc/cron.allow:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;

  • /etc/cron.deny:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab 。

以优先顺序来说, /etc/cron.allow 比 /etc/cron.deny 要优先, 而判断上面,这两个文件只选择一个来限制而已,因此,建议你只要保留一个即可, 免得影响自己在配置上面的判断!一般来说,系统默认是保留 /etc/cron.deny , 你可以将不想让他运行 crontab 的那个使用者写入 /etc/cron.deny 当中,一个帐号一行!

一个实用的定时任务示例

假设你想创建一个脚本,用于拷贝多个目录内容到一个路径并打包作为备份,该如何实现?

通过 cron 定时任务就可以很容易实现该功能。

请看如下脚本:

#!/usr/bin/bash
echo "Backing up..."
mkdir -p ~/.local/tmp/
tar -Pc ~/Documents/ -f ~/.local/tmp/backup.gz

该脚本做了如下事情:

  1. 确保备份路径目录 ~/.local/tmp/ 存在。
  2. 将目录 ~/Documents/ 下的所有内容打包至文件 ~/.local/tmp/backup.gz

我们先来手动运行该脚本,看看它到底如何工作。

首先,我们在家目录(~)下创建该脚本,命令为 backup_script,如下图所示:

然后编辑 backup_script 脚本,写入上面那个脚本代码。

接着,赋予 backup_script 可执行权限:

最后运行脚本 ~/backup_script,进行功能验证:

你可以通过运行命令 tar -xf ~/.local/tmp/backup.gz -C <output_dir> 来进行备份恢复,这里 <output_dir> 是指文件要恢复到的路径目录。

接下来,就可以用 cron 工具来进行定时任务运行该脚本了。

举个例子,假设需要每天的凌晨 3 点运行该备份脚本,你可以在 crontab 中输入如下命令:

* 3 * * * ~/backup_script

这样你就可以每天自动进行备份操作了。

后记

本文简单介绍了定时任务功能。尽管我不确定 Linux 桌面用户使用该功能多不多,但我知道定时任务功能被许多系统管理员广泛应用。

以上是关于linux下快速添加自己的定时任务的主要内容,如果未能解决你的问题,请参考以下文章

linux设置定时任务的方法(自己总结)

Linux设置定时任务

linux下添加定时任务

Linux设置定时任务

linux 下cron定时任务为啥没执行

Linux下crontab命令添加Kettle作业定时任务