Linux任務計劃,週期性任務執行
(我們以前已經提到過數據備份的概念了,假如在某種場景中我們需要做數據備份,將來我們可能遇到MySQL等各種各樣的提供數據管理等相關的服務器程序數據,能夠做數據備份,那就必然會用到這個功能。對於企業來講最重要的是數據,數據備份是非常重要的,有的數據需要每1天或者每幾個小時進行備份一次,比方說我們希望在凌晨的時候講某個目錄的數據複製一份,或者把某個臨時目錄比方說“/tmp”目錄中的臨時文件每多長時間都清理一次。這每一天都做的任務就叫週期性任務。像那種僅僅是爲了某個需要將命令執行一次,那麼這種任務就叫週期性計劃。)
週期性計劃:
在未來的某個時間點執行一次某任務:at,batch
週期性任務:
週期性運行某任務:crontab
執行結果:會通過郵件發送給用戶
(對於linux來講,週期性任務可能經常運行,任務計劃也需要在外來某個時間點運行,但是任務執行時用戶不在線怎麼辦?我們的用戶沒有登錄並且不在線,所以一般而言這兩種任務的執行結果,一旦某個任務到時間了,其執行結果會通過默認的郵件發送給用戶。
這個郵件是指電子郵件的相關概念,但是不同的時,這裏並不需要連接到互聯網上去,發互聯網上的郵箱,一般情況下,我們主機上默認會啓動一個本地的郵件服務,他只用於本地主機上用戶之間互相傳信息的,我們以前講過一個命令叫wall,它能夠將一個信息發送給主機上的所有終端,但是像郵件的發送,這個命令就不能滿足我們此處的需要了,這也很容易理解,用戶沒有登錄上主機,那麼他就不可能發送給用戶,那麼我們就只能通過離線消息接受的功能,來實現這種消息的傳遞,而郵件就是這種消息非常有效的解決方式,但是這種服務他不是爲互聯網上用戶提供公開的公共服務的,而僅僅是保證本地主機上的用戶在下一次登錄以後,能夠知道他此前定義的週期性任務計劃或者未來某一時間點的任務在某一刻運行沒有,運行的結果與否,運行的結果怎麼樣,我們一定要注意,這個服務一定要運行在本機上,並且也只用於本地主機上不同用戶之間,互相傳郵件,比方說tom給jerry發送郵件,但是jerry這個用戶並沒有登錄,等jerry下次登錄後,直接就能收到一封郵件的提示,提示說“你有一封新郵件,請注意查收”,好的,jerry只需登錄自己的郵箱,然後讀取自己的郵件即可,所以郵件一般有這樣的效用,那麼他跟我們現實中郵件的工作法則是非常相似的,當郵遞員發送郵件的時候,他不可能將郵件直接放到你加的桌子上,而是找一個公共的區域,這個公共區域就是各家各戶的郵筒,同樣tom給jerry發送郵件的話,也是先發送給郵件服務器的,然後郵件服務器將郵件放在離線用戶將來登錄後能夠收信的地方。
這個位置在哪呢?
我們此前講過,在系統上每個用戶在創建時,在目錄 “/var/spool/mail”目錄下有一個與用戶同名的文件,這個個同名文件就相當於用戶自己放在公共區域的郵筒,我們的郵件服務器就會將郵件數據寫進這個文件中,就像相面說的,tom給jerry發送郵件,那麼服務器就會將jerry要收的郵件中的數據寫進/var/spool/mail/jerry文件中。那麼這個工作要想工作起來,那麼首先要啓動本地的郵件服務,但是這個郵件服務不需要本地主機上的用戶與其他主機上的用戶進行通信。另外我們每一個本機用戶都應該有一個與用戶名同名的說法郵件的文件。
郵件服務器對於centos系列的文件系統都是默認開啓的,無論是5,還是6,還是7.
我們確認本地的郵件服務器是否開啓只需運行命令:
“ss -tnl”
或者運行:
“netstat -tnl”
如果發現有一個25號端口處於監聽的狀態,那麼就表示本機的郵件服務是正常的,正處於監聽狀態,對於cenots5來講用的是postfix6,對於centos6來講是postfix7
我們還可以使用“netstat -tnlp”可以看到這個郵件服務器程序在監聽。
[root@centos6 mail]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2703/master
tcp 0 0 ::1:25 :::* LISTEN 2703/master //master是郵件服務器中的一個主控進程用來監聽25號端口,並看到25前面是127.0.0.1那麼就是代表本地主機上爲各用戶之間傳遞郵件做準備。
[root@centos6 mail]#
)
本地電子郵件服務:
smtp:simple mail transmission protocol(簡單郵件傳輸協議)是一個應用層協議, 他只能實現用戶發郵件,不能收郵件
POP3:郵局協議:Post Office Procotol
imap4:互聯網郵件訪問協議:Internet Mail Access Proctol
在本地主機上實現郵件收發服務:
直接使用mail命令即可,mail也屬於一個文本行的MUA(郵件用戶代理)
mail命令:
centos6上使用的是mail,但是centos7上使用的是mailx
MUA:Mail User Agent,用戶收發郵件的工具程序;
要想使用mail命令或者mailx命令來實現發送郵件,實現發送郵件。
格式:
可以直接寫一個mail即可因爲他是一個連接,也可以先一個完成的
mailx [-s'SUBJECT'] username[@hostname]
解釋:
'SUBJECT'是郵件標題
username:表示要發送給的用戶名
@hostname:表示域名或者主機名,如果是本地主機上的用戶之間發郵件,這 個域名可以省略
郵件正文的生成:
(1)交互式輸入;點號“.”單獨成行可以表示正文結束;ctrl+d提交也可
(2)通過輸入重定向;
(3)通過管道; //主要是在我們將一個命令的結果作爲郵件的正文發送給對方 時,我們使用管道。
演示收發本地郵件:
[root@centos6 ~]# mail -s 'hello dong' dong@centos6 //發送本地郵件時,@主機名可以省 略,回車後就表示開始輸入郵件的正文。
你好!想你了哈哈。。。。
. //郵件正文輸入後,然後另起一行輸入點號“.”,表示結束
EOT
[root@centos6 ~]# su - dong
[dong@centos6 ~]$ mail //輸入mail打開自己的郵箱,mail不帶任何選項時,表示收郵件
Heirloom Mail version 12.4 7/29/08. Type ? for help.
"/var/spool/mail/dong": 1 message1 new
>N 1 root Wed Nov 16 12:29 18/713 "hello dong" //N:表示新郵件;1:表示新郵件的編號;
& 1 //我們要想查看新郵件,只需輸入新郵件的編號
Message 1: //這灰色的表示郵件的收發信息
[email protected] WedNov 16 12:29:26 2016 //發件人是誰,發 送的時間
Return-Path:<[email protected]> //恢復的話恢復給誰
X-Original-To:dong@centos6
Delivered-To:[email protected]
Date:Wed, 16 Nov 2016 12:29:25 +0800
Subject:hello dong //郵件標題
User-Agent:Heirloom mailx 12.4 7/29/08 //對方發郵件是用的什麼程序
Content-Type:text/plain; charset=utf-8 //郵件正文是什麼格式
From:[email protected] (root)
Status:R
你好!想你了哈哈。。。。
& q //退出
Held 1 message in /var/spool/mail/dong
You have mail in /var/spool/mail/dong //這裏還顯示我們還有郵件
[dong@centos6 ~]$
另外我們可否自動給一個郵件正文呢?
一般情況下我們在命令行下輸入mail命令後,我們是在交互式模式下輸入正文,這樣就不太容易寫腳本,我們寫腳本時要儘量避免與用戶交互,只要是通過標準輸入接收輸入的,我們都可以通過管道或者重定向的方式來實現。
舉例演示:
自動輸入郵件內容
[root@centos6 ~]# mail -s 'fstab file' xiang < /etc/fstab //這條命令還可以這樣寫:
[root@centos6 ~]# cat /etc/issue | mail -s 'issue file' dong
[root@centos6 ~]# su - xiang
[xiang@centos6 ~]$ mail
Heirloom Mail version 12.4 7/29/08. Type ? for help.
"/var/spool/mail/xiang": 1message 1 new
>N 1 root Wed Nov 1612:54 33/1573 "fstab file"
& 1
Message 1:
[email protected] WedNov 16 12:54:39 2016
Return-Path:<[email protected]>
X-Original-To: xiang
Delivered-To:[email protected]
Date: Wed, 16 Nov 2016 12:54:39 +0800
Subject: fstab file
User-Agent: Heirloom mailx 12.4 7/29/08
Content-Type: text/plain; charset=us-ascii
From: [email protected](root)
Status: R
#
# /etc/fstab
# Created by anaconda on Tue Oct 1112:39:17 2016
#
# Accessible filesystems, by reference, aremaintained under '/dev/disk'
# See man pages fstab(5), findfs(8),mount(8) and/or blkid(8) for more info
#
UUID=2ead7599-15b0-4b11-b96d-5f9b59e2e7eb/ ext4 defaults
11
UUID=edb28e3e-5ee7-400f-8226-fab5fa157188/boot ext4 defaults
12
UUID=32376552-a128-416d-be08-0aa6acab4661/testdir ext4 defaults
12
UUID=091e5b14-8201-4ffc-9278-41b7acae00d9swap swap defaults
00
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
&
At EOF
&
At EOF
& q
Held 1 message in /var/spool/mail/xiang
[xiang@centos6 ~]$
at命令:
格式:
at [OPTION]... TIME
時間表示格式TIME:
(1)HH:MM[YYY-mm-dd]:表示指明小時分鐘
舉例:現在是11:28了,如果我想表示11:10,會表示在下一個11:10執行計劃任務。
如果我們想表示年月日的話,那麼我們就這樣給出:
11:102016-11-16
(2)模糊時間表示法:
noon(正午12點)
midnight(午夜表示晚上12點)
teatime(下午茶是下午4點)
tomorrow
(3)相對時間表示法:
now+# //從現在開始往後走一週。
#表示數字然後後面加上單位
單位UNIT有:minutes,hours,days, weeks
at的作業有隊列概念,用單個字符表示,默認都使用a隊列;並且作業的編號使用絕對編號。
(當主機上有多個用戶都設置了多個作業,那麼我們可以根據用戶不同講作業分別放在不同的隊列中,比方說a,b,c......等來表示不同對列)
常用的選項:
-l:查看作業隊列,也就是查看提交的還未執行的作業,相當於atq,當作業執行 後就看不到了。
-f /PATH/FROM/SOMEFILE:從指定文件中讀取作業任務,而不用再交互式輸入;
(如果有一些命令經常性的執行,只是在某些時間點進行,並不是週期性的,什麼時間點用到時我們可以將這個命令寫在一個文件中,用選項“-f”來讀取即可。)
-d:當一個作業提交了還未執行,現在想刪除指定的作業;就使用選項-d後面跟作 業號,相當於使用atrm命令
-c:查看at命令作業的執行內容,當我們忘記時,就是用選項“-c”然後面跟上作 業號,這個過程中顯示的出的內容包括,前面顯示的是at執行環境,也就是 說at執行是在某一個環境中執行的。在文件最底下是顯示作業的具體內容。
-q QUEUE:指明隊列;
注意:
(1)作業的執行結果是以郵件方式,發送給提交作業的用戶;
(2)at命令也能執行腳本,所以我們只要給定腳本路徑就可以了,我們要記得是at有自己的運行環境,在我們自己交互式運行環境下可能不一樣,所以有些命令需要我們給出全路徑才能執行。
舉例演示:
在at後面輸入的內容既可以是一個腳本,也可以是任何一條命令,當我們將需要執行的命令寫完了,我們使用“ctr+d”提交
舉例演示:
at讀取作業文件
(1)先用命令查看是否有作業還未執行:
at -l 或 atq
(2)切換到/tetstdir目錄下,並創建一個作業文件,文件內容爲:
vim zuoye
文件內容:
cat /etc/issue
echo "tianxiang i love you."
(3)執行at讀取作業文件設計計劃任務
at -f /testdir/zuoye now+1min
(4)用at -l 或 atq查看未執行的作業
(5)等過了作業執行時間後,驗證一下
[root@centos6 testdir]# mail
Heirloom Mail version 12.4 7/29/08. Type ? for help.
"/var/spool/mail/root": 3messages 1 new
1root Wed Nov 1614:51 17/621 "Output from your job "
2root Wed Nov 1614:55 26/692 "Output from your job "
>N 3 root Wed Nov 1615:20 17/631 "Output from your job "
& 3
Message 3:
From [email protected] Wed Nov 16 15:20:01 2016
Return-Path:<[email protected]>
X-Original-To: root
Delivered-To:[email protected]
Subject: Output from your job 10
Date: Wed, 16 Nov 2016 15:20:01 +0800 (CST)
From: [email protected](root)
Status: R
CentOSrelease 6.8 (Final)
Kernel\r on an \m
tianxiangi love you
& q
Held 3 messages in /var/spool/mail/root
[root@centos6 testdir]#
batch命令:
batch會讓系統自行選擇在系統資源較空閒的時間去執行指定的任務;
週期性任務計劃:
(crontab更多的時候我們應用的是cron,那我們怎樣才能做到週期性執行某任務呢?什麼是連續時間什麼是不連續時間,想象一下,我們現在定義了好多的任務,有連續的,也有不連續的,這就意味着我們必須有一種機制,確保在某個時間點到達時,這個任務就提交。所以說有那麼一種機制,必須保證每時每刻隨時觀測着,看看有哪些任務該提交了,那麼誰來做這件事呢?我們需要一個服務,隨時處於運行狀態,而這個服務他將一直運行在後臺,在每一個時間點不斷的檢查有哪些任務該執行了,這就需要一個服務程序不間斷的,去監聽去查看對應的時間點是否滿足條件,然後讓其運行。這種服務程序對於我們的系統來講,一般靠的就是程序包,這個程序包叫做cronie,這個包中有兩個程序包其中, cronie:這是一個主程序包,提供了crond守護進程及相關輔助工具;真正提供服務的是這個叫crond的文件。)
服務程序:
cronie:主程序包,提供了crond守護進程及相關輔助工具;
確保crond守護進程(daemon)處於運行狀態;
(對於centos5 和centos6, centos7還不一樣
CentOS7:
systemctl status crond.service //crond後面的“.service”可以省略
顯示:active(running)表示正常
也可以執行:service crond status
CentOS6:
service crond status
顯示:isrunning..表示正常
CentOS5:執行的命令跟centos6一樣
在centos7系統上我們需要使用
“systemctl status crond.service”這個命令來來查看這個服務的狀態:如果出現一個綠色的active(running)則表示這個服務是正常的,也可以在centos7上使用centos6上的命令:
“service crond status”
在centos6上執行命令
是:“service crond status”顯示“is running....”表示這個服務正常運行
[root@centos6 testdir]# service crond status
crond (pid 2819) is running...
[root@centos6 testdir]#
)
只有crond這個服務能夠正常運行,才能確保我們之後定義的週期性任務計劃能夠完成。
所以週期任務也需要像cat那樣提供任務作業給crond
但是向crond提交作業的方式不同於at,他需要使用專用的配置文件,此文件有固定格式,並且不建議直接使用文本編輯器直接編輯此文件;要使用crontab命令。
(原因就是使用vim編輯器直接編輯此文件的話,不能進行語法格式的檢查,而使用crontab命令,會自動進行語法檢查,一旦發現文件中的語法錯誤,他會拒絕提交文件,或者提醒用戶文件中有語法錯誤,)
cron任務分爲兩類:
系統cron任務:主要用於實現系統自身的維護。
(比方說/tmp目錄下本來就是臨時文件,如果這些臨時文件創建超過一 個月,那我們需要清除這些臨時文件,這就是系統自身的維護操縱,而 這種任務都是允許在系統安裝完成後,自動運行的。對於系統任務我們 不能使用crontab命令,而是手動編輯配置文件)
手動編輯配置文件:/etc/crontab文件(現在基本都不需要手動編輯了)
用戶cron任務:用戶手動編輯任務文件,根據自身需要寫的任務。
命令:crontab命令
系統cron的配置格式:
[root@centos7 ~]# cat /etc/crontab
SHELL=/bin/bash //前面這些不帶#的都是定義環境變量的,定義哪種SHELL來運行腳本
PATH=/sbin:/bin:/usr/sbin:/usr/bin //到哪些路徑下找我們的命令,這裏定義的路徑很少,但是我們系統上的PATH路徑很多,所以我們一定要注意的是,有很多命令在往cron文件寫的時候,上面的PATH路徑可能是不夠用的,所以導致的結果是很多時候我們的命令需要些絕對路徑。甚至我們自己寫的腳本,腳本的運行也應用的是上面定義的PATH,也就意味着我們的腳本中的命令也就只能識別到上面的PATH路徑,如果沒有的,我們就需要自定義PATH路徑,或者寫命令的絕對路徑,在腳本中。
MAILTO=root //這個任務計劃完成後,郵件發送給誰
# 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
[root@centos7 ~]#
注意總結:系統cron指定的配置。
(1)每一行定義一個週期性任務一共有 七個字段;前五個定義時間,第六個定義身份,最後一個表示指定任務的。
“* * * * *”前五個用空格隔開的五個字段表示定義週期性時間;
user-name:運行任務的用戶身份
commandto be executed:任務
(2)此處的環境變量不同於用戶登錄後獲得的環境,因此,建議命令使用絕對路徑, 或者自定義PATH環境變量;
(3)執行結果郵件發送給MAILTO指定的用戶;
用戶cron的配置格式:
用戶cron的配置文件是/var/spool/cron/USERNAME文件
其中/var/spool/cron/USERNAME //這個大寫就表示要替換的用戶名,也就 是表示新建的cron已經是以新用戶身份
進行運行,所以命令中就不需要用戶名了
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59) //第一個星號*表示分鐘,取值範圍爲0-59
# | .------------- hour (0 - 23) //第二個星號*表示小時,取值範圍爲0-23
# | | .---------- day of month (1 -31) //第三個星號*表示天,其值範圍爲1-31
# | | | .------- month (1 - 12) OR jan,feb,mar,apr... //表示月,其實範圍爲1-12
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | | //最後一個星號*表示星期幾,0和7都表示週日。我們也可以使用星 期的英文簡寫來表示
# * * * * * user-name command to be executed //在用戶cron文件中沒有用戶 名,因爲對於用戶而言誰編輯的就發給誰
注意:
(1)每行定義一個cron任務,共6個字段;比系統cron文件中少了一個“user-name”
(2)此處的環境變量不同於用戶登錄後獲得的環境,因此,建議命令使用絕對路徑, 或者自定義PATH環境變量;
(3)郵件發送給當前用戶;
上面已經從空間上大體已經說明了,接下來說一下cron文件中的時間點怎樣指;
時間表示法:對系統cron和用戶cron都是通用的
注意:
(1)特定值:
給定時間點有效取值範圍內的值;
注意:day of week(星期幾)和day of month(月)一般不同時使用;
(2)*
星號*有特殊意義,表示:給定的時間點上有效取值範圍內的所有值;
比方說,在分鐘的*上寫分鐘時,其取值範圍爲1-59;所以也可以說 *是通配符。這樣寫就表示:“每什麼什麼,在分上就表示沒分,在時 上就表示每小時,在天上就表示每天,在月上,就表示每月,在週上 就表示每週”
(3)離散取值:使用逗號隔開“,”
在中間時間點上使用逗號分隔的多個數值;#,#,#
(4)連續其值:使用減符號“-”#-#
(5)在指定的時間範圍上,定義步長;使用“/”表示;
在指定的時間內,控制
/#:#即步長
*/2:每多少,執行一次任務;
舉例演示:
(1)3 * * * *:(每小時執行一次)表示每小時第三分鐘執行一次 ;
這個“3”表示幾點的3分,也就是每小時三分鐘。
總結:當我們說每多少的時候,我們就找時間點單位最小的那個*即可。
(2)3 4 * * 5:(每週執行一次)表示每週五的4點3分;(表示每週執行一 次)
這裏要注意,月給了周就不要給了,周給了月就不要給了。
(3)5 6 7 * *:(每月執行一次)表示每月的7日6點5分執行一次;
(4)7 8 9 1 0 *:(每年執行一次)表示每年的10月9日每年的10月9日 8點七點半
(5)9 8 * * 3,7: 每週三和週日上午八點九分執行;
(6)0 8,20 * * 3,7:每週三和週日上午和下午八點9分;
(7)0 9-18 * * 1-5:工作時間內每小時運行;
(8)*/5 * * * * :表示每5分鐘執行一次計劃任務;
(9)*/7 * * * :表示每多少分鐘執行一次
注意:
(1)指定的時間點不能被步長整除時,其意義將不復存在。
(2)對於crontab最小時間單位爲分鐘。完成“秒”級任務,得需要額外藉助於 其他的機制;
定義每分鐘任務,而在利用腳本實現在每分鐘之內,循環執行多少次;
crontab命令:
格式:
crontab [-u user] [-l | -r | -e] [-i] [-s]
選項:
-e:編輯任務;
舉例:crontab -e 直接回車就打開一個文件,直接編輯即可
-l:列出所有任務;
-r:移除所有任務;即刪除文件/var/spool/cron/USERNAME文件;
如果只想刪除其中某一個任務,那就直接crontab -e重新編輯文件,把要刪的那 一行刪除或者加上註釋即可。
-i:在使用-r選項移除所有任務時提示用戶確認;
-u user:root用戶可爲指定用戶管理cron任務;
舉例:crontab -u dong -e
舉例:
在用戶cron的配置文件中,我們手動編輯一個配置文件。
* * * * * /bin/echo "hello!" 這表示每分鐘輸出一個hello!
注意:運行結果以郵件方式通知給當前用戶,如果拒絕接收郵件;
(1)COMMAND >/dev/null
(2)COMMAND &> /dev/null
注意:定義COMMAND時,如果命令需要用到%,需要對其轉義;但放置於單引號中的%不用轉義亦可;
思考:
某任務在指定的時間因關機未能執行,下次開機會不會自動執行?
解:
不會!
如果期望某時間因故未能按時執行,下次開機後無論是否到了響應的時間點都 要執行一次,可使用anacron實現;
課外作業:anacron及其應用;
練習:
1.每12小時備份一次/etc/目錄至/backups目錄中,保存文件稱格式爲 “etc-yyyy-mm-dd-hh.tar.xz”
2.每週2,4,7備份/var/log/secure文件至/logs目錄中,文件名格式爲 “secure-yyyymmdd”
3.每兩小時取出當前系統/proc/meminfo文件中以S或M開頭的行信息追加至 /tmp/meminfo.txt文件中;