在我们的生活中,有的工作是例行的,例如每年一次加薪、每年给女朋友过一次生日、每天上班都要打卡等,有的工作是临时发生的,例如明天朋友要来访,你需要准备午餐等等。
像很多例行的工作,你一旦忙起来就很容易忘记,这时候就需要人去提醒你,linux的crontab功能就能够排上用场了,例如每年女朋友的生日前一天给你发个邮件提醒你,好让你有所准备。临时发生的事情,例如上面那个例子,明天朋友要来访,在第二天的上午给你发一封邮件提醒你要精心准备午餐。这时候linux的at功能就能派上用场了。那他们之间有什么不一样呢?真的有这么牛x吗?下面我们就来一起看看吧!
at和crontab简介
at:一般用于未来某一个时间点去执行一次某某任务,要记住,只执行一次,所有at很适合那些临时的任务;
crontab:周期性的去运行某任务,所以适合那些周期性的任务。
电子邮件服务
在写at和crontab之前,我们先来简单的看一下本地的电子邮件服务----mailx,mailx的用途就是用来发送和接受网络邮件。
用法(这里只简单的谈一下,以便后面介绍at和crontab,详细的可以见man手册):
mailx [-s 'SUBJECT'] username[@hostname] #使用mail也可以
每个用户在/var/spool/mail/目录下都有一个以自己名字命令的"邮筒",可以用来接收邮件!
1.通过交互式的方式生成邮件正文,我们让root用户给frank用户发个邮件:
[root@localhost ~]# mailx -s "hello frank" frank@localhost.localdomain #-s指定邮件标题,本地用户@hostname可以去掉 how are you? I am root! . EOT
frank用户收邮件:
[frank@localhost ~]$ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/frank": 1 message 1 new >N 1 root Mon Sep 4 11:43 19/654 "hello frank" & 1 #输入序号即可查看文件内容 Message 1: From root@localhost.localdomain Mon Sep 4 11:43:30 2017 Return-Path: <root@localhost.localdomain> X-Original-To: frank@localhost.localdomain Delivered-To: frank@localhost.localdomain Date: Mon, 04 Sep 2017 11:43:30 -0400 To: frank@localhost.localdomain Subject: hello frank #邮件标题 User-Agent: Heirloom mailx 12.5 7/5/10 #用户收发邮件的工具程序 Content-Type: text/plain; charset=us-ascii From: root@localhost.localdomain (root) Status: R how are you? #邮件正文 I am root!
2.使用输入重定向来生成邮件正文,让frank给root回一封,这里可以将文件直接发给root用户。
我们将/tmp/下写好的的hello.txt文件发给root:
[frank@localhost tmp]$ mailx -s "hello root" root < /tmp/hello.txt #这里我们省去了hostname
root收邮件并查看:
[root@localhost ~]# You have mail in /var/spool/mail/root #看吧!这里会弹出提示,告诉你有一封邮件! [root@localhost ~]# [root@localhost ~]# mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 1 message 1 new >N 1 frank Mon Sep 4 11:56 19/629 "hello root" & 1 Message 1: From frank@localhost.localdomain Mon Sep 4 11:56:31 2017 Return-Path: <frank@localhost.localdomain> X-Original-To: root Delivered-To: root@localhost.localdomain Date: Mon, 04 Sep 2017 11:56:31 -0400 To: root@localhost.localdomain Subject: hello root User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: frank@localhost.localdomain (frank) Status: R I am ok! and you? & q #q退出 Held 1 message in /var/spool/mail/root
3.通过管道生成邮件正文,让root给frank再回一封邮件:
事先准备好了hello2.txt
[root@localhost ~]# cat /tmp/hello2.txt | mail -s "hey Frank" frank #使用mail和mailx都是可以的
frank来收邮件查看:
[frank@localhost tmp]$ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/frank": 2 messages 1 new 1 root Mon Sep 4 11:43 20/665 "hello frank" >N 2 root Mon Sep 4 12:05 19/622 "hey Frank" & 2 Message 2: From root@localhost.localdomain Mon Sep 4 12:05:27 2017 Return-Path: <root@localhost.localdomain> X-Original-To: frank Delivered-To: frank@localhost.localdomain Date: Mon, 04 Sep 2017 12:05:27 -0400 To: frank@localhost.localdomain Subject: hey Frank User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: root@localhost.localdomain (root) Status: R I am fine too!
好了,邮件服务就暂时写到这里,想要了解的更详细可见参考man手册,下面我们就来进入正式的主题吧!
at命令
at命令一般用于临时的任务,只会执行一次,at执行的结果都会以邮件的形式发给提交作业的用户。
语法: at [OPTION]... TIME 选项: -l:查看作业队列,相当于atq -f /path/from/somefile:从指定的文件读取作业任务,而不是交互式的输入 -d:删除指定的作业,相当于atrm -c:查看指定作业的具体内容 -q:指定队列 TIME: 精确的时间:HH:MM [YYYY-mm-dd] 00:13 2017-09-05 模糊的时间:noon,midnight,teatime,tomorrow 加:now + # now + 5 minutes 5分钟后,单位有:minutes hours days weeks
下面我们就来使用:
[root@localhost ~]# at now + 2 minutes at> cat /etc/passwd at> <EOT> #输入<EOT>或者使用ctrl+d job 6 at Mon Sep 4 12:26:00 2017
2分钟后我们收到一封邮件:
[root@localhost ~]# mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 4 messages 1 unread 1 frank Mon Sep 4 11:56 20/640 "hello root" 2 root Mon Sep 4 12:21 17/596 "Output from your job 2" 3 root Mon Sep 4 12:24 15/514 "Output from your job 3" >U 4 root Mon Sep 4 12:26 36/1561 "Output from your job 6" & 4 Message 4: From root@localhost.localdomain Mon Sep 4 12:26:00 2017 Return-Path: <root@localhost.localdomain> X-Original-To: root Delivered-To: root@localhost.localdomain Subject: Output from your job 6 To: root@localhost.localdomain Date: Mon, 4 Sep 2017 12:26:00 -0400 (EDT) From: root@localhost.localdomain (root) Status: RO root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt ....(略)
查看作业队列:
[root@localhost ~]# at -l #也可以使用atq 7 Mon Sep 4 12:29:00 2017 a root
从指定的文件去读取作业任务:
[root@localhost ~]# at -f myat.txt 12:36 job 9 at Mon Sep 4 12:36:00 2017 [root@localhost ~]# atq #查看作业队列,相当at -l 9 Mon Sep 4 12:36:00 2017 a root
使用-c查看指定作业的具体内容:
[root@localhost ~]# at -c 10 #!/bin/sh # atrun uid=0 gid=0 # mail root 0 umask 22 XDG_SESSION_ID=9; export XDG_SESSION_ID HOSTNAME=localhost.localdomain; export HOSTNAME SELINUX_ROLE_REQUESTED=; export SELINUX_ROLE_REQUESTED SHELL=/bin/bash; export SHELL HISTSIZE=1000; export HISTSIZE SSH_CLIENT=192.168.122.1\ 62021\ 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:\*.arc=01\;31:\*.arj=01\;31:\*.taz=01\;31:\*.lha=01\;31:\*.lz4=01\;31:\*.lzh=01\;31:\*.lzma=01\;31:\*.tlz=01\;31:\*.txz=01\;31:\*.tzo=01\;31:\*.t7z=01\;31:\*.zip=01\;31:\*.z=01\;31:\*.Z=01\;31:\*.dz=01\;31:\*.gz=01\;31:\*.lrz=01\;31:\*.lz=01\;31:\*.lzo=01\;31:\*.xz=01\;31:\*.bz2=01\;31:\*.bz=01\;31:\*.tbz=01\;31:\*.tbz2=01\;31:\*.tz=01\;31:\*.deb=01\;31:\*.rpm=01\;31:\*.jar=01\;31:\*.war=01\;31:\*.ear=01\;31:\*.sar=01\;31:\*.rar=01\;31:\*.alz=01\;31:\*.ace=01\;31:\*.zoo=01\;31:\*.cpio=01\;31:\*.7z=01\;31:\*.rz=01\;31:\*.cab=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:\*.webm=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/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin; export PATH PWD=/root; export PWD LANG=en_US.UTF-8; export LANG SELINUX_LEVEL_REQUESTED=; export SELINUX_LEVEL_REQUESTED HISTCONTROL=ignoredups; export HISTCONTROL SHLVL=1; export SHLVL HOME=/root; export HOME LOGNAME=root; export LOGNAME SSH_CONNECTION=192.168.122.1\ 62021\ 192.168.122.128\ 22; export SSH_CONNECTION LESSOPEN=\|\|/usr/bin/lesspipe.sh\ %s; export LESSOPEN XDG_RUNTIME_DIR=/run/user/0; export XDG_RUNTIME_DIR cd /root || { echo 'Execution directory inaccessible' >&2 exit 1 } ${SHELL:-/bin/sh} << 'marcinDELIMITER02cdeaba' echo "hello" cat /tmp/hello.txt cat /etc/passwd