延迟进程调度
前言:大部分时候,我们都希望进程快点開始,开点结束,别卡.而shell的运行,也是在前一个命令后,立即接着运行下一个命令.命令完毕的速度是与资源的限制有关,且不在shell的权限下.
在交谈模式中使用下,有时不必等到命令完毕才干运行还有一个.这是shell提供的一个简单方式:全部的命令仅仅要在最后加上&字符,都可起始于后台运行,无需等待.仅仅有在少数情况下,必须等待后台进程完毕.
稍稍有四种情况须要延时进程事实上,知道未来的某个事件才运行.
第一种 sleep
sleep命令经常使用于在shell脚本中延迟时间
经常使用方式:
格式:sleep<n>
格式:sleep<n>s
作用效果:延迟<n>秒
格式:sleep<n>m
作用效果:延迟n分钟
格式:sleep<n>h
作用效果:延迟n小时
格式:sleep<n>d
作用效果:延迟n天
注意:<n>能够是小数
案例
# date;sleep 5;date
2015年 07月 29日 星期三 15:40:32 CST
2015年 07月 29日 星期三 15:40:37 CST
at:延迟至特定时间
在win系统中,win提供了计划任务这一功能,在控制面板->性能与维护->任务计划,它的功能就是安排自己主动执行的任务.通过”加入任务计划”的一步步引导,则可建立一个定时执行的任务.
在linux系统中你可能已经发现为什么系统经常会自己主动的进行一些任务?
这些任务究竟是谁在支配他们工作的?
在linux系统假设你想让自己设计的备份程序能够自己主动的在某个时间点開始在系统低下执行,而不须要收到启动它,又该怎样处置呢?
这些例行的工作可能又分为一次性定时工作与循环定时工作,在系统内有时那些服务在负责?还有,假设你想要在每天的老婆过生日的时候送份礼物,一个老婆可能还好说,假设一多了,easy记不住,还easy记混了.
进入正题
at命令的格式:
at [參数] [时间]
功能:在一个指定的时间指定一个指定任务,仅仅能运行一次,且须要开启atd进程.
备注:先使用ps -ef | grep atd查看,开启用/etc/init.d/atd start或者/etc/init.d/atd restart;开机自启动:chkconfig --level 2345 atd on
參数:
名称 | 说明 |
-m | 当指定的任务被完毕之后,将给用户发送邮件,即使没有标准输出 |
-I | atq的别名 |
-d | atrm的别名 |
-v | 显示任务将被运行的时间 |
-c | 打印任务的任荣到标准输出 |
-V | 显示版本号信息 |
-q<队列> | 使用指定的队列 |
-f<文件> | 从指定文件读入任务而不是从标准输入读入 |
-t<时间參数> | 以时间參数的形式提交要执行的任务 |
at同意使用一套相当复杂的指定时间的方法。他可以接受在当天的hh:mm(小时:分钟)式的时间指定。假如该时间已过去,那么就放在第二天运行。
当然也可以使用midnight(深夜),noon(中午),teatime(饮茶时间,通常是下午4点)等比較模糊的 词语来指定时间。用户还可以採用12小时计时制,即在时间后面加上AM(上午)或PM(下午)来说明是上午还是下午。 也可以指定命令运行的详细日期,指定格式为month day(月 日)或mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年)。指定的日期必须跟在指定时间的后面。 上面介绍的都是绝对计时法,事实上还可以使用相对计时法,这对于安排不久就要运行的命令是非常有优点的。指定格式为:now + count time-units ,now就是当前时间,time-units是时间单位,这里可以是minutes(分钟)、hours(小时)、days(天)、weeks(星期)。count是时间的数量,到底是几天,还是几小时,等等。
更有一种计时方法就是直接使用today(今天)、tomorrow(明天)来指定完毕命令的时间。
TIME:时间格式,这里能够定义出什么时候要进行 at 这项任务的时间,格式有:
HH:MM
ex> 04:00
在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此任务。
HH:MM YYYY-MM-DD
ex> 04:00 2009-03-17
强制规定在某年某月的某一天的特殊时刻进行该项任务
HH:MM[am|pm] [Month] [Date]
ex> 04pm March 17
也是一样。强制在某年某月某日的某时刻进行该项任务
HH:MM[am|pm] + number [minutes|hours|days|weeks]
ex> now + 5 minutes
ex> 04pm + 3 days
就是说,在某个时间点再加几个时间后才进行该项任务。
案例:三天后的下午五点钟运行/bin/ls
#at 5pm+3days
at> /bin/ls
at><EOT>
job 7 at 2015-07-28 17:00
案例2:明天17点钟,输出时间到指定文件里
#at 17:20 tomorrow
at> date>/root/2015.log
at> <EOT>(输入完毕须要按下Ctrl+D键)
job 8 at 2015-07-28 17:00
案例3:计划任务设定后,在没有运行之前我们能够用atq命令来查看系统没有运行工作任务命令:
#atq
案例4:删除已经设置的任务
#atrm 7
详情
#atq //先使用atq命令查看当前系统设置的任务
8 2015-07-28 17:00 a root
7 2015-07-28 17:00 a root
#atrm 7 //删除设置的任务
#atq //查看任务
8 2015-07-28 17:00 a root
案例5:显示已经设置的任务内容
#at -c 8
atd的启动与at执行的方式:
atd的启动
要使用一次性计划任务时,我们的linux系统上面必需要有负责这个计划任务的服务,那就是atd服务.只是并非全部的linux发行版本号都是默认把它打开的,所以,某些时刻我们需要手动将atd服务激活才行.激活的方式例如以下:
#/etc/init.d/atd start 或者#/etc/init.d/atd restart
停止atd:#/etc/init.d/atd stop
备注:设置一下自启动:#chkconfig atd on
at的执行方式
既然是计划任务。那么应该会有任务执行的方式,而且将这些任务排进行程表中。那么产生计划任务的方式是怎么进行的? 其实,我们使用 at 这个命令来产生所要执行的计划任务。并将这个计划任务以文字档的方式写入 /var/spool/at/ 文件夹内,该工作便能等待 atd 这个服务的取用与执行了。就这么简单。
只是,并非全部的人都能够进行 at 计划任务。
为什么? 由于系统安全的原因。
非常多主机被所谓的攻击破解后,最常发现的就是他们的系统其中多了非常多的黑客程序, 这些程序非常可能运用一些计划任务来执行或搜集你的系统执行信息,并定时的发送给黑客。 所以。除非是你认可的帐号,否则先不要让他们使用 at 命令。
那怎么达到使用 at 的可控呢?
我们能够利用 /etc/at.allow 与 /etc/at.deny 这两个文件来进行 at 的使用限制。加上这两个文件后。 at 的工作情况是这种:
先找寻 /etc/at.allow 这个文件。写在这个文件里的使用者才干使用 at 。没有在这个文件里的使用者则不能使用 at (即使没有写在 at.deny 其中);
假设 /etc/at.allow 不存在,就寻找 /etc/at.deny 这个文件,若写在这个 at.deny 的使用者则不能使用 at ,而没有在这个 at.deny 文件里的使用者。就能够使用 at 命令了。
假设两个文件都不存在,那么仅仅有 root 能够使用 at 这个命令。
透过这个说明。我们知道 /etc/at.allow 是管理较为严格的方式,而 /etc/at.deny 则较为松散 (由于帐号没有在该文件里,就行执行 at 了)。在一般的 distributions 其中。由于如果系统上的全部用户都是可信任的, 因此系统一般会保留一个空的 /etc/at.deny 文件,意思是同意全部人使用 at 命令的意思 (您可以自行检查一下该文件)。 只是,万一你不希望有某些使用者使用 at 的话,将那个使用者的帐号写入 /etc/at.deny 就可以! 一个帐号写一行。
batch:为资源控制而延迟
跟at一样也是定期运行的命令,使用方法也跟at同样,可是不同的是batch不须要指定时间,由于它会自己主动在系统负载比較低的时候运行(平均负载小于0.8的时候)
crontab:在指定时间再运行
上面具体说了at命令的使用方法,循环执行的例行性计划任务,linux系统则是由cron(crond)
这个系统服务来控制的.linux系统上面原本就有许多的计划性工作,因此这个系统服务是默认启动的.另外,因为使用者自己也能够设置计划任务,所以,linux系统也提供了使用者控制计划任务的命令:crontab命令.
crond简单介绍
crond四linux下用来周期性的运行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完毕操作系统后,默认会安装此项服务,而且会自启动crond进程,crond进程每分钟会定期检查是否又要运行的任务,假设有要运行的文物,则会自己主动运行该任务.
linux下的任务调度分为两类,系统任务调度和用户任务调度.
系统任务调度;系统周期性所要运行的工作,比方写缓存数据到硬盘,日志清理.在/etc文件夹下有一个crontab文件,这个就是系统任务调度的配置文件.以下我们来看一下/etc/crontab这个文件:
# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
前四行是用来配置crond任务运行的环境变量,第一行shell变量指定了系统要使用那个shell,这里是ba是,第二行PATH变量指定了系统运行命令的路径,第三行MAILTO变量指定了crond的任务运行信息将通过电子邮件发送给root用户,假设MAILTO变量的值为空,则表示不发送任务运行信息给用户,第四行的HOME变量指定了在运行命令或脚本时使用的主文件夹.
用户任务调度:用户定期要运行的工作,比方用户数据备份,定是邮件提醒等.用户能够使用crontab工具来定制自己的计划任务,全部用户定义的crontab文件都被保存在/var/spool/cron文件夹中.其文件名称和username一致.
使用者权限文件:
文件:
/etc/cron.deny //该文件里国所列出的用户不能使用crontab命令
文件:/etc/cron/allow //该文件里所列出用户同意使用crontab命令
文件:
/etc/spool/cron //全部用户crontab文件存放的文件夹,以username命名
crontab文件的含义:
用户所建立的crontab文件里,每一行都代表一项任务,每行的每一个字段代表一项设置,他的格式分为六个字段,前五个字段是时间设定段,第六个字段是要运行的命令字段,格式例如以下:
minute hour day month week command
当中:
minute: 表示分钟。能够是从0到59之间的不论什么整数。
hour:表示小时。能够是从0到23之间的不论什么整数。
day:表示日期。能够是从1到31之间的不论什么整数。
month:表示月份。能够是从1到12之间的不论什么整数。
week:表示星期几,能够是从0到7之间的不论什么整数,这里的0或7代表星期日。
command:要运行的命令,能够是系统命令,也能够是自己编写的脚本文件。
(盗的图....)
在以上各个字段中,还能够使用下面特殊字段:
星号(*):代表全部可能的值,比如mouth字段假设是星号,则表示在满足其它字段的制约条件后每月都运行该命令操作.
逗号(,):能够用逗号隔开的值制定一个列表范围,比如”1,2,3,4,,6,9”
中杠(-):能够用证书之间的中杠表示一个整数范围,比如”2-6”,表示”2,3,4,5,6”
正斜杠(/):能够用正斜杠指定时间的间隔频率,比如”0-23/2”表示每两小数运行一次.同一时候正斜杠能够和星号一起使用,比如*/10,假设用在minute字段,表示没十分钟运行一次.
crond服务
安装crontab:
#yum install crontabs
服务操作说明:
#/sbin/service crond start //启动服务
#/sbin/service crond stop //关闭服务
#/sbin/service crond restart //重新启动服务
#/sbin/service crond reload //又一次加载配置
查看crontab服务状态:
#service crond status
手动启动crontab服务:
#service crond start
查看crontab服务是否已设置为开机启动。运行命令:
#ntsysv
增加开机自己主动启动:
#chkconfig –level 35 crond on
crontab具体解释
格式:
crontab [-u user] file
crontab [-u user] [-e | -l |-r]
功能:
通过crontab命令,我们能够在固定的间隔时间运行指定的系统指令或shell脚本.时间间隔的单位能够是分钟,小时,日,月.周以及以上的随意组合.这个命令社尝试和周期性的日志分析或数据备份等工作.
參数:
选项名 | 说明 |
-u user | 用来设定某个用户的crontab服务,比如”-u syx”表示设定syx用户的crontab服务,这个參数一般有root用户来执行 |
file | file是命令文件的名字,表示将file作为crontab的任务列表问价并加载crontab.假设在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们加载crontab |
-e | 编辑某个用户的crontab文件内容.假设不指定用户,则表示编辑当前用户的crontab文件. |
-l | 显示某个用户的crontab文件内容,假设不指定用户,则表示显示当前用户的crontab文件内容 |
-r | 从/var/spool/cron文件夹中删除某个用户的crontab文件,假设不指定,你猜结果如何? |
-i | 在删除用户的crontan文件时给确认提示. |
经常用法
(1)创建一个新的crontab文件
在考虑向cron进程提交一个crontab文件时,首先要做的一件事情就是环境变量设置EDITOR.cron进程依据它来确定使用哪个编辑器编辑crontab文件.99%的linux用户都是用vi,假设你也是这样
那么你就编辑$HOME文件夹下.profile文件(假设没有,就是.bash_profile文件),在当中增加这样一行:EDITOR=vi;export EDITOR然后保存退出.最好还是创建一个名为<user>cron的文件,当中<user>是username,比如,syxcron.在该文件里增加例如以下的内容
# (put your own initials here)echo the date to the console every
# 15minutes between 6pm and 6am
0,15,30,45 * * * * /bin/echo 'date' > /dev/console
保存并退出.确保前面五个域用空格分隔.
在上面的样例中,系统每一个15分钟向控制台输出依次当前时间.假设系统崩溃或挂起,从最后所显示的时间就能够一眼看出系统是什么时间停止工作的.在有些系统中,用tty1来表示控制台.能够依据实际情况对上面的粒子进行对应的改动.为了提交你刚刚创建的crontab文件,能够把这个新创建的文件作为cron命令參数.
#crontab syxcron
如今该文件已经提交给cron进程,它每隔十五分钟执行一次.
同一时候,新创建的文件的一个副本已经被放在/var/spool/cron文件夹中,文件名称就是username(即syx)
注意:这里easy出现“bad minute”及“errors in crontab file, can't install”错误。
经确认,根本原因是crontab文件里时间格式定义不对导致的。
crontab时间格式内容
* * * * * command
M H D m d command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要执行的命令或脚本内容
假设能掌握这个crontab的时间格式的定义,基本上就会避免出现“bad minute”错误。
(2)列出crontab文件
为了列出crontab文件,能够用:
#crontab -l //你认为这里要是数字1有意义吗?
假设你跟着我做了这个案例,你就会看到和上面的内容一样:0,15,30,45 * * * * /bin/echo 'date' > /dev/console
使用这样的方法能够在$HOME文件夹中对crontab文件做一份备份:
#crontab -l >$HOME/mycron
(3)编辑crontab文件
假设希望加入,删除或改动crontab文件里的条目,而EDITOR环境变量有舍值为vi,能够使用vi来编辑crontab文件,命令:
#crontab -e
能够像使用vi编辑其它不论什么文件那样改动crontab文件并退出.假设改动了某些条目或增加了新的条目,那么在保存该文件时,cron会对其进行必要的完整性检查.假设当中的某个域出现超出=同意范围的值,他就会提示你,我们在编辑crontab文件时,没准会增加新的条目.比如,增加以下一条:
# DT:delete core files,at 3.30am on 1,7,14,21,26,26 days of each month
30 3 1,7,14,21,26 * * /bin/find -name "core' -exec rm {} \;
如今保存并退出。最好在crontab文件的每个条目之上增加一条凝视,这样就能够知道它的功能、执行时间,更为重要的是,知道这是哪位用户的作业。
如今让我们使用前面讲过的crontab -l命令列出它的所有信息:
$ crontab -l
# (crondave installed on Tue May 4 13:07:43 1999)
# DT:ech the date to the console every 30 minites
0,15,30,45 18-06 * * * /bin/echo `date` > /dev/tty1
# DT:delete core files,at 3.30am on 1,7,14,21,26,26 days of each month
30 3 1,7,14,21,26 * * /bin/find -name "core' -exec rm {} \;
(4)删除crontab文件
要删除crontab文件,能够用:
#crontab -r
(5)恢复丢失的crontab文件
假设不小心误删了crontab文件,假设你在自己的$ H O M E文件夹下另一个备份。那么能够将其复制到/var/spool/cron/<username>。当中<username>是用户名。
假设因为权限问题无法完毕拷贝,能够用:
$ crontab <filename>
当中,<filename>是你在$ H O M E文件夹中副本的文件名称。
我建议你在自己的$ H O M E文件夹中保存一个该文件的副本。我就有过类似的经历。有数次误删了crontab文件(由于r键紧挨在e键的右边)。这就是为什么有些系统文档建议不要直接编辑crontab文件,而是编辑该文件的一个副本,然后又一次提交新的文件。
有些crontab的变体有些怪异。所以在使用crontab命令时要格外小心。假设遗漏了不论什么选项,crontab可能会打开一个空文件。或者看起来像是个空文件。
这时敲delete键退出。不要按<Ctrl-D>。否则你将丢失crontab文件。
实例1:每1分钟运行一次command
命令:
* * * * * command
实例2:每小时的第3和第15分钟运行
命令:
3,15 * * * * command
实例3:在上午8点到11点的第3和第15分钟运行
命令:
3,15 8-11 * * * command
实例4:每隔两天的上午8点到11点的第3和第15分钟运行
命令:
3,15 8-11 */2 * * command
实例5:每一个星期一的上午8点到11点的第3和第15分钟运行
命令:
3,15 8-11 * * 1 command
实例6:每晚的21:30重新启动smb
命令:
30 21 * * * /etc/init.d/smb restart
实例7:每月1、10、22日的4 : 45重新启动smb
命令:
45 4 1,10,22 * * /etc/init.d/smb restart
实例8:每周六、周日的1 : 10重新启动smb
命令:
10 1 * * 6,0 /etc/init.d/smb restart
实例9:每天18 : 00至23 : 00之间每隔30分钟重新启动smb
命令:
0,30 18-23 * * * /etc/init.d/smb restart
实例10:每星期六的晚上11 : 00 pm重新启动smb
命令:
0 23 * * 6 /etc/init.d/smb restart
实例11:每一小时重新启动smb
命令:
* */1 * * * /etc/init.d/smb restart
实例12:晚上11点到早上7点之间。每隔一小时重新启动smb
命令:
* 23-7/1 * * * /etc/init.d/smb restart
实例13:每月的4号与每周一到周三的11点重新启动smb
命令:
0 11 4 * mon-wed /etc/init.d/smb restart
实例14:一月一号的4点重新启动smb
命令:
0 4 1 jan * /etc/init.d/smb restart
实例15:每小时运行/etc/cron.hourly文件夹内的脚本
命令:
01 * * * * root run-parts /etc/cron.hourly
说明:
run-parts这个參数了,假设去掉这个參数的话,后面就能够写要执行的某个脚本名,而不是文件夹名了
使用注意事项
1. 注意环境变量问题
有时我们创建了一个crontab。可是这个任务却无法自己主动运行。而手动运行这个任务却没有问题,这样的情况通常是因为在crontab文件里没有配置环境变量引起的。
在crontab文件里定义多个调度任务时,须要特别注意的一个问题就是环境变量的设置。由于我们手动运行某个任务时。是在当前shell环境下进行的,程序当然能找到环境变量。而系统自己主动运行任务调度时,是不会载入不论什么环境变量的,因此,就须要在crontab文件里指定任务运行所需的全部环境变量,这样,系统运行任务调度时就没有问题了。
不要假定cron知道所须要的特殊环境,它事实上并不知道。
所以你要保证在shelll脚本中提供全部必要的路径和环境变量,除了一些自己主动设置的全局变量。
所以注意例如以下3点:
1)脚本中涉及文件路径时写全局路径;
2)脚本运行要用到java或其它环境变量时。通过source命令引入环境变量,如:
cat start_cbp.sh
#!/bin/sh
source /etc/profile
export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf
/usr/local/jboss-4.0.5/bin/run.sh -c mev &
3)当手动运行脚本OK,可是crontab死活不运行时。
这时必须大胆怀疑是环境变量惹的祸,并能够尝试在crontab中直接引入环境变量解决这个问题。如:
0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
2. 注意清理系统用户的邮件日志
每条任务调度执行完成,系统都会将任务输出信息通过电子邮件的形式发送给当前系统用户。这样日积月累,日志信息会很大。可能会影响系统的正常执行。因此,将每条任务进行重定向处理很重要。
比如,能够在crontab文件里设置例如以下形式,忽略日志输出:
0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
“/dev/null 2>&1”表示先将标准输出重定向到/dev/null,然后将标准错误重定向到标准输出,因为标准输出已经重定向到了/dev/null。因此标准错误也会重定向到/dev/null,这样日志输出问题就攻克了。
3. 系统级任务调度与用户级任务调度
系统级任务调度主要完毕系统的一些维护操作,用户级任务调度主要完毕用户自己定义的一些任务,能够将用户级任务调度放到系统级任务调度来完毕(不建议这么做),可是反过来却不行,root用户的任务调度操作能够通过“crontab –uroot –e”来设置,也能够将调度任务直接写入/etc/crontab文件。须要注意的是,假设要定义一个定时重新启动系统的任务,就必须将任务放到/etc/crontab文件。即使在root用户下创建一个定时重新启动系统的任务也是无效的。
4. 其它注意事项
新创建的cron job。不会立即运行,至少要过2分钟才运行。假设重新启动cron则立即运行。
当crontab突然失效时,能够尝试/etc/init.d/crond restart解决这个问题。或者查看日志看某个job有没有运行/报错tail -f /var/log/cron。
千万别乱执行crontab -r。
它从Crontab文件夹(/var/spool/cron)中删除用户的Crontab文件。删除了该用户的全部crontab都没了。
在crontab中%是有特殊含义的,表示换行的意思。假设要用的话必须进行转义\%,如经经常使用的date ‘+%Y%m%d’在crontab里是不会运行的。应该换成date ‘+\%Y\%m\%d’。
简单的案例:http://www.ahlinux.com/start/cmd/20378.html