【进程/作业管理】篇章四:Linux任务计划、周期性任务执行

时间:2021-11-09 21:52:10

命令归纳:

at 未来时间点让特定任务运行一次
batch 未来时间点让系统自行选择在系统资源较空闲的时间去执行指定的任务
corn  周期性任务计划(corntad)

 



 

at命令详解

  <--- 假如我们只是想要让特定任务运行一次,那么,这时候就要用到at监控程序了 --->

任务计划和周期性任务计划执行了之后都会通过邮件发送给用户,用户可以通过mail命令查看执行情况,也可以通过配置文件查看执行情况(配置文件: /var/spool/mail/USER_NAME)

一、命令格式:

  at [参数] [时间]

 at [-V] [-q queue] [-f file] [-mMlbv] TIME
 at [-V] [-q queue] [-f file] [-mMlbv] -t time_arg
 at -c job [job...]
 at [ -rd ] job [job...]
 atq [-V] [-q queue]
 atrm [-V] job [job...]

 

二、命令功能:

  在一个指定的时间执行一个指定任务,只能执行一次,且需要开启atd进程(ps -ef | grep atd查看, 开启用/etc/init.d/atd start or restart; 开机即启动则需要运行 chkconfig --level 2345 atd on)

 

三、命令参数

-V : 印出版本编号 
-q : 使用指定的伫列(Queue)来储存,at 的资料是存放在所谓的 queue 中,使用者可以同时使用多个 queue,
    而 queue 的编号为 a, b, c... z 以及 A, B, ... Z 共 52 个(默认值 “a” ) -m : 即使程序/指令执行完成后没有输出结果, 也要寄封信给使用者 -f /PATH/FROM/SOMEFILE:从指定文件中读取作业任务,而不用再交互式输入 -l : 列出所有的指定 (使用者也可以直接使用 atq 而不用 at -l) -d : 删除指定 (使用者也可以直接使用 atrm 而不用 at -d) -v : 列出所有已经完成但尚未删除的指定
TIME :

  HH:MM [YYYY-mm-dd]
  noon(中午),midnight(深夜), teatime(下午16点)
  tomorrow
  now+#
   UNIT:minutes, hours, days, OR weeks

【注意:作业执行结果是以邮件发送给提交作业的用户】

四、示例演示:

示例1:查看当前任务队列

  # at -l

[root@test1 mnt]# at -l
10    2018-06-15 17:00 a root
[root@test1 mnt]# 

 

示例2:删除任务

  # at -d 10

[root@test1 mnt]# at -d 10
[root@test1 mnt]# at -l
[root@test1 mnt]# 

 

示例3:查看指定作业的具体内容【只能查看还未执行的任务,执行完了的不能查看】

  # at -c 11

