- Linux系统上提供了多个在预选时间运行脚本的方法:
at
命令和cron
表,每个方法都使用不同的技术来安排脚本的运行时间和频率;
at
命令允许指定Linux系统何时运行脚本,at
命令会将作业提交到队列中,指定shell何时运行该作业,at
的守护进程atd
会以后台模式运行,检查作业队列来运行作业;atd
守护进程会检查系统上的一个特殊目录(通常位于/var/spool/at
)来获取用at
命令提交的作业,通常情况下,atd
守护进程会每60秒检查一下这个目录,有作业时,std
守护进程会检查作业设置运行的时间,如果时间跟当前时间匹配,atd
守护进程就会运行此作业;
at [ if filename ] time
;at
命令会将STDIN
的输入放在队列中,可以使用-f
参数来指定用于读取命令(脚本文件)的文件名:如:at -f test now
;time
参数指定了Linux系统何时运行该作业,如果你指定的时间已经错过,at
命令会在第二天的那个时间运行指定的作业;
at 命令能识别多种不同的时间格式 |
at 可以通过不同的日期格式指定特定的日期 |
---|---|
标准的小时和分钟格式:如:10:12 | 标准日期格式:如:MMDDYY、MM/DD/YY、DD.MM.YY |
AM/PM指示符:比如:10:12PM | 文本日期,如:Jul 4或 Dec 25加不加年份均可 |
特定可命名时间:如:now、noon、midnight、teatime(4PM) | 可以指定时间增量:当前时间+25min;明天10:14PM;10:12+7天 |
- 在使用
at
命令时,该作业会被提交到作业队列,作业队列会保存通过at
命令提交的待处理的作业,针对不同优先级,存在26种不同的作业队列,作业队列通常用小写字母az和大写字母AZ来指代,作业队列的字母排序越高,作业运行的优先级就越低,通常情况下,at
的作业会被提交到a
作业队列,如果想以更高优先级运行作业,可以使用-q
选项指定不同的队列字母;
- 当作业在Linux系统上运行时,显示器并不会关联到该作业,取而代之得是,Linux系统会将提交该作业的用户的电子邮件地址作为
STDOUT
和STDERR
,任何发送到STDOUT
或STDERR
的输出都会通过邮件系统发送给该用户如:
echo "this script ran at $(date + %B%d , %T)"
echo
sleep 4
echo "this is the script's end......"
- 使用该脚本:
at -f test now
;at
命令会显示分配给作业的作业号以及为作业安排的运行时间,-f
选项指明使用哪个脚本文件,now
指示at
命令立刻执行该脚本;使用邮件作为输出机器不方便,如果没有邮件将会收不到输出,所以,最好在脚本中对STDOUT
和STDERR
进行重定向;如:
echo "this script ran at $(date + %B%d , %T)" >test.out
echo >>test.out
sleep 5
echo "this is the script's end......">>test.out
- 使用该脚本:
at -M -f test now
;将输出重定向到test.out文件中,如果不想在at
命令中使用邮件或重定向,最好加上-M
选项来屏蔽作业产生的输出信息;
atq
命令可以查看系统中有哪些作业在等待;使用该命令会显示作业号、系统运行该作业的日期和时间及其所在的作业队列;
- 一旦知道了哪些作业在作业队列中等待,就能使用
atrm
命令来删除等待中的作业;atrm 作业号
:只要指定想要删除的作业号就行了,只能删除你提交的作业,不能删除别人提交的作业;
- Linux系统使用
cron
程序来安排要定期执行的作业,cron
程序会在后台运行并检查一个特殊的表(被称为cron时间表),以获取已安排执行的作业;
- cron时间表采用一种特殊的格式来指定作业何时运行:格式如下:
min hour dayofmonth month dayofweek command
;cron时间表允许你用特定值、取值范围如:1~5或者通配符*来指定条目,例如:如果想在每天的10:15运行一个命令,可以用cron时间表条目:15 10 * * * command
:在dayofmonth、month、dayofweek字段中使用了通配符,表明cron会在每个月每天的10:15执行该命令;指定在每周一4:15PM运行命令:15 16 * * 1 command
:可以使用三字符的文本值(mon、tue、wed、thu、fri、sat、sun)或数值(0为周日,6为周六)来指定dayofweek表项;在每个月的第一天中午12点执行命令00 12 1 * * command
:dayofmonth表项指定月份中的日期值(1到31);设置每个月的最后一天,通常的办法是加一条使用date命令的if-then语句来检查明天的日期是不是01:00 12 * * * if[ 'date +%d -d tomorrow' = 01] ;then;command
;命令列表必须指定要运行的命令或脚本的全路径名:12 13 * * * /home/ningbaoqi/test >test.out
;cron程序会用提交作业的用户账户运行该脚本,因此,你必须有访问该命令和命令中指定的输出文件的权限;
- 每个系统用户(包括root用户)都可以用自己的cron时间表来运行安排好的任务,
crontab
命令来处理cron时间表,要列出已有的cron时间表,可以使用-l
选项;默认情况下,用户的cron时间表文件并不存在,要为cron时间表添加条目,可以使用-e
选项,在添加条目时,crontab命令会启动一个文本编辑器,使用已有的cron时间表作为文件内容(或者一个空文件,如果时间表不存在的话);
- 如果你创建的脚本对精确的执行时间要求不高,用预配置的cron脚本目录更方便,有4个基本目录hourly、daily、monthly、weekly;使用
ls /etc/cron.*ly
可以查看这几个基本目录;因此,如果脚本需要每天运行一次,只要将脚本复制到daily目录,cron就会每天执行它;
- 如果某个作业在cron时间表中安排运行的时间已到,但这时候Linux系统处于关机状态,那么这个作业就不会被运行,当系统开机时,cron程序不会再去运行那些错过的作业,要解决这个问题,使用
anacron
程序;如果anacron
知道某个作业错过了执行时间,它会尽快运行该作业,这意味着如果Linux系统关机了好几天,当它再次开机时,原定的关机期间运行的作业会自动运行;这个功能常用于进行常规日志维护的脚本;anacron
程序只会处理位于cron目录的程序,如:/etc/cron.monthly
,他会用时间戳来决定作业是否在正确的计划间隔内运行了,每个cron目录都会有个时间戳文件,该文件位于/var/spool/anacron
;anacron
程序会使用自己的时间表(位于/etc/anacrontab
)来检查作业目录:sudo cat /etc/anacrontab
;
anacrontab时间表的基本格式 |
---|
anacron时间表的基本格式和cron时间表略有不同:period delay identifier command |
period条目定义了作业多久运行一次,以天为单位,anacron程序用此条目来检查作业的时间戳文件 |
delay条目会指定系统启动后anacron程序需要等待多少分钟再开始运行错过的脚本 |
identifier条目是一个特殊的非空字符串,如cron.weekly,它用于唯一标识日志消息和错误邮件中的作业 |
command条目包含了run-parts程序和一个cron脚本目录名,run-parts程序负责运行目录中传给它的任何脚本 |
- anacron不会运行位于/etc/cron.hourly的脚本,因为anacron程序不会处理执行时间需求小于一天的脚本;
- 因为登录bash shell需要启动启动文件,并且按照顺序运行第一个文件,其余文件被忽略,文件顺序如下:
$HOME/.bash_profile
;$HOME/.bash_login
;$HIME/.profile
; 因此,应该将需要登录时运行的脚本放在上面的第一个文件中;每次启动一个新shell时,bash shell都会运行.bashrc文件,.bashrc文件通常也是通过某个bash启动文件来运行的,因为.bashrc文件会运行两次,一次是当你登录bash shell时,另一次是当你启动了一个bash shell时,如果你需要一个脚本在两个时刻都得到运行,就把这个脚本放进该文件中;