详解在Linux中怎么使用cron计划任务
没有时间运行命令?使用cron的计划任务意味着你不用熬夜程序也可以运行。
系统管理员(在许多好处中)的挑战之一是在你该睡觉的时候去运行一些任务。例如,一些任务(包括定期循环运行的任务)需要在没有人使用计算机资源的时候去运行,如午夜或周末。在下班后,我没有时间去运行命令或脚本。而且,我也不想在晚上去启动备份或重大更新。
取而代之的是,我使用两个服务功能在我预定的时间去运行命令、程序和任务。cron和at服务允许系统管理员去安排任务运行在未来的某个特定时间。at服务指定在某个时间去运行一次任务。cron服务可以安排任务在一个周期上重复,比如天、周、或月。
在这篇文章中,我将介绍cron服务和怎么去使用它。
常见(和非常见)的cron用途
我使用cron服务去安排一些常见的事情,比如,每天凌晨2:00发生的定期备份,我也使用它去做一些不常见的事情。
- 许多电脑上的系统时钟(比如,操作系统时间)都设置为使用网络时间协议(NTP)。NTP设置系统时间后,它不会去设置硬件时钟,它可能会“漂移”。我使用cron基于系统时间去设置硬件时钟。
- 我还有一个Bash程序,我在每天早晨运行它,去在每台电脑上创建一个新的“每日信息”(MOTD)。它包含的信息有当前的磁盘使用情况等有用的信息。
- 许多系统进程和服务,像Logwatch、logrotate、和RootkitHunter,使用cron服务去安排任务和每天运行程序。
crond守护进程是一个完成cron功能的后台服务。
cron服务检查在/var/spool/cron和/etc/cron.d目录中的文件,以及/etc/anacrontab文件。这些文件的内容定义了以不同的时间间隔运行的cron作业。个体用户的cron文件是位于/var/spool/cron,而系统服务和应用生成的cron作业文件放在/etc/cron.d目录中。/etc/anacrontab是一个特殊的情况,它将在本文中稍后部分介绍。
使用crontab
cron实用程序运行基于一个cron表(crontab)中指定的命令。每个用户,包括root,都有一个cron文件。这些文件缺省是不存在的。但可以使用crontab-e命令创建在/var/spool/cron目录中,也可以使用该命令去编辑一个cron文件(看下面的脚本)。我强烈建议你,不要使用标准的编辑器(比如,Vi、Vim、Emacs、Nano、或者任何其它可用的编辑器)。使用crontab命令不仅允许你去编辑命令,也可以在你保存并退出编辑器时,重启动crond守护进程。crontab命令使用Vi作为它的底层编辑器,因为Vi是预装的(至少在大多数的基本安装中是预装的)。
现在,cron文件是空的,所以必须从头添加命令。我增加下面示例中定义的作业到我的cron文件中,这是一个快速指南,以便我知道命令中的各个部分的意思是什么,你可以自由拷贝它,供你自己使用。
#crontab-e SHELL=/bin/bash MAILTO=root@example.com PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin #Fordetailsseeman4crontabs #Exampleofjobdefinition: #.----------------minute(0-59) #|.-------------hour(0-23) #||.----------dayofmonth(1-31) #|||.-------month(1-12)ORjan,feb,mar,apr... #||||.----dayofweek(0-6)(Sunday=0or7)ORsun,mon,tue,wed,thu,fri,sat #||||| #*****user-namecommandtobeexecuted #backupusingthersbuprogramtotheinternal4TBHDDandthen4TBexternal 0101***/usr/local/bin/rsbu-vbd1;/usr/local/bin/rsbu-vbd2 #Setthehardwareclocktokeepitinsyncwiththemoreaccuratesystemclock 0305***/sbin/hwclock--systohc #Performmonthlyupdatesonthefirstofthemonth #25041**/usr/bin/dnf-yupdate
crontab命令用于查看或编辑cron文件。
上面代码中的前三行设置了一个缺省环境。对于给定用户,环境变量必须是设置的,因为,cron不提供任何方式的环境。SHELL变量指定命令运行使用的shell。这个示例中,指定为Bashshell。MAILTO变量设置发送cron作业结果的电子邮件地址。这些电子邮件提供了cron作业(备份、更新、等等)的状态,和你从命令行中手动运行程序时看到的结果是一样的。第三行为环境设置了PATH变量。但即使在这里设置了路径,我总是使用每个程序的完全限定路径。
在上面的示例中有几个注释行,它详细说明了定义一个cron作业所要求的语法。我将在下面分别讲解这些命令,然后,增加更多的crontab文件的高级特性。
0101***/usr/local/bin/rsbu-vbd1;/usr/local/bin/rsbu-vbd2
在我的/etc/crontab中的这一行运行一个脚本,用于为我的系统执行备份。
这一行运行我自己编写的Bashshell脚本rsbu,它对我的系统做完全备份。这个作业每天的凌晨1:01(0101)运行。在这三、四、五位置上的星号(*),像文件通配符一样代表一个特定的时间,它们代表“一个月中的每天”、“每个月”和“一周中的每天”,这一行会运行我的备份两次,一次备份内部专用的硬盘驱动器,另外一次运行是备份外部的USB驱动器,使用它这样我可以很保险。
接下来的行我设置了一个硬件时钟,它使用当前系统时钟作为源去设置硬件时钟。这一行设置为每天凌晨5:03分运行。
0305***/sbin/hwclock--systohc
这一行使用系统时间作为源来设置硬件时钟。
我使用的第三个也是最后一个的cron作业是去执行一个dnf或yum更新,它在每个月的第一天的凌晨04:25运行,但是,我注释掉了它,以后不再运行。
#25041**/usr/bin/dnf-yupdate
这一行用于执行一个每月更新,但是,我也把它注释掉了。
其它的定时任务技巧
现在,让我们去做一些比基本知识更有趣的事情。假设你希望在每周四下午3:00去运行一个特别的作业:
0015**Thu/usr/local/bin/mycronjob.sh
上面这一行会在每周四下午3:00运行mycronjob.sh这个脚本。
或者,或许你需要在每个季度末去运行一个季度报告。cron服务没有为“每个月的最后一天”设置选项,因此,替代方式是使用下一个月的第一天,像如下所示(这里假设当作业准备运行时,报告所需要的数据已经准备好了)。
020311,4,7,10*/usr/local/bin/reports.sh
在季度末的下一个月的第一天运行这个cron作业。
下面展示的这个作业,在每天的上午9:01到下午5:01之间,每小时运行一次。
0109-17***/usr/local/bin/hourlyreminder.sh
有时,你希望作业在业务期间定时运行。
我遇到一个情况,需要作业在每二、三或四小时去运行。它需要用期望的间隔去划分小时,比如,*/3为每三个小时,或者6-18/3为上午6点到下午6点每三个小时运行一次。其它的时间间隔的划分也是类似的。例如,在分钟位置的表达式*/15意思是“每15分钟运行一次作业”。
*/508-18/2***/usr/local/bin/mycronjob.sh
这个cron作业在上午8:00到下午18:59之间,每五分钟运行一次作业。
需要注意的一件事情是:除法表达式的结果必须是余数为0(即整除)。换句话说,在这个例子中,这个作业被设置为在上午8点到下午6点之间的偶数小时每5分钟运行一次(08:00、08:05、08:10、08:15……18:55等等),而不运行在奇数小时。另外,这个作业不能运行在下午7:00到上午7:59之间。(LCTT译注:此处本文表述有误,根据正确情况修改)
我相信,你可以根据这些例子想到许多其它的可能性。
限制访问cron
普通用户使用cron访问可能会犯错误,例如,可能导致系统资源(比如内存和CPU时间)被耗尽。为避免这种可能的问题,系统管理员可以通过创建一个/etc/cron.allow文件去限制用户访问,它包含了一个允许去创建cron作业的用户列表。(不管是否列在这个列表中,)不能阻止root用户使用cron。
通过阻止非root用户创建他们自己的cron作业,那也许需要将非root用户的cron作业添加到root的crontab中,“但是,等等!”你说,“不是以root去运行这些作业?”不一定。在这篇文章中的第一个示例中,出现在注释中的用户名字段可以用于去指定一个运行作业的用户ID。这可以防止特定的非root用户的作业以root身份去运行。下面的示例展示了一个作业定义,它以“student”用户去运行这个作业:
0407***student/usr/local/bin/mycronjob.sh
如果没有指定用户,这个作业将以contab文件的所有者用户去运行,在这个情况中是root。
cron.d
目录/etc/cron.d中是一些应用程序,比如SpamAssassin和sysstat安装的cron文件。因为,这里没有spamassassin或者sysstat用户,这些程序需要一个位置去放置cron文件,因此,它们被放在/etc/cron.d中。
下面的/etc/cron.d/sysstat文件包含系统活动报告(SAR)相关的cron作业。这些cron文件和用户cron文件格式相同。
#Runsystemactivityaccountingtoolevery10minutes */10****root/usr/lib64/sa/sa111 #Generateadailysummaryofprocessaccountingat23:53 5323***root/usr/lib64/sa/sa2-A
sysstat包安装了/etc/cron.d/sysstatcron文件来运行程序生成SAR。
该sysstatcron文件有两行执行任务。第一行每十分钟去运行sa1程序去收集数据,存储在/var/log/sa目录中的一个指定的二进制文件中。然后,在每天晚上的23:53,sa2程序运行来创建一个每日汇总。
计划小贴士
我在crontab文件中设置的有些时间看上起似乎是随机的,在某种程度上说,确实是这样的。尝试去安排cron作业可能是件很具有挑战性的事,尤其是作业的数量越来越多时。我通常在我的每个电脑上仅有一些任务,它比起我工作用的那些生产和实验环境中的电脑简单多了。
我管理的一个系统有12个每天晚上都运行cron作业,另外3、4个在周末或月初运行。那真是个挑战,因为,如果有太多作业在同一时间运行,尤其是备份和编译系统,会耗尽内存并且几乎填满交换文件空间,这会导致系统性能下降甚至是超负荷,最终什么事情都完不成。我增加了一些内存并改进了如何计划任务。我还删除了一些写的很糟糕、使用大量内存的任务。
crond服务假设主机计算机24小时运行。那意味着如果在一个计划运行的期间关闭计算机,这些计划的任务将不再运行,直到它们计划的下一次运行时间。如果这里有关键的cron作业,这可能导致出现问题。幸运的是,在定期运行的作业上,还有一个其它的选择:anacron。
anacron
anacron程序执行和cron一样的功能,但是它增加了运行被跳过的作业的能力,比如,如果计算机已经关闭或者其它的原因导致无法在一个或多个周期中运行作业。它对笔记本电脑或其它被关闭或进行睡眠模式的电脑来说是非常有用的。
只要电脑一打开并引导成功,anacron会检查过去是否有计划的作业被错过。如果有,这些作业将立即运行,但是,仅运行一次(而不管它错过了多少次循环运行)。例如,如果一个每周运行的作业在最近三周因为休假而系统关闭都没有运行,它将在你的电脑一启动就立即运行,但是,它仅运行一次,而不是三次。
anacron程序提供了一些对周期性计划任务很好用的选项。它是安装在你的/etc/cron.[hourly|daily|weekly|monthly]目录下的脚本。根据它们需要的频率去运行。
它是怎么工作的呢?接下来的这些要比前面的简单一些。
1、crond服务运行在/etc/cron.d/0hourly中指定的cron作业。
#Runthehourlyjobs SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root 01****rootrun-parts/etc/cron.hourly
/etc/cron.d/0hourly中的内容使位于/etc/cron.hourly中的shell脚本运行。
2、在/etc/cron.d/0hourly中指定的cron作业每小时运行一次run-parts程序。
3、run-parts程序运行所有的在/etc/cron.hourly目录中的脚本。
4、/etc/cron.hourly目录包含的0anacron脚本,它使用如下的/etdc/anacrontab配置文件去运行anacron程序。
#/etc/anacrontab:configurationfileforanacron #Seeanacron(8)andanacrontab(5)fordetails. SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root #themaximalrandomdelayaddedtothebasedelayofthejobs RANDOM_DELAY=45 #thejobswillbestartedduringthefollowinghoursonly START_HOURS_RANGE=3-22 #periodindaysdelayinminutesjob-identifiercommand 15cron.dailynicerun-parts/etc/cron.daily 725cron.weeklynicerun-parts/etc/cron.weekly @monthly45cron.monthlynicerun-parts/etc/cron.monthly
/etc/anacrontab文件中的内容在合适的时间运行在cron.[daily|weekly|monthly]目录中的可执行文件。
5、anacron程序每日运行一次位于/etc/cron.daily中的作业。它每周运行一次位于/etc/cron.weekly中的作业。以及每月运行一次cron.monthly中的作业。注意,在每一行指定的延迟时间,它可以帮助避免这些作业与其它cron作业重叠。
我在/usr/local/bin目录中放置它们,而不是在cron.X目录中放置完整的Bash程序,这会使我从命令行中运行它们更容易。然后,我在cron目录中增加一个符号连接,比如,/etc/cron.daily。
anacron程序不是设计用于在指定时间运行程序的。而是,用于在一个指定的时间开始,以一定的时间间隔去运行程序,比如,从每天的凌晨3:00(看上面脚本中的START_HOURS_RANGE行)、从周日(每周第一天)和这个月的第一天。如果任何一个或多个循环错过,anacron将立即运行这个错过的作业。
更多的关于设置限制
我在我的计算机上使用了很多运行计划任务的方法。所有的这些任务都需要一个root权限去运行。在我的经验中,很少有普通用户去需要运行cron任务,一种情况是开发人员需要一个cron作业去启动一个开发实验室的每日编译。
限制非root用户去访问cron功能是非常重要的。然而,在一些特殊情况下,用户需要去设置一个任务在预先指定时间运行,而cron可以允许他们去那样做。许多用户不理解如何正确地配置cron去完成任务,并且他们会出错。这些错误可能是无害的,但是,往往不是这样的,它们可能导致问题。通过设置功能策略,使用户与管理员互相配合,可以使个别的cron作业尽可能地不干扰其它的用户和系统功能。
可以给为单个用户或组分配的资源设置限制,但是,这是下一篇文章中的内容。
更多信息,在cron、crontab、anacron、anacrontab、和run-parts的man页面上,所有的这些信息都描述了cron系统是如何工作的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。