[root@test1 mnt]# at -l
11    2018-06-15 17:00 a root
[root@test1 mnt]# at -c 11
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
umask 22
HOSTNAME=test1; export HOSTNAME
SELINUX_ROLE_REQUESTED=; export SELINUX_ROLE_REQUESTED
SHELL=/bin/bash; export SHELL
HISTSIZE=1000; export HISTSIZE
SSH_CLIENT=10.0.0.1\ 62110\ 22; export SSH_CLIENT
SELINUX_USE_CURRENT_RANGE=; export SELINUX_USE_CURRENT_RANGE
SSH_TTY=/dev/pts/0; export SSH_TTY
USER=root; export USER
LS_COLORS=rs=0:di=01\;34:ln=01\;36:mh=00:pi=40\;33:so=01\;35:do=01\;35:bd=40\;33\;01:cd=40\;33\;01:or=40\;31\;01:mi=01\;05\;37\;41:su=37\;41:sg=30\;43:ca=30\;41:tw=30\;42:ow=34\;42:st=37\;44:ex=01\;32:\*.tar=01\;31:\*.tgz=01\;31:\*.arj=01\;31:\*.taz=01\;31:\*.lzh=01\;31:\*.lzma=01\;31:\*.tlz=01\;31:\*.txz=01\;31:\*.zip=01\;31:\*.z=01\;31:\*.Z=01\;31:\*.dz=01\;31:\*.gz=01\;31:\*.lz=01\;31:\*.xz=01\;31:\*.bz2=01\;31:\*.tbz=01\;31:\*.tbz2=01\;31:\*.bz=01\;31:\*.tz=01\;31:\*.deb=01\;31:\*.rpm=01\;31:\*.jar=01\;31:\*.rar=01\;31:\*.ace=01\;31:\*.zoo=01\;31:\*.cpio=01\;31:\*.7z=01\;31:\*.rz=01\;31:\*.jpg=01\;35:\*.jpeg=01\;35:\*.gif=01\;35:\*.bmp=01\;35:\*.pbm=01\;35:\*.pgm=01\;35:\*.ppm=01\;35:\*.tga=01\;35:\*.xbm=01\;35:\*.xpm=01\;35:\*.tif=01\;35:\*.tiff=01\;35:\*.png=01\;35:\*.svg=01\;35:\*.svgz=01\;35:\*.mng=01\;35:\*.pcx=01\;35:\*.mov=01\;35:\*.mpg=01\;35:\*.mpeg=01\;35:\*.m2v=01\;35:\*.mkv=01\;35:\*.ogm=01\;35:\*.mp4=01\;35:\*.m4v=01\;35:\*.mp4v=01\;35:\*.vob=01\;35:\*.qt=01\;35:\*.nuv=01\;35:\*.wmv=01\;35:\*.asf=01\;35:\*.rm=01\;35:\*.rmvb=01\;35:\*.flc=01\;35:\*.avi=01\;35:\*.fli=01\;35:\*.flv=01\;35:\*.gl=01\;35:\*.dl=01\;35:\*.xcf=01\;35:\*.xwd=01\;35:\*.yuv=01\;35:\*.cgm=01\;35:\*.emf=01\;35:\*.axv=01\;35:\*.anx=01\;35:\*.ogv=01\;35:\*.ogx=01\;35:\*.aac=01\;36:\*.au=01\;36:\*.flac=01\;36:\*.mid=01\;36:\*.midi=01\;36:\*.mka=01\;36:\*.mp3=01\;36:\*.mpc=01\;36:\*.ogg=01\;36:\*.ra=01\;36:\*.wav=01\;36:\*.axa=01\;36:\*.oga=01\;36:\*.spx=01\;36:\*.xspf=01\;36:; export LS_COLORS
MAIL=/var/spool/mail/root; export MAIL
PATH=/usr/local/htop1.0.2/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin; export PATH
PWD=/mnt; export PWD
LANG=en_US.UTF-8; export LANG
MODULEPATH=/usr/share/Modules/modulefiles:/etc/modulefiles; export MODULEPATH
LOADEDMODULES=; export LOADEDMODULES
SELINUX_LEVEL_REQUESTED=; export SELINUX_LEVEL_REQUESTED
HISTCONTROL=ignoredups; export HISTCONTROL
SHLVL=1; export SHLVL
HOME=/root; export HOME
LOGNAME=root; export LOGNAME
CVS_RSH=ssh; export CVS_RSH
SSH_CONNECTION=10.0.0.1\ 62110\ 10.0.0.200\ 22; export SSH_CONNECTION
MODULESHOME=/usr/share/Modules; export MODULESHOME
LESSOPEN=\|\|/usr/bin/lesspipe.sh\ %s; export LESSOPEN
G_BROKEN_FILENAMES=1; export G_BROKEN_FILENAMES
OLDPWD=/root; export OLDPWD
cd /mnt || {
     echo 'Execution directory inaccessible' >&2
     exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER5953a367'
/bin/ls

marcinDELIMITER5953a367
[root@test1 mnt]# 

 

示例4:

  # at 2:05 tomorrow   在每天2:05分执行
  at>/home/kyle/do_job
  at> Ctrl+D
  AT Time中的时间表示方法
  -----------------------------------------------------------------------
  时 间 例子 说明
  -----------------------------------------------------------------------
  Minute    at now + 5 minutes   任务在5分钟后运行
  Hour      at now + 1 hour      任务在1小时后运行
  Days      at now + 3 days      任务在3天后运行
  Weeks     at now + 2 weeks     任务在两周后运行
  Fixed     at midnight          任务在午夜运行
  Fixed     at 10:30pm           任务在晚上10点30分

  Fixed     at 23:59 12/31/2018   任务在2018年12月31号23点59分  

示例5:三天后的下午5点执行 /bin/ls

  # at 5pm+3 day

[root@test1 mnt]# date
Tue Jun 12 18:25:08 CST 2018
[root@test1 mnt]# at 5pm+3 day
at> /bin/ls
at> <EOT>    【退出使用Ctrl + d 】
job 10 at 2018-06-15 17:00
You have new mail in /var/spool/mail/root
[root@test1 mnt]# at -l
10    2018-06-15 17:00 a root

 

示例6:明天17点钟,输出时间到指定文件 /mnt/date.log内

  # at now+1minutes

  at> date >/mnt/date.log

  at> <EOF>

[root@test1 mnt]# at now+1minutes 
at> date >/mnt/date.log
at> <EOT>
job 13 at 2018-06-12 18:38
[root@test1 mnt]# at -l
13    2018-06-12 18:38 a root
[root@test1 mnt]# ls
at.taks  date.log  htop-2.2.0-1.el7.x86_64.rpm  mm.sh  XX  xx.txt
[root@test1 mnt]# cat date.log 
Tue Jun 12 18:38:00 CST 2018


五、补充:atd 的启动与 at 运行的方式

  1)atd 的启动

  要使用一次性计划任务时,我们的 Linux 系统上面必须要有负责这个计划任务的服务,那就是 atd 服务。 不过并非所有的 Linux distributions 都默认会把他打开的,所以,某些时刻我们需要手动将atd 服务激活才行。 激活的方法很简单,就是这样:  

   命令:【 /etc/init.d/atd {start|stop|restart|condrestart|status} 】

    /etc/init.d/atd start 

    /etc/init.d/atd restart

