在Linux操作系統中,除了用戶即時執行的操作命令外,還可以配置在指定的時間,指定的日期執行預先計划的系統管理任務(如定期備份、定期采集檢測數據)。CentOS系統默認已安裝了at、cronie軟件包,通過atd和crond這兩個系統服務實現一次性、周期性計划任務的功能,分別通過at、crontab命令進行計划任務設置。
一、at一次性任務設置
使用at命令設置的計划任務只在指定的時間執行一次,前提是對應的系統服務atd必須已經運行。需要注意的事,計划任務的時間,日期必須安排在當前系統時間之后,否則無法正確的設置計划任務。
使用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 即可! 一個帳號寫一行。
設置一次性任務的時候,在at命令行中依次指定執行任務的時間、日期作為參數(若只指定時間則表示當天的時間,若只指定日期則表示該日期的檔期時間)確認后將進入“at>”提示符的任務編輯頁面,每行設置一條執行命令,可以一次設置多條語句,最后按Ctrl+D組合鍵提交任務。
at:指定時間點,執行一次性任務,用法如下
at 命令:at [option] TIME
常用選項:
-V 顯示版本信息 -t time 時間格式 [[CC]YY]MMDDhhmm[.ss] -l 列出指定隊列中等待運行的作業;相當於atq -d 刪除指定的作業;相當於atrm -c 查看具體作業任務,后面跟任務隊列中的任務編號ID -f /path/file 指定的文件中讀取任務 -m 當任務被完成之后,將給用戶發送郵件,即使沒有標准輸出 TIME:定義具體執行at這項任務的時間點,TIME格式如下: HH:MM [YYYY-mm-dd] noon, midnight, teatime(4pm) tomorrow now+#{minutes,hours,days, OR weeks} TIME時間格式舉例如下: HH:MM 02:00 在今日的 HH:MM 進行,若該時刻已過,則明天此時執行任務 HH:MM YYYY-MM-DD 02:00 2016-09-20 規定在某年某月的某一天的特殊時刻進行該項任務 HH:MM[am|pm] [Month] [Date] 04pm March 17 17:20 tomorrow 在某個時間點再加幾個時間后才進行該項任務 HH:MM[am|pm] + number [minutes|hours|days|weeks] now + 5 min 02pm + 3 days
at任務的創建方式有如下幾種:
1)交互式 #輸入at命令與系統交互式創建 2)輸入重定向 #采用管道符"|" 或者"<" 輸入重定向創建 3)at -f 文件 #使用-f選項后面跟指定的文件的方式來創建
例子:
[root@localhost ~]# date //查詢時間 Sun Sep 8 13:39:14 CST 2019 [root@localhost ~]# at 13:41 2019-9-8 //指定時間設置任務 at> pgrep -U root | wc -l > /tmp/ps.root //統計改時間點root用戶運行的進程數量,保存到/tmp/ps.root文件中 at> <EOT> //任務設置完畢后,按Ctrl+D組合鍵提交任務 job 3 at Sun Sep 8 13:41:00 2019 [root@localhost ~]# cat /tmp/ps.root 132 //時間過后,查看執行效果
例子2:
[root@localhost ~]# at 22:00 2019-9-8 at> shutdown -h now at> <EOT> job 4 at Sun Sep 8 22:00:00 2019 //在2019年9月8號晚上22:00關閉系統
舉例:創建定時任務,今天18:00自動關機
[root@centos7 ~]#at 18:00 at> shutdown -p at> <EOT> #按Ctrl+D鍵正常結束輸入 job 4 at Thu Aug 22 18:00:00 2019 查看創建的at任務列表 [root@centos7 ~]#at -l #或者使用atq命令 4 Thu Aug 22 18:00:00 2019 a root [root@centos7 ~]# 查看指定任務的具體信息 [root@centos7 ~]#at -c 4 #4為指定任務的編號ID 刪除at任務 [root@centos7 ~]#at -d 4 或者 [root@centos7 ~]#atrm 4
對於已經設置但還未執行的計划任務,可以通過“atq”命令進行查詢。但是已經執行過的at任務將不會顯示在列表中,如下:
[root@localhost ~]# atq 4 Sun Sep 8 22:00:00 2019 a root
若要刪除指定編號的at任務,可以使用“atrm”命令。刪除后的at任務將不會被執行,並且不會顯示在atq命令的顯示結果中,但已經執行過的任務無法刪除。
[root@localhost ~]# atq 4 Sun Sep 8 22:00:00 2019 a root [root@localhost ~]# atrm 4 //刪除第4條at計划任務 [root@localhost ~]# atq
batch:系統自行選擇空閑時間去執行此處指定的任務 (此類計划任務由於執行時間不確定,所以使用相對較少)
舉例:創建任務,在系統空閑的時候,自動將/data目錄下的f1.log壓縮
[root@centos7 ~]#batch at> gzip /data/f1.log at> <EOT> #Ctrl+D 正常退出完成任務輸入
僅執行一次的工作調度:
其實 batch 是利用 at 來進行指令的下達啦!只是加入一些控制參數而已。這個 batch 神奇的地方在於:他會在 CPU 的工 作負載小於 0.8 的時候,才進行你所下達的工作任務啦! 那什么是工作負載 0.8 呢?
這個工作負載的意思是: CPU 在單一時間點所 負責的工作數量。不是 CPU 的使用率。
可以使用“uptime”命令,查看cpu的負載情況!
at與batch命令創建的計划任務默認存放在 /var/spool/at 目錄下
注意:at與batch命令依賴atd服務,需確保系統atd服務處於運行狀態
二、crontab周期性的任務設置
使用crontab命令設置的計划任務可以按預設的周期重復執行,從而大大減輕設置重復性系統管理任務的操作。啟用周期性任務也有一個前提條件,即對應的系統服務crond必須運行。
(1)crontab的配置文件和目錄
crontab通過多個目錄和文件設置計划任務,不同類型的任務由不同的配置文件來設置。
修改以下相關配置文件,或將需要添加計划任務的腳本放入到以下對應的目錄中
/etc/crontab 配置文件 /etc/cron.d/ 配置文件 /etc/cron.hourly/ 腳本 /etc/cron.daily/ 腳本 /etc/cron.weekly/ 腳本 /etc/cron.monthly/ 腳本
1)/etc/crontab——系統任務配置文件
/etc/crontab文件中設置的是維護Linux操作系統所需的任務,Linux操作系統及相關程序在安裝時可自動設置,不建議用戶手動修改此文件。文件內容如下:
[root@localhost ~]# cat /etc/crontab SHELL=/bin/bash //使用哪種shell接口 PATH=/sbin:/bin:/usr/sbin:/usr/bin //可執行文件搜尋路徑 MAILTO=root //若失敗,將email發送給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
文件中包括設置shell環境、可執行路徑等變量的操作,以及每小時、每天、每月需要制定的任務目錄。
根據 /etc/crontab配置文件中的設定,crond將按照不同的周期重復執行相應目錄中的任務腳本文件。
2)/var/spool/cron——用戶cron任務的配置文件存放目錄
由用戶自行設置(使用crontab命令)的cron計划任務會被保存到目錄/var/spool/cron中,文件名與用戶名相同。
crond守護進程會自動檢查/etc/crontab文件、/etc/cron.d目錄及/var/spool/cron目錄中的改動,如果發現有配置更改,他們就會被載入內存,所以當會被載入內存,所以當某個crontab文件改動后並不需要重新啟動,crond守護進程就可以使設置生效。
cron任務創建后,任務隊列存放在每個用戶專用的cron任務目錄下 /var/spool/cron/USERNAME
cron任務的日志文件位於 /var/log/cron
(2)使用crontab命令管理用戶的計划任務
設置用戶的周期性計划任務列表主要通過crontab命令進行,結合不同的選項可以完成不同的計划任務管理操作。
常用的選項有:
-e:編輯計划任務列表; -u:制定所管理的計划任務屬於哪個用戶,默認是針對當前用戶,一般只有root用戶有權限使用此選項(用於編輯、刪除其他用戶的計划任務)。 -l:列表顯示計划任務; -r:刪除計划任務列表。
1)編輯用戶的計划任務列表
執行“crontab -e”命令后,將打開計划任務編輯界面(與vi中的操作相同)。通過該界面用戶可以自行添加具體的任務配置,每行代表一個記錄。配置格式,
┌───────────── 分鍾(0 - 59) │ ┌───────────── 小時(0 - 23) │ │ ┌───────────── 天 (1 - 31) │ │ │ ┌───────────── 月 (1 - 12) │ │ │ │ ┌───────────── 周幾 (0 - 6) (周日到周六,其中周日可以用0或7表示) │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ * * * * *
如圖:
還可以使用一些特殊的符號:
* 星號 表示任意值 ,逗號 表示多個值,例如 1,2,3 - 連字符 表示連續的范圍,例如3-6,代表3,4,5,6 / 斜線 表示在指定的時間范圍上,定義步長,注意,定義的步長的值,對應字段的值需要能整除,例如在分鍾字段,*/5,表示每5分鍾,對應的執行任務的時刻點為0 5 10 15 20 25 30 35 40 45 50 55,如不能整除則無效,例如分鍾字段不能設置為7(因為60不能被7整除) L 表示最后(last),比如在周那個字段的6L表示某一個月的最后一個周六。
常用的cron表達式舉例:
每小時
0 * * * *
每2小時
* */2 * * *
每個月的10號和每個禮拜的禮拜一到禮拜三的早上11點
0 11 10 * 1-3
每天的下午2點從1分到40分的每分鍾
1-40 14 * * *
每天的早上8點到下午4點,每隔兩個小時
0 8-16/2 * * *
每年3月到6月份,每個月的1號、10號、20號,或者每個月的星期天
* * 1,10,20 3-6 0
例如:
[root@localhost ~]# crontab -e
50 7 * * * /usr/bin/systemctl start sshd //每天7點50自動開啟ssh服務 0 0 */5 * * /usr/bin/rm -rf /var/ftp/pub/* //每隔5天清空一次FTP服務器的公共目錄的數據
因各種計划任務在執行時不需要用戶登錄,所以計划任務配置記錄中的命令建議使用絕對路徑,以避免因缺少執行路徑和無法執行命令的情況。
cron任務注意事項:
1、在同時存在日期字段和星期字段的表達式中,日期和星期在條件匹配上是或者的關系,只要滿足其中一個條件,計划任務就會執行,其他字段為並且的關系,需要同時滿足才執行。
2、運行結果的標准輸出和錯誤默認會以郵件通知給相關用戶,如不希望產生大量郵件,需要將命令的輸出做重定向處理,例如:
COMMAND &> /dev/null
3、對於cron任務來講,%有特殊用途;如果在命令中要使用%,則需要轉義,將%放置於單引號中,則可不用轉義,或者將命令寫入腳本文件中。
2)查看用戶的計划任務列表
crontab命令結合“-l”選項可以查看當前用戶的計划任務列表,對於root用戶來說,還可以結合“-u”選項查看其它用戶的計划任務。操作如下:
[root@localhost ~]# crontab -l //查看用戶root自己的計划任務 50 7 * * * /usr/bin/systemctl start sshd 0 0 */5 * * /usr/bin/rm -rf /var/ftp/pub/* [root@localhost ~]# crontab -l -u lisi //查看用於lisi的計划任務
3)刪除用戶的計划任務列表
當只需要刪除某一條計划任務是,可以通過“crontab -e”命令進行編輯;而若要清空某個用戶的所有計划任務時,可以使用“crontab -r”命令。
[root@localhost ~]# crontab -r //清空當前用戶設置的計划任務 [root@localhost ~]# crontab -l no crontab for root
在設置用戶的crontab計划任務的過程中,由於每一條記錄只能運行一條命令,難以完成更復雜的系統管理任務操作,因此在實際環境中,當需要按照固定周期運行一些操作復雜的任務時,通常是將相關命令編寫成腳本,然后在計划任務配置中加載該腳本並執行。
4)可喚醒停機期間的工作任務——anacron
由於 anacron 默認會以一天、七天、一個月為期去偵測系統未進行的 crontab 任務,因此對於某些特殊的使用環境非常有 幫助。 舉例來說,如果你的 Linux 主機是放在公司給同仁使用的,因為周末假日大家都不在所以也沒有必要打開, 因此你的 Linux 是周末都會關機兩天的。但是 crontab 大多在每天的凌晨以及周日的早上進行各項任務, 偏偏你又關機了,此時系統很多 crontab 的任務就無法進行。 anacron 剛好可以解決這個問題!
那么 anacron 又是怎么知道我們的系統啥時關機的呢?這就得要使用 anacron 讀取的時間記錄文件 (timestamps) 了! anacron 會去分析現在的時間與時間記錄文件所記載的上次執行 anacron 的時間,兩者比較后若發現有差異, 那就是在某些時刻沒 有進行 crontab 啰!此時 anacron 就會開始執行未進行的 crontab 任務了!
anacron指令常用的參數:
注意:
基本上,crontab 與 at 都是“定時”去執行,過了時間就過了!不會重新來一遍~
那 anacron 則是“定期”去執行,某一段周期的執行 ~ 因此,兩者可以並行,並不會互相沖突啦!
參考:https://blog.51cto.com/14157628/2375002
https://www.cnblogs.com/eddie1127/p/11394678.html