以下内容适用于centos6.10,其他版本暂时不清楚。
1、at一次执行
通过at执行的任务,只能在定义的时间点执行一次,并不能循环执行,at服务一般是linux中默认安装好的,而且在3、4、5运行级别都是默认开启的。
①、at的访问控制
- 如果系统中有/etc/at.allow文件,那么只有写入/etc/at.allow文件(白名单)中的用户可以使用at命令(/etc/at.deny文件会被忽略)
- 如果系统中没有/etc/at.allow文件,只有/etc/at.deny文件,那么写入/etc/at.deny文件(黑名单)中的用户不能使用at命令。对root用户不起作用
- 如果系统中这两个文件都不存在,那么只有root用户可以使用at命令
②、at命令格式
at [选项] 时间
选项:
-m: 当at工作完成后,无论是否命令有输出,都用email通知执行at命令的用户
-c 工作号: 显示该at工作的实际内容
时间:
-HH:MM 例如:02:30
-HH:MM YYYY-MM-DD 例如:02:30 2018.11.20
-HH:MM[am|pm] [month] [date] 例如:02:30pm November 20
-HH:MM[am|pm] + [minutes|hours|days|weeks] 例如:now + 5 minutes
③、其他at管理命令
atq
#查询当前服务器上的at工作
atrm [工作号]
#删除指定的at任务
实例为:
2、crontab循环定时任务
crontab是服务器上的一个常规操作,是linux中默认安装好的服务,默认是2、3、4、5运行级别自启动的,需要熟练掌握。
crontab与at命令相比,可以执行at命令不能执行的循环任务。
①、crontab的访问控制
- 当系统中有/etc/cron.allow文件时,只有写入此文件的用户可以使用crontab命令,没有写入的用户不能使用crontab命令。同样如果有此文件,/etc/cron.deny文件会被忽略,/etc/cron.allow文件的优先级更高
- 当系统中只有/etc/cron.deny文件时,则写入此文件的用户不能使用crontab命令,没有写入文件的用户可以使用crontab命令
②、用户的crontab设置
crontab [选项]
选项:
-e: 编辑crontab定时任务
-l: 查询crontab任务
-r: 删除当前用户所有的crontab任务
crontab -e会以当前登录用户的身份打开一个空文件(会打开vim编辑你的工作),进入crontab编辑界面。
③、crontab命令的格式
* * * * * 要执行的任务
前面的5个"*"的含义如下面的表格所示:
项目 | 含义 | 时间范围 |
第一个“*” | 一小时中的第几分钟 | 0到59 |
第二个“*” | 一天中的第几小时 | 0到23 |
第三个“*” | 一个月当中的第几天 | 1到31 |
第四个“*” | 一年当中的第几个月 | 1到12 |
第五个“*” | 一周当中的星期几 | 0到7(0和7都代表星期日) |
一些特殊符号的含义:
特殊符号 | 含义 |
* | 代表任何时间。比如第一个“*”就代表一小时中每分钟都执行一次的意思 |
, | 代表不连续的时间。比如:“0 8,12,16 * * * 命令”,代表每天的8点0分,12点0分,16点0分都执行一次命令 |
- | 代表连续的时间范围。比如:“0 5 * * 1-6 命令”,代表在周一到周六的凌晨5点0分执行命令 |
*/n | 代表每隔多久执行一次。比如:“*/10 * * * * 命令”,代表每隔10分钟就执行一遍命令 |
一些例子:
crontab命令 | 含义 |
45 22 * * * 命令 | 在22点45分执行命令 |
0 17 * * 1 命令 | 每周1的17点0分执行命令 |
0 5 1,15 * * 命令 | 每月1号和15号的凌晨5点0分执行命令 |
40 4 * * 1-5 命令 | 每周一到周五的凌晨4点40分执行命令 |
*/10 4 * * * 命令 | 每天的凌晨4点,每隔10分钟执行一次命令 |
0 0 1,15 * 1 | 每月1号和15号,每周1的0点0分都会执行命令。 注意:星期几和几号最好不要同时出现,因为他们定义的都是天。非常容易让管理员混乱。 |
④、常用的crontab命令
crontab -l
#查看root用户的crontab任务
crontab -r
#删除root用户所有的定时任务
实例:
⑤、crontab注意事项
- 六个选项不能为空,必须填写。如果不确定,使用“*”代表任意时间
- crontab定时任务,最小有效时间是分钟,最大时间范围是月。像2018年某时执行,3点30分30秒这样的时间都不能识别
- 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为他们都是用天作单位,非常容易让管理员混淆
- 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都用绝对路径
3、系统的crontab设置
上节的crontab -e命令是与用户相关的,也就是说不同的用户身份可以执行自己的定时任务。可是有些定时任务需要系统执行,这时我们就需要编辑/etc/crontab这个配置文件了。这样做的好处是可以任意指定定时任务执行者的身份,而不用像crontab -e命令那样必须绑定当前登录者的身份。在centos6.10中,/etc/crontab文件的初始内容如下:
当然centos6.10中还有个更简单的方法,当然也是很粗略的定时任务执行方法,这涉及到如下的几个目录:
- /etc/cron.daily/
- /etc/cron.hourly/
- /etc/cron.monthly/
- /etc/cron.weekly/
进入/etc/cron.daily目录,可以看到有如下一些系统默认已经放入的可执行文件:
这些可执行文件每天都能够自动执行一次(只要服务器没关机),因此,可以最简单的crontab任务执行方法是将用户自己的可执行文件直接移动到对应的这几个目录下,就能根据目录的时间属性自动执行相应的crontab定时任务。这简直不要太方便啊!!!
4、anacron配置及总结
①、anacron是什么?
anacron是用来保证在系统关机的时候错过的定时任务,可以在系统开机之后再执行。
②、anacron检测周期
- anacron会使用一天,七天,一个月作为检测周期
- 在系统的/var/spool/anacron/目录中存在cron.{daily,weekly,monthly}文件,用于记录上次执行crontab的时间
- 和当前时间作比较,如果两个时间的差值超过了anacron的指定时间差值,证明crontab任务错过了执行
③、centos6.x的区别
- 在老的centos版本中,/etc/cron.{daily,weekly,monthly}这些目录会被crontab调用,也会被anacron调用,容易重复执行
- 在centos6.x中则只会被anacron调用,避免了重复执行
- 在centos6.x中,anacron不再是服务,而是系统命令
④、/etc/anacrontab文件的内容解析
/etc/anacrontab文件的内容如下:
其中:
- RANDOM_DELAY=45 #最大随机延迟
- START_HOURS_RANGE=3-22 #anacron的执行时间范围是3:00到22:00
用户目录下都有cron.daily之类的文件夹,里面的可执行文件每天都会被执行一次。也就是说如果想添加一个每天都被执行的任务的话,在目录下放置该任务的脚本即可。使用很方便,原理是什么呢,就是run-parts命令。
run-parts命令位于/usr/bin/run-parts,内容是很简单的一个shell脚本,就是遍历目标文件夹,执行第一层目录下的可执行权限的文件。该脚本文件的内容如下:
#!/bin/bash
# run-parts - concept taken from Debian
# keep going when something fails
set +e
if [ $# -lt 1 ]; then
echo "Usage: run-parts <dir>"
exit 1
fi
if [ ! -d $1 ]; then
echo "Not a directory: $1"
exit 1
fi
# Ignore *~ and *, scripts
for i in $(LC_ALL=C; echo $1/*[^~,]) ; do
[ -d $i ] && continue
# Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} scripts
[ "${i%.cfsaved}" != "${i}" ] && continue
[ "${i%.rpmsave}" != "${i}" ] && continue
[ "${i%.rpmorig}" != "${i}" ] && continue
[ "${i%.rpmnew}" != "${i}" ] && continue
[ "${i%.swp}" != "${i}" ] && continue
[ "${i%,v}" != "${i}" ] && continue
# jobs.deny prevents specific files from being executed
# jobs.allow prohibits all non-named jobs from being run.
# can be used in conjunction but there's no reason to do so.
if [ -r $1/jobs.deny ]; then
grep -q "^$(basename $i)$" $1/jobs.deny && continue
fi
if [ -r $1/jobs.allow ]; then
grep -q "^$(basename $i)$" $1/jobs.allow || continue
fi
if [ -x $i ]; then
if [ -r $1/whitelist ]; then
grep -q "^$(basename $i)$" $1/whitelist && continue
fi
logger -p cron.notice -t "run-parts($1)[$$]" "starting $(basename $i)"
$i 2>&1 | awk -v "progname=$i" \
'progname {
print progname ":\n"
progname="";
}
{ print; }'
logger -i -p cron.notice -t "run-parts($1)" "finished $(basename $i)"
fi
done
exit 0
因此,将用户自己的可执行脚本放入/etc/cron.{daily,weekly,monthly}中就不用担心由于服务器宕机或者关机造成的定时任务错过执行的情况,而且整个过程几乎不用人来参与,非常方便,唯一的缺点是错过执行的文件具体在哪个时间点补充执行是不确定的。