[root@test1 /]# /etc/init.d/atd start
[root@test1 /]# /etc/init.d/atd 

[root@test1 /]# /etc/init.d/atd stop
停止 atd:[确定]
[root@test1 /]# ps -ef|grep atd
root     25062 24951  0 14:53 pts/0    00:00:00 grep atd
[root@test1 /]# /etc/init.d/atd start
[确定]td:[确定]
[root@test1 /]# ps -ef|grep atd
root     25068     1  0 14:53 ?        00:00:00 /usr/sbin/atd
root     25071 24951  0 14:53 pts/0    00:00:00 grep atd
[root@test1 /]# /etc/init.d/atd restart
停止 atd:[确定]
[确定]td:[确定]

备注:配置一下启动时就启动这个服务,免得每次重新启动都得再来一次

  命令:

  chkconfig atd on

  输出:

[root@test1 /]# chkconfig atd on
[root@test1 /]#

  2)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命令:
  <--- batch会让系统自行选择在系统资源较空闲的时间去执行指定的任务,我们一般不使用这个命令 --->



cron、crontab命令详解:

   <--- 周期性任务计划(corntad) --->

一、介绍

  cron是一个后台运行;其有三个进程分别为

   [root@test1 mnt]# rpm -qa | grep cron
   cronie-anacron-1.4.4-15.el6.x86_64
   crontabs-1.10-33.el6.noarch
   cronie-1.4.4-15.el6.x86_64

可以使用 # rpm -qa | grep cron 查看

  cronie:主程序包,提供了crond守护进程及相关辅助工具;
  cronie-anacron:cronie的补充程序,用于监控cronie任务执行状态,如cronie中的任务在过去该运行的时间点未能正常运行,则cronie-anacron会随后启动一次任务
  crontables:包含CentOS提供系统维护任务

二、我们要使用周期性任务计划的话,必须先确保进程处于运行状态

  CentOS 7:
   systemctl status crond.service
    Active: active (running) ... ...

  CentOS 6:
   service crond status
    ... is running.

  【如果显示的是上面两种情况的话,就是进程以及处于运行状态了】

三、cron任务分为两类

系统cron任务:主要用于实现系统自身的维护;  【这个是实现系统维护的,我们操作定时任务一般不使用系统cron任务】
  手动编辑:/etc/crontab文件
