at
目录
- at的启动
- 对at使用的用户进行限制
- at命令
- at命令使用的范例
- at工作的查看 和删除
- batch
- .batch:系统有空时才进行背景任务
1.at的启动
at依赖服务atd
[root@study ~]# systemctl restart atd # 重新启动 atd 这个服务
[root@study ~]# systemctl enable atd # 让这个服务开机就自动启动
[root@study ~]# systemctl status atd # 查阅一下 atd 目前的状态
atd.service - Job spooling tools
Loaded: loaded
(/usr/lib/systemd/system/atd.service; enabled) # 是否开机启动
Active: active
(running) since Thu 2015-07-30 19:21:21 CST; 23s ago # 是否正在运行中
Main PID: 26503 (atd)
CGroup: /system.slice/atd.service
└─26503 /usr/sbin/atd -f
Jul 30 19:21:21 study.centos.vbird systemd[1]: Starting Job spooling tools...
Jul 30 19:21:21 study.centos.vbird systemd[1]: Started Job spooling tools.
我们使用 at 这个指令来产生所要
运行的工作,并将这个工作以文本文件的方式写入 /var/spool/at/ 目录内,该工作便能等待
atd 这个服务的取用与执行了。
2.对使用at的用户进行限制
我们可以利用 /etc/at.allow 与 /etc/at.deny 这两个文件来进行 at 的使用限制呢!
加
上这两个文件后, at 的工作情况其实是这样的:
1. 先找寻 /etc/at.allow 这个文件,写在这个文件中的使用者才能使用 at ,没有在这个文
件中的使用者则不能使用 at (即使没有写在 at.deny 当中);
2. 如果 /etc/at.allow 不存在,就寻找 /etc/at.deny 这个文件,若写在这个 at.deny 的使用
者则不能使用 at ,而没有在这个 at.deny 文件中的使用者,就可以使用 at 咯;3. 如果两个文件都不存在,那么只有 root 可以使用 at 这个指令。
3.at命令
[root@study ~]# at [-mldv] TIME
[root@study ~]# at -c 工作号码
选项与参数:
-m :当 at 的工作完成后,即使没有输出讯息,亦以 email 通知使用者该工作已完成。
-l :at -l 相当于 atq,列出目前系统上面的所有该使用者的 at 调度;
-d :at -d 相当于 atrm ,可以取消一个在 at 调度中的工作;
-v :可以使用较明显的时间格式列出 at 调度中的工作列表;
-c :可以列出后面接的该项工作的实际指令内容。
TIME:时间格式,这里可以定义出
“什么时候要进行 at 这项工作”的时间,格式有:
HH:MM
ex> 04:00
在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此工作。
HH:MM YYYY-MM-DD
ex> 04:00 2015-07-30
强制规定在某年某月的某一天的特殊时刻进行该工作!
HH:MM[am|pm] [Month] [Date]
ex> 04pm July 30
也是一样,强制在某年某月某日的某时刻进行!
HH:MM[am|pm] + number [minutes|hours|days|weeks]
ex> now + 5 minutes
ex> 04pm + 3 days
就是说,在某个时间点
“再加几个时间后”才进行。
4.at使用的范例
范例一:再过五分钟后,将 /root/.bashrc 寄给 root 自己
[root@study ~]# at now + 5 minutes <==记得单位要加 s 喔!
at> /bin/mail -s "testing at job" root < /root/.bashrc
at> <EOT> <==这里输入 [ctrl] + d 就会出现 <EOF> 的字样!代表结束!
job 2 at Thu Jul 30 19:35:00 2015
# 上面这行信息在说明,第 2 个 at 工作将在 2015/07/30 的 19:35 进行!
# 而执行 at 会进入所谓的 at shell 环境,让你下达多重指令等待运行!
范例二:将上述的第 2 项工作内容列出来查阅
[root@study ~]# at -c 2
#!/bin/sh <==就是通过 bash shell 的啦!
# atrun uid=0 gid=0
# mail root 0
umask 22
....(中间省略许多的环境变量项目)....
cd /etc/cron\.d || {
echo 'Execution directory inaccessible' >&2
exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER410efc26'
/bin/mail -s "testing at job" root < /root/.bashrc # 这一行最重要!
marcinDELIMITER410efc26
# 你可以看到指令执行的目录 (
/root),还有多个环境变量与实际的指令内容啦!
范例三:由于机房预计于 2015/08/05 停电,我想要在 2015/08/04 23:00 关机?
[root@study ~]# at 23:00 2015-08-04
at> /bin/syncTips
at> /bin/sync
at> /sbin/shutdown -h now
at> <EOT>
job 3 at Tue Aug 4 23:00:00 2015
# 您瞧瞧! at 还可以在一个工作内输入多个指令呢!不错吧!
事实上,当我们使用 at 时会进入一个 at shell 的环境来让使用者下达工作指令,此
时,建议你最好使用绝对路径来下达你的指令,比较不会有问题喔!
由于 at 工作调度的使用上,系统会将该项 at 工作独立出你的 bash 环境中, 直接
交给系统的 atd 程序来接管,
举例来说,你在 /tmp 下 达“ at now ”然后输入“ mail -s “test” root < .bashrc ”, 问一下,那个 .bashrc 的文件会是在
哪里?答案是“ /tmp/.bashrc ”!因为 at 在运行时,会跑到当时下达 at 指令的那个工作目录 的缘故啊!
有些朋友会希望“我要在某某时刻,在我的终端机显示出 Hello 的字样”,然后就在
at 里面下达这样的信息“ echo “Hello” ”。等到时间到了,却发现没有任何讯息在屏幕上显
示,这是啥原因啊?这是因为 at 的执行与终端机环境无关,而所有 standard
output/standard error output 都会传送到执行者的 mailbox 去啦!所以在终端机当然看不到
任何信息。那怎办?没关系, 可以通过终端机的设备来处理!假如你在 tty1 登陆,则可
以使用“ echo “Hello” > /dev/tty1 ”来取代。
5.at工作的查看,删除
[root@study ~]# atq
[root@study ~]# atrm (jobnumber)
范例一:查询目前主机上面有多少的 at 工作调度?
[root@study ~]# atq
3 Tue Aug 4 23:00:00 2015 a root
# 上面说的是:“在 2015/08/04 的 23:00 有一项工作,该项工作指令下达者为
# root”而且,该项工作的工作号码 (
jobnumber) 为 3 号喔!
范例二:将上述的第 3 个工作移除!
[root@study ~]# atrm 3
[root@study ~]# atq
# 没有任何信息,表示该工作被移除了
6.batch:系统有空时才进行背景任务
其实 batch 是利用 at 来进行指令的下达啦!只是加入一些控制参数而已。这个
batch 神奇的地方在于:他会在 CPU 的工作负载小于 0.8 的时候,才进行你所下达的工作
任务啦!
那什么是工作负载 0.8 呢?这个工作负载的意思是: CPU 在单一时间点所负责
的工作数量。不是 CPU 的使用率喔!
举例来说,如果我有一只程序他需要一直使用 CPU
的运算功能,那么此时 CPU 的使用率可能到达 100% , 但是 CPU 的工作负载则是趋近
于“ 1 ”,因为 CPU 仅负责一个工作嘛!如果同时执行这样的程序两支呢? CPU 的使用率
还是 100% ,但是工作负载则变成 2 了!
范例一:请执行 pi 的计算,然后在系统闲置时,执行 updatdb 的任务
[root@study ~]# echo "scale=100000; 4*a
(1)" | bc -lq &
[root@study ~]# echo "scale=100000; 4*a
(1)" | bc -lq &
[root@study ~]# echo "scale=100000; 4*a
(1)" | bc -lq &
[root@study ~]# echo "scale=100000; 4*a
(1)" | bc -lq &
# 然后等待个大约数十秒的时间,之后再来确认一下工作负载的情况!
[root@study ~]# uptime
19:56:45 up 2 days, 19:54, 2 users, load average: 3.93, 2.23, 0.96
[root@study ~]# batch
at> /usr/bin/updatedb
at> <EOT>
job 4 at Thu Jul 30 19:57:00 2015
[root@study ~]# date;atq
Thu Jul 30 19:57:47 CST 2015
4 Thu Jul 30 19:57:00 2015 b root
# 可以看得到,明明时间已经超过了,却没有实际执行 at 的任务!
[root@study ~]# jobs
[1] Running echo "scale=100000; 4*a
(1)" | bc -lq &
[2] Running echo "scale=100000; 4*a
(1)" | bc -lq &
[3]- Running echo "scale=100000; 4*a
(1)" | bc -lq &
[4]+ Running echo "scale=100000; 4*a
(1)" | bc -lq &
[root@study ~]# kill -9 %1 %2 %3 %4
# 这时先用 jobs 找出背景工作,再使用 kill 删除掉四个背景工作后,慢慢等待工作负载的下降
[root@study ~]# uptime; atq
20:01:33 up 2 days, 19:59, 2 users, load average: 0.89, 2.29, 1.40
4 Thu Jul 30 19:57:00 2015 b root
[root@study ~]# uptime; atq
20:02:52 up 2 days, 20:01, 2 users, load average: 0.23, 1.75, 1.28
# 在 19:59 时,由于 loading 还是高于 0.8,因此 atq 可以看得到 at job 还是持续再等待当中喔!
# 但是到了 20:01 时, loading 降低到 0.8 以下了,所以 atq 就执行完毕啰!