您的位置:首页 > 运维架构 > Linux

linux中使用at和crontab制定任务计划

2015-10-08 20:48 776 查看
有时我们需要让linux系统按我们指定的时间规则自动的处理某些作业,例如在某个时间点执行某个脚本,周期性的备份数据,这时候就可以制定任务计划了。任务计划分为一次性周期性两类。

一、制定一次性任务计划
一次性任务计划即执行完一次后就没有了的那种,可以通过at或batch命令生成。计划内容会以文件的形式写入/var/spool/at目录中,一个任务计划对应一个文件,系统的服务进程atd(at daemon)会读取这些文件并执行。某任务执行完毕后,其对应的文件也会被自动删除。
1、为安全起见,我们通常需要编辑/etc/at.allow(白名单)或/etc/at.deny(黑名单)以允许或拒绝某些特定用户制定任务计划,这两个文件对at和batch命令都适用
直接在文件中输入用户名,一行一个用户
⑵若这两个文件都不存在,默认只有root可以使用at和batch命令
⑶/etc/at.allow若存在但没有任何内容,表示允许的用户为空,意即拒绝所有用户(root除外),同样/etc/at.deny若没有任何内容,则表示放行所有用户。
⑷为避免混乱,/etc/at.allow和/etc/at.deny通常不同时使用。但若两者都存在且有矛盾的地方,以/etc/at.allow优先。
2、at:生成一次性任务计划
用法:at [option]... [TIME]
at命令后不能为空,必须接选项或参数
常用选项:
-d 作业编号:删除指定的待执行任务,相当于atrm
-l:显示待执行的任务的列表,相当于atq
-m:任务执行完成后向用户发送E-mail(默认)
-c 作业编号:显示指定作业的实际内容
任务计划创建格式:
at TIME
> COMMAND1
> COMMAND2
...
> 按Ctrl+D结束,结束符为EOT
TIME格式:
HH:MM 如14:30
HH:MM YYYY-MM-DD 如14:30 2015-10-07
HH:MM[am|pm] [Month] [Date] 如02:30pm October 07
HH:MM[am|pm] + number [minutes|hours|days|weeks] 如14:30 + 2 weeks
now + #UNIT 如now + 5minutes
noon,midnight,teatime,tomrrow
其它命令:
atq:查看待执行任务列表,相当于at -l
atrm:删除指定作业,相当于at -d
注:任务作业执行后,若有错误或标准输出,则会以邮件形式告知提交者。可重定向至其他地方或干脆丢弃(> /dev/null)
[root@localhost ~]# at now+2minutes  # 两分钟后执行
at> tail -2 /etc/group
at> <EOT>
job 6 at 2015-10-07 23:36
[root@localhost ~]# mail   # 上述命令执行完后,root已收到邮件
Heirloom Mail version 12.4 7/29/08.  Type ? for help.
"/var/spool/mail/root": 1 message 1 new
>N  1 root                  Wed Oct  7 23:36  15/526   "Output from your job        6"
& 1
Message  1:
From root@localhost.localdomain  Wed Oct  7 23:36:00 2015
...
wittgenstein:x:500:
tesla:x:501:

& q
[root@localhost ~]# at 07:30
at> echo "Good morning" > /dev/pts/0  # 将结果重定向至终端屏幕而非以邮件形式告知root
at> <EOT>
job 8 at 2015-10-08 07:30
[root@localhost ~]# at tomorrow  # 明天这个时候执行(即时隔24小时)
at> rm -f /home/tesla/passwd
at> <EOT>
job 9 at 2015-10-08 23:43
[root@localhost ~]# at -l    # 显示待执行任务
8	2015-10-08 07:30 a root   # 第4段表示作业队列
9	2015-10-08 23:43 a root
[root@localhost ~]# atrm 9   # 删除9号任务
[root@localhost ~]# atq      # 显示待执行任务
8	2015-10-08 07:30 a root
[root@localhost ~]# at -c 8  # 查看8号任务的内容
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
...
echo "Good morning" > /dev/pts/0

marcinDELIMITER6e7b2aa1

3、batch
batch不同于at的地方仅在于其所生成的任务计划是在系统空闲时执行的,故batch命令后不能指定时间。
[root@localhost ~]# batch
at> echo "hello"
at> <EOT>
job 10 at 2015-10-07 23:44


