当前位置: 首页 > Linux

Linux基本命令介绍十四:定时任务

时间:2023-04-06 11:57:42 Linux

在使用电脑的过程中,经常会有一些计划好的任务需要在未来的某个时间执行。Linux提供了一些设置定时任务的方法。1、at命令at从文件或标准输入中读取命令,并在以后的某一时刻执行,只执行一次。at的正常执行需要守护进程atd(systemctl见这篇文章):#installatyuminstall-yatorapt-getinstallat-y#启动守护进程serviceatdstartorsystemctlstartatd#查看是否启动chkconfig--list|grepatdorsystemctllist-unit-files|grepatd#Setbootchkconfig--level235atdonorsystemctlenableatd如果不使用管道|或者指定选项-f,at的执行会以交互方式执行,需要在at的提示符下输入命令:[root@centos7temp]#atnow+2minutes#Executeat并指定执行时间为上次当前时间的两分钟at>echohelloworld>/root/temporCommandatqquerytask[root@centos7temp]#atq9ThuDec2214:05:002016a任务在一个root到达时间后执行,生成一个新的文件file并保存echo的输出内容[root@centos7temp]#ls-lfile-rw-r--r--1rootroot12December2214:05file[root@centos7temp]#catfilehelloworld[root@centos7temp]#指定时间at的方式有很多种,可以是1)hh:mm时:分(当天,如果时间已过,则执行onthenextday)2)midnight(深夜)、noon(中午)、teatime(下午茶时间,下午4点)、今天、明天等3)12小时制,加上am(上午)或pm(afternoon)4)指定具体执行日期mm/dd/yy(月/日/年)或dd.mm.yy(day.month.year)5)相对计时方式now+nunits,now为当前时刻,n为数字,units为单位(分、时、日、周)如明天2:20pm创建目录[root@centos7temp]#at02:20pmtomorrowat>mkdir/root/temp/Xat>job11atFriDec2314:20:002016选项-d或命令atrm表示删除task[root@centos7temp]#at-d11#删除11号任务(上例)[root@centos7temp]#atq[root@centos7temp]#可以使用pipeline|或选项-f让at从标准输入或文件task[root@centos7temp]#cattest.txtechohelloworld>/root/temp/file[root@centos7temp]#at-ftest.txt5pm+2daysjob12atSatDec2417:00:002016[root@centos7temp]#cattest.txt|at16:2012/23/16job13atFriDec2316:20:002016atd通过两个文件/etc/at.allow和/etc/at.deny确定系统中哪些用户可以使用at设置定时任务。它首先检查/etc/at.allow。如果文件存在,则只有文件中列出的用户(每行一个用户名)可以使用at;如果不存在,则检查文件/etc/at.deny,所有不在该文件中的用户都可以使用at。如果/etc/at.deny是一个空文件,表示系统中所有用户都可以使用at;如果/etc/at.deny文件不存在,只有超级用户(root)可以使用at。2、crontab命令crontab用于设置、删除和列出服务crond表。crond服务的功能与atd类似。不同的是crond可以设置任务执行多次。相对比atd更常用。还需要启动服务crond[root@centos7temp]#ps-ef|grep[c]rondroot73310December20?00:00:00/usr/sbin/crond-n系统中的每个用户都可以有自己的cron表和atd类似,crond也有两个文件/etc/cron.allow和/etc/cron.deny来限制用户使用cron,规则同atd的两个文件。选项-l表示列出当前用户的cron表项。选项-u表示指定用户[root@centos7~]#crontab-l-ulearnernocrontabforlearner[root@centos7~]#选项-e表示编辑用户的cron表。编辑时,系统会选择默认的编辑器。在笔者的环境下,vi可以通过直接编辑文件/etc/crontab来设置系统级的cron表。使用crontab-e编辑时,会在/tmp下生成一个临时文件。保存后crond会将内容写入到/var/spool/cron下一个与用户名同名的文件中,保存时crond会进行语法检查。这也是设置cron任务的推荐用法。语法:*****command每一行代表一个任务,#开头的行代表注释,不生效。每条有效行如上图,一行分为6部分,其中:第一部分代表分钟(0-59),*代表每分钟,第二部分代表小时(0-23),*代表hourofeveryhour三部分代表天(1-31),*代表每一天,第四部分代表月份(1-12),*代表每个月,第五部分代表星期几(0-6,0代表星期天),*代表一周中的每一天第六部分表示要执行的任务。前五部分时间设置,除了*表示当前部分任意时间外,还支持其他三个符号/,,,-表示每一个区间,分别是时间点A和时间点B,时间点A到时间点B。例如每隔3分钟测试10.0.1.252的连通性,并将结果追加到/root/252.log[root@centos7~]#crontab-e*/3****/usr/bin/ping-之后c110.0.1.252&>>/root/252.log保存,会出现crontab:installingnewcrontab字样。请注意,这六个部分都不能为空。最好写命令的绝对路径。编辑普通用户的计划任务时,要注意命令的执行权限。比如1月到5月,每隔2、5的凌晨2点30执行一次备份任务302*1-52,5/bin/bash/root/temp/backup.sh这里写入备份任务到script/root中执行/temp/backup.sh比如March-June和September-December,每周一到周五12:00-14:00,每2分钟执行一次刷新任务*/212-14*3-6,9-121-5/bin/bash/root/temp/refresh.sh通过混合日期和时间以及特殊符号,您可以组合最需要的时间。查看定时任务[root@centos7~]#crontab-l*/3****/usr/bin/ping-c110.0.1.252&>>/root/252.log302*1-52,5/bin/bash/root/temp/backup.sh*/212-14*3-6,9-121-5/bin/bash/root/temp/refresh.shoption-r表示删除定时任务[root@centos7~]#crontab-r[root@centos7~]#crontab-lnocrontabforroot使用crontab时经常遇到的问题之一是无法设置在命令行下可以正常执行的命令或脚本定时任务已设置。正常执行。出现这种情况的原因一般是因为crond为命令或脚本设置了与登录shell不同的环境变量[root@centos7~]#head-3/etc/crontabSHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root[root@centos7~]#[root@centos7~]#echo$PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin[root@centos7~]#这里crond的PATH与shell中的值不同,PATH环境变量定义了shell执行命令时搜索命令的路径。更多关于环境变量的内容将在shell编程一文中详细介绍。对于系统级的定时任务,这些任务比较重要。大多数linux系统在/etc中包含了一系列cron相关的子目录:/etc/cron.{hourly,daily,weekly,monthly},目录下的文件定义了每小时、每天、每周、每月需要运行的脚本.运行这些任务的准确时间在文件/etc/crontab中指定。如:SHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=rootHOME=/#run-parts01****rootrun-parts/etc/cron.hourly024***rootrun-parts/etc/cron.daily224**0rootrun-parts/etc/cron.weekly4241**rootrun-parts/etc/cron.monthly定期运行保证服务器的稳定性。但是请注意,这些任务通常在凌晨执行。对于经常需要关机的Linux电脑(比如笔记本),很可能在需要运行cron的时候就处于关机状态。减速。针对这样的系统,Linux引入了另一个工具anacron来负责执行系统定时任务。anacron的目的不是要完全取代cron,而是作为cron的一个补充。anacron任务在文件/etc/anacrontab中定义:#/etc/anacrontab:anacron的配置文件#详情请参阅anacron(8)和anacrontab(5)。SHELL=/bin/shPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root#添加到作业基本延迟的最大随机延迟RANDOM_DELAY=45#作业将仅在接下来的几个小时内启动START_HOURS_RANGE=3-22#periodindaysdelayinminutesjob-identifiercommand15cron.dailynicerun-parts/etc/cron.daily725cron.weeklynicerun-parts/etc/cron.weekly@monthly45cron.monthlynicerun-parts/etc/cron.monthlywithcronasdaemon不同进程运行,anacron作为正常进程运行和终止。对于定义的每一个任务,anacron都会检查系统启动后应该运行的任务,判断从上次运行到现在的时间是否超过了预定的天数(/etc/anacrontab中任务行第一列),如果大于预定天数,任务将延迟运行(/etc/anacrontab中任务行的第二列)。这确保了任务的执行。关于anacron的更多信息,请参考相关文档。3.systemd.timercrond和atd服务是基于分钟的,这意味着他们每分钟醒来检查是否有任务要执行。如果任务的执行需要精确到秒,crond和atd无能为力。在基于systemd的系统上,计时器systemd.timer可用于实现精确到秒的计划任务。在上一篇文章中,我们提到了systemd中服务单元的概念,这里我们需要用到其中的两个:.service和.timer。其中.service负责配置需要运行的任务,.timer负责配置执行时间。先看一个例子:创建任务脚本[root@centos7temp]#cat/root/temp/ping252.sh#!/bin/bashping-c110.0.1.252&>>/root/temp/252.log配置服务。service[root@centos7temp]#cd/usr/lib/systemd/system[root@centos7system]#catping252.service[Unit]Description=ping252[Service]Type=simpleExecStart=/root/temp/ping252.sh[root@centos7system]#配置timer.timer[root@centos7temp]#cd/usr/lib/systemd/system[root@centos7system]#catping252.timer[单位]说明=ping252every30s[Timer]#启用此单元后等待的时间OnActiveSec=60#每次连续运行之间的时间timeOnUnitActiveSec=30Unit=ping252.service[Install]WantedBy=multi-user.target[root@centos7system]#Enabletimer[root@centos7system]#systemctl启用ping252.timerCreated从/etc/systemd/system/multi-user.target.wants/ping252.timer到/usr/lib/systemd/system/ping252.timer的符号链接。[root@centos7system]#systemctlstartping252.timerView#Timer[root@centos7system]#systemctlstatusping252.timerping252.timer-每30秒ping252已加载:已加载(/usr/lib/systemd/system/ping252.timer;已启用;供应商预设:已禁用)活动:活动(等待)自五2016-12-2314:27:26CST;3分钟42秒前12月23日14:27:26centos7systemd[1]:每30秒开始ping252。12月23日14:27:26centos7systemd[1]:每30秒开始ping252。#服务[root@centos7system]#systemctlstatusping252●ping252.service-ping252已加载:已加载(/usr/lib/systemd/system/ping252.service;静态;供应商预设:禁用)活动:活动(运行)自五2016-12-2314:中部标准时间35:38;2ms前MainPID:11494(ping252.sh)CGroup:/system.slice/ping252.service└─11494/bin/bash/root/temp/ping252.sh12月2314:35:38centos7systemd[1]:Startedping252.12月2314:35:38centos7systemd[1]:开始ping252...停止使用[root@centos7system]#systemctldisableping252.timer删除符号链接/etc/systemd/system/multi-user.target。wants/ping252.timer.[root@centos7system]#systemctlstopping252.timer[root@centos7system]#开启定时器1分钟后,生成/root/temp/252.log文件,然后每隔30秒,将内容写入systemd的服务单元配置文件,由不同的标签分隔成不同的配置块,其中:[Unit]标签指定不依赖于特定类型的通用配置信息。例如,示例中的两个文件都指定了一个选项Description=来指示描述信息。本单元的安装信息保存在[Install]标签下,其中WantedBy=表示使用systemctlenable命令启用本单元时,会在指定目标的.wants/或.requires/下创建对应的符号链接(如上例所示)。这样做的结果是该单元将在指定目标启动时启动。除了这两个可以在所有配置文件中设置的标签(其他选项可以通过命令man5systemd.unit查看),每个服务单元还有一个特定单元类型的标签,比如.service中的[我们示例服务中的文件]和.timer文件中的[Timer]。[Service]标签下Type=后的值表示执行方式。设置为simple,配合ExecStart=表示指定的程序(本例中的脚本)不会被fork()启动;如果设置为oneshot,则只会执行一次(类似于at),如果想让systemd在服务进程退出后仍然认为服务是活跃的,还需要设置RemainAfterExit=yes。其他选项请使用命令man5systemd.service查看【定时器】选项卡。您可以指定各种单调计时器。所谓“单调时间”是指从上电(零)那一刻起,只要系统在运行,时间就会持续单调均匀递增(但这个时间在系统休眠时保持不变),永远不会倒退,并且与时区无关。即使用户在系统运行过程中向前/向后修改系统时间,也不会对“单调时间”产生任何影响。其中:OnActiveSec=表示相对于本单元开启的时间点OnBootSec=表示相对于机器启动的时间点OnStartupSec=表示相对于systemd首次启动的时间点OnUnitActiveSec=表示相对于匹配单元(该标签下Unit=指定单元)最后启动的时间点OnUnitInactiveSec=表示匹配单元(该标签下Unit=指定的单元)最后停止的时间点。在我们的例子中,其中两个OnActiveSec=60和OnUnitActiveSec都使用了=30指定这个unit在unit=60秒后调用unit,在unit启用后每隔30秒再enable一次,达到目的定时和定期执行。这些定时器后面指定的时间单位可以是:us(微秒)、ms(毫秒)、s(秒)、m(分钟)、h(小时)、d(天)、w(周)、month(月),y(年)。如果省略单位,则使用默认单位“秒”。可以写成5h30min,表示接下来的5小时30分钟。在【定时器】选项卡下,还可以根据挂钟时间设置日历定时器OnCalendar=。所谓“挂钟时间”,是指现实世界中挂钟的时间。在操作系统中,其实就是系统时间。这个时候是操作系统在启动时从主板上的时钟芯片读取的。由于这个时间可以手动修改,所以这个时间不一定是单调递增,也不一定是匀速递增。它的时间格式可以是:Thu,Fri2012-*-1,511:12:13#表示2012年任意一个月的1号和5号,如果是星期四或星期五,则在11:12执行:13*-*-**:*:00#表示每分钟*-*-*00:00:00#表示每天*-01,07-0100:00:00#表示每半年*:0/15#表示每15分钟12,14,13:20,10,30#表示12/13/14点的10分钟,20分钟,30分钟Mon,Fri*-01/2-01,03*:30:45#meansany在一年中奇数月的1号和3号,如果是周一或周五,单调定时器和日历定时器将以每小时30分45秒的速度执行。其他内容可以在命令后指定man7systemd.timequeryUnit=这个定时器关联的服务单元(我们的例子中是ping252.service)。服务单元中的大部分设置选项都可以指定多次,没有冲突才会生效。例如.timer中可以设置多个Unit,表示这些服务单元共用一个定时器。另外,选项Persistent=也可以设置在[Timer]标签下,只对OnCalendar=命令定义的日历定时器有意义。如果设置为yes(默认为no),表示将匹配单元的最后一次触发时间永久保存在磁盘中。这样,当定时器单元再次启动时,如果在定时器单元停止期间应该启动至少一次的匹配单元,则立即启动。这样您就不会因为关机而错过必须完成的任务。(类似anacron的功能)更多关于定时器的选项可以通过mansystemd.timer查看。使用systemd.timer设置定时任务可以替代atd和crond的所有功能。此外,systemd还接管了很多其他的服务,这超出了本文的范围,如果以后的文章涉及到相关内容,会有相应的介绍。