在计算机的使用过程中,经常会有一些计划中的任务需要在将来的某个时间执行,linux中提供了一些方法来设定定时任务。
1、at
命令at从文件或标准输入中读取命令并在将来的一个时间执行,只执行一次。at的正常执行需要有守护进程atd:
#安装at yum install -y at 或 apt-get install at -y #启动守护进程 service atd start 或 systemctl start atd #查看是否开机启动(关于systemctl请看这一篇) chkconfig --list|grep atd 或 systemctl list-unit-files|grep atd #设置开机启动 chkconfig --level 235 atd on 或 systemctl enable atd</div>
如果不使用管道|或指定选项-f的话,at的执行将会是交互式的,需要在at的提示符下输入命令:
[root@centos7 temp]# at now +2 minutes #执行at并指定执行时刻为现在时间的后两分钟 at> echo hello world > /root/temp/file #手动输入命令并回车 at> <EOT> #ctrl+d 结束输入 job 9 at Thu Dec 22 14:05:00 2016 #显示任务号及执行时间 [root@centos7 temp]#</div>
选项-l或命令atq查询任务
[root@centos7 temp]# atq 9 Thu Dec 22 14:05:00 2016 a root</div>
到达时间后任务被执行,生成一个新文件file并保存echo的输出内容
[root@centos7 temp]# ls -l file -rw-r--r-- 1 root root 12 12月 22 14:05 file [root@centos7 temp]# cat file hello world [root@centos7 temp]#</div>
at指定时间的方法很丰富,可以是
1)hh:mm小时:分钟(当天,如果时间已过,则在第二天执行)
2)midnight(深夜),noon(中午),teatime(下午茶时间,下午4点),today,tomorrow等
3)12小时计时制,时间后加am(上午)或pm(下午)
4)指定具体执行日期mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年)
5)相对计时法now + n units,now是现在时刻,n为数字,units是单位(minutes、hours、days、weeks)
如明天下午2点20分执行创建一个目录
[root@centos7 temp]# at 02:20pm tomorrow at> mkdir /root/temp/X at> <EOT> job 11 at Fri Dec 23 14:20:00 2016</div>
选项-d或命令atrm表示删除任务
[root@centos7 temp]# at -d 11 #删除11号任务(上例) [root@centos7 temp]# atq [root@centos7 temp]#</div>
可以使用管道|或选项-f让at从标准输入或文件中获得任务
[root@centos7 temp]# cat test.txt echo hello world > /root/temp/file [root@centos7 temp]# at -f test.txt 5pm +2 days job 12 at Sat Dec 24 17:00:00 2016 [root@centos7 temp]# cat test.txt|at 16:20 12/23/16 job 13 at Fri Dec 23 16:20:00 2016</div>
atd通过两个文件/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@centos7 temp]# ps -ef|grep [c]rond root 733 1 0 12月20 ? 00:00:00 /usr/sbin/crond -n</div>
系统中每个用户都可以拥有自己的cron table,同atd类似,crond也有两个文件/etc/cron.allow和/etc/cron.deny用来限制用户使用cron,规则也和atd的两个文件相同。
选项-l表示列出当前用户的cron表项
选项-u表示指定用户
[root@centos7 ~]# crontab -l -u learner no crontab for learner [root@centos7 ~]#</div>
选项-e表示编辑用户的cron table。编辑时系统会选定默认编辑器,在笔者的环境中是vi
通过直接编辑文件/etc/crontab可以设置系统级别的cron table。
使用crontab -e的方式编辑时,会在/tmp下面生成一个临时文件,保存后crond会将内容写入到/var/spool/cron下面一个和用户名同名的文件中,crond会在保存时做语法检查。这也是推荐的设置定时任务的用法。
语法:
* * * * * command
每一行表示一个任务,以符号#开头的行表示注释,不生效。每个生效行都形如上面所示,一行被分为6部分,其中:
第一部分表示分钟(0-59),* 表示每分钟
第二部分表示小时(0-23),* 表示每小时
第三部分表示日(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 -c1 10.0.1.252 &>> /root/252.log</div>
保存后会有crontab: installing new crontab字样出现。注意六个部分都不能为空,命令最好写绝对路径,编辑普通用户的定时任务时,要注意命令的执行权限。
如一月份到五月份,每周2和周5凌晨2:30执行备份任务
30 2 * 1-5 2,5 /bin/bash /root/temp/backup.sh
这里将备份任务写入到脚本/root/temp/backup.sh中执行
如3-6月和9-12月,每周一到周五12点到14点,每2分钟执行一次刷新任务
*/2 12-14 * 3-6,9-12 1-5 /bin/bash /root/temp/refresh.sh
混合使用日期时间及特殊符号,可以组合出大多数想要的时间。
查看定时任务
[root@centos7 ~]# crontab -l */3 * * * * /usr/bin/ping -c1 10.0.1.252 &>> /root/252.log 30 2 * 1-5 2,5 /bin/bash /root/temp/backup.sh */2 12-14 * 3-6,9-12 1-5 /bin/bash /root/temp/refresh.sh</div>
选项-r表示删除定时任务
[root@centos7 ~]# crontab -r [root@centos7 ~]# crontab -l no crontab for root</div>
使用crontab时经常会遇到的一个问题是,在命令行下能够正常执行的命令或脚本,设置了定时任务时却不能正常执行。造成这种情况的原因一般是因为crond为命令或脚本设置了与登录shell不同的环境变量
[root@centos7 ~]# head -3 /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root [root@centos7 ~]# [root@centos7 ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@centos7 ~]#</div>
这里crond的PATH和shell中的值不同,PATH环境变量定义了shell执行命令时搜索命令的路径。关于环境变量更多的内容,将在shell编程的文章里详细说明。
对于系统级别的定时任务,这些任务更加重要,大部分linux系统在/etc中包含了一系列与 cron有关的子目录:/etc/cron.{hourly,daily,weekly,monthly},目录中的文件定义了每小时、每天、每周、每月需要运行的脚本,运行这些任务的精确时间在文件/etc/crontab中指定。如:
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # run-parts 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly</div>
对于24小时开机的服务器来说,这些任务的定期运行,保证了服务器的稳定性。但注意到这