二、制定周期性任务计划
周期性任务计划是由crond(cron daemon)这个系统服务来控制的。与atd服务一样,crond也是默认启动的工作于后台的守护进程。crond执行的每一项任务都会被记录到/var/log/cron这个日志文件中。
周期性任务计划分两类:
①系统cron:定义在/etc/crontab文件中,直接编辑即可
②用户cron:定义在/var/spool/cron目录中,每个用户都有一个与用户名同名的文件(/var/spool/cron/USERNAME),其功能类似于/etc/crontab,使用crontab命令生成
系统通常自带cron服务程序和crontab命令,若没有,可使用如下命令安装:
yum -y install vixie-cron #cron服务程序包
yum -y install crontabs #crontab程序包
系统cron和用户cron的制定语法只存在细微差别,现主要说明一下用户cron的创建
1、用户周期性任务计划
⑴与at一样,我们也可以设置白名单(/etc/cron.allow)或黑名单(/etc/cron.deny)来限制使用crontab的用户,再次建议,这两个文件保留一个即可。
⑵使用crontab命令创建用户cron
用法:crontab [-u username] [-elr]
选项:
-u:管理员可为其他用户创建任务
-e:打开编辑页面定义任务
-l:列出已经定义的所有任务
-r:移除所有任务
crontab -e打开编辑页面后,一行一个任务进行编辑,每行包括6段,前5段为时间,最后一段为要执行的命令,格式如下:
分钟 小时 日 月 周几 命令
例如 0 0 7 10 * echo "happy birthday" | mail -s "blessing" tesla
时间位:
*:表示任何时刻都接受的意思,所有时间段位上不能同时为*
数字:表示具体某一小时某一分钟等,如 8 8 8 8 * 表示每年的8月8日8时8分
,:表示分隔时段,表示一段时间范围,如 8 9,13 * * * 表示每天9:08和13:08
*/#: 在对应的时间位的有效取值上每#一次,如 */8 * * * * 表示每8分钟一次
-:某个时间位上的连续区间,如 10-50/8 * * * * 表示第10分和第50分之间每8分钟一次
crontab的最小单位是分钟,那么如何实现秒级别的任务呢?
例:每10秒输出一次rose
* * * * * for i in {0..5};do echo "rose";sleep 10;done
注意:%在crontab中有特殊意义,如果在crontab的用户命令中要用到%,则要转义,使用\%格式
⑶与atd一样,crond在执行完任务作业后,若有错误或标准输出,也会以邮件形式通知提交者。
cron中的环境变量问题
cron守护进程在执行任务时默认遵循的是cron环境变量定义,而cron环境变量定义得比较简单,尤其是PATH变量,故有时候会出现无法找到命令的情况,如下图。因此,我们应使用命令的绝对路径或者在任务之前自定义变量;时间段后如果接的是脚本,在脚本中最好也自定义PATH变量或添加source /etc/profile和source $HOME/.bash_profile
[tesla@localhost ~]$ crontab -e
*/2 * * * * ifconfig   # 在打开的页面中输入这一行任务
no crontab for tesla - using an empty one
crontab: installing new crontab
[tesla@localhost ~]$ crontab -l   # 查看任务列表
*/2 * * * * ifconfig
[tesla@localhost ~]$ mail
Heirloom Mail version 12.4 7/29/08.  Type ? for help.
"/var/spool/mail/tesla": 1 message 1 new
>N  1 Cron Daemon           Thu Oct  8 19:02  22/791   "Cron <tesla@localhost> ifconfig"
& 1
Message  1:
...
From: root@localhost.localdomain (Cron Daemon)
To: tesla@localhost.localdomain
Subject: Cron <tesla@localhost> ifconfig
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/tesla>
X-Cron-Env: <PATH=/usr/bin:/bin>   #注意这一行,cron预设的PATH变量
X-Cron-Env: <LOGNAME=tesla>
X-Cron-Env: <USER=tesla>
Date: Thu,  8 Oct 2015 19:02:01 +0800 (CST)
Status: R

/bin/sh: ifconfig: command not found   # 提示找不到命令

[tesla@localhost ~]$ which 'ifconfig'
/sbin/ifconfig    # 显示ifconfig命令在/sbin目录下,cron默认PATH变量中并不包含
[tesla@localhost ~]$ echo $PATH    # 查询当前用户PATH变量
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/tesla/bin
[tesla@localhost ~]$ crontab -e
SHELL=/bin/bash
JAVA_HOME=/usr/java/latest
PATH=$JAVA_HOME:/bin:/sbin:/usr/bin:/usr/sbin

30 00 * * * /scripts/backup.sh &> /dev/null

[tesla@localhost ~]$ crontab -r   # 删除所有任务
[tesla@localhost ~]$ crontab -l
no crontab for tesla
[tesla@localhost ~]$ su - root
Password:
[root@localhost ~]# ls /var/spool/cron   # 在root用户下查看有哪些用户cron
tesla
[root@localhost ~]# crontab -u tesla -r  # 管理员可操作其他用户cron
You have new mail in /var/spool/mail/root
[root@localhost ~]# crontab -u tesla -l
no crontab for tesla


2、系统周期性任务计划
系统cron是直接在/etc/crontab文件中编辑的,该文件开头部分已预先设置了一些环境变量,如下,与用户cron不同的地方在于时间段和命令段之间多个一个用户段,此段必须指定,系统cron默认是以root身份进行的。
[root@localhost ~]# 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  # 时间段与命令段之间多了一个用户段


3、anacron
crontab的补充机制,检查有没有过去一个有效周期未曾执行的任务,如果有,在开机后的指定时间点执行一次。

三、制定周期性任务实例:
1、每4小时执行一次对/etc/目录的备份,备份至/backup目录中,保存的目录名为etc-当前时间(以类似于2015071004的格式)
0 */4 * * * -d /backup || madir /backup;/bin/cp -a /etc /backup/etc-$(date + "\%Y\%m\%d\%H")
2、每周3,5,7备份/var/log/messages 文件至/backup/message_logs/目录中,保存的文件名为messages-当前时间
0 2 * * 3,5,7 /bin/cp -a /var/log/messages /backup/message_logs/messages-$(date + "\%Y\%m\%d\%H")
3、每天每两小时取当前系统/proc/meminfo中的以S开头的信息保存至/status/memory.txt中
0 */2 * * * /bin/grep -i '^S' /proc/meminfo >> /status/memory.txt
4、工作日的工作时间内,每小时执行一次echo "howdy"
0 8-17 * * 1-5 echo "howdy"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  crontab at cron anacron