用户cron任务:      【用户一般使用crontab命令实现周期性定时任务的】
   命令:crontab命令

1、两类任务的通用格式:【参考 /etc/crontab】 

  【进程/作业管理】篇章四:Linux任务计划、周期性任务执行

  注意:

  (1) 每一行定义一个周期性任务,共7个字段;

    * * * * * : 定义周期性时间
    user-name : 运行任务的用户身份
    command to be executed:任务
  (2) 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量;
  (3) 执行结果邮件发送给MAILTO指定的用户【用户可以使用mail命令或者  /var/spool/mail/USER_NAME查看】

  前五个字段的时间法:

表示法:
 (1) 特定值;
      给定时间点有效取值范围内的值;
      注意:day of week和day of month一般不同时使用;
 (2) *
      给定时间点上有效取值范围内的所有值;表“每..”
 (3) 离散取值:,
      在时间点上使用逗号分隔的多个值; 
         #,#,#
 (4) 连续取值:-
      在时间点上使用-连接开头和结束
         #-#
 (5) 在指定时间点上,定义步长: 
        /#:#即步长;
                    
注意:
  (1) 指定的时间点不能被步长整除时,其意义将不复存在;
  (2) 最小时间单位为“分钟”,想完成“秒”级任务,得需要额外借助于其它机制;
       定义成每分钟任务:而在利用脚本实现在每分钟之内,循环执行多次;
示例:
(1) 3 * * * *:每小时执行一次;每小时的第3分钟;
(2) 3 4 * * 5:每周执行一次;每周5的4点3分;
(3) 5 6 7 * *:每月执行一次;每月的7号的6点5分;
(4) 7 8 9 10 *:每年执行一次;每年的10月9号8点7分;
(5) 9 8 * * 3,7:每周三和周日;
(6) 0 8,20 * * 3,7:
(7) 0 9-18 * * 1-5:
(8) */5 * * * *:每5分钟执行一次某任务;
(9) */7

 

2、对于系统cron任务:

  系统任务主要用于系统维护等,我们操作定时任务一般不使用系统cron任务

    如果必须要操作:我们一般把任务写到 /etc/crontab文件里面

3、用户cron任务,

  我们直接使用crontab命令实现

  直接使用:crontab -e 编辑我们需要执行的任务就行了

  语法格式:rontab [-u user] [-l | -r | -e] [-i]
    -e:编辑任务;
    -l:列出所有任务;
    -r:移除所有任务;即删除/var/spool/cron/USERNAME文件;
    -i:同 ' -r ' 一同使用,以交互式模式让用户有选择的移除指定任务;
    -u user:root用户可为指定用户管理cron任务 【仅管理员有权限】

注意:运行结果以邮件通知给当前用户;如果拒绝接收邮件:
  (1) COMMAND > /dev/null
  (2) COMMAND &> /dev/null

  【定义COMMAND时,如果命令需要用到%,需要对其转义;但放置于单引号中的%不用转义亦可】

 

思考:

  某任务在指定的时间因关机未能执行,下次开机会不会自动执行?
   不会!.
   如果期望某时间因故未能按时执行,下次开机后无论是否到了相应时间点都要执行一次,可使用anacron实现;

 

四、示例演示

1、每12小时备份一次/etc目录至/backups目录中,保存文件 名称格式为“etc-yyyy-mm-dd-hh.tar.xz”

        [root@localhost ~]# mkdir /backups
        0 */12 * * * /bin/tar -Jcf /backups/etc-`date+\%y-\%M-\%d-%\H`.tar.xz /etc
 
 2、每周2、4、7备份/var/log/secure文件至/logs目录中,文件名格式为“secure-yyyymmdd”;
        [root@localhost ~]# mkdir /logs
        0 0 * * 2,4,7 /bin/tar -zcf /logs/secure-`date+\%y\%M\%d`.tar.gz /var/log/secure
 
3、每两小时取出当前系统/proc/meminfo文件中以S或M开头的行信息追加至/tmp/meminfo.txt文件中;
        [root@localhost tmp]# touch meminfo.txt
        0 */2 * * * /bin/cat /proc/meminfo | grep -E "^[S,M]" &gt;&gt; /tmp/meminfo.txt