at
    目录

    • at的启动
    • 对at使用的用户进行限制
    • at命令
    • at命令使用的范例
    • at工作的查看 和删除
    • batch
    • .batch:系统有空时才进行背景任务

    1.at的启动
    at依赖服务atd

    1. [root@study ~]# systemctl restart atd # 重新启动 atd 这个服务
    2. [root@study ~]# systemctl enable atd # 让这个服务开机就自动启动
    3. [root@study ~]# systemctl status atd # 查阅一下 atd 目前的状态
    4. atd.service - Job spooling tools
    5. Loaded: loaded
    6. (/usr/lib/systemd/system/atd.service; enabled # 是否开机启动
    7. Active: active
    8. running since Thu 2015-07-30 19:21:21 CST; 23s ago # 是否正在运行中
    9. Main PID: 26503 atd
    10. CGroup: /system.slice/atd.service
    11. └─26503 /usr/sbin/atd -f
    12. Jul 30 19:21:21 study.centos.vbird systemd[1]: Starting Job spooling tools...
    13. 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 就执行完毕啰!