前言
計劃任務,是系統自動完成任務的一種方式。其原理就像是鬧鐘一樣,到了我們指定的某一個時間點,系統就會自動的執行某種操作,實現我們想要達到的目的。在實際生產中有很多這樣類似的例子,例如,定時發送郵件,定時備份某個目錄,定時檢查計算機的磁盤利用率並及時提醒管理員。
Linux 操作系統提供了這樣的計劃任務機制,使我們能夠靈活的制定計劃任務,以達到我們實際生產中的目的。
目錄
我們將從以下幾個方面系統地介紹Linux中地計劃任務。
一次性計劃任務–at命令
週期性計劃任務–cron命令
anacron 系統
普通用戶的cron
一次性計劃任務——at命令
就像一個定時鬧鐘一樣,Linux中提供了能夠在某一個特定時刻執行某條計劃任務的命令,就是at命令。在使用at 命令的時候,要首先檢查at命令是否已經安裝,並且已經啓動。但是CentOS 7 與CentOS 6中的服務名稱已經有所變化,包括後面的cron服務也是一樣,這裏我們以at命令爲例詳細的解釋一下。
CentOS 7 中at命令
# 查詢at命令是否已經安裝 rpm -ql at /etc/at.deny #at命令的黑名單 /etc/pam.d/atd /etc/sysconfig/atd /usr/bin/at #at的一些命令 /usr/bin/atq #at的一些命令 /usr/bin/atrm /usr/bin/batch /usr/lib/systemd/system/atd.service #at命令服務的名稱 /usr/sbin/atd /usr/sbin/atrun ...... #at命令的一些文檔,此處省略 /var/spool/at #at任務的暫存目錄 /var/spool/at/.SEQ /var/spool/at/spool #查詢服務是否已經啓動 systemctl status atd #如果沒有啓動,將其啓動 systemctl start atd
CentOS 6 中at 命令
#查詢at 命令是否已經安裝 rpm -ql at /etc/at.deny #at命令的黑名單 /etc/pam.d/atd /etc/rc.d/init.d/atd #at命令的服務名稱 /etc/sysconfig/atd /usr/bin/at #at命令的一些命令 /usr/bin/atq #at命令的一些命令 /usr/bin/atrm #at命令的一些命令 /usr/bin/batch /usr/lib64/pm-utils/sleep.d/56atd /usr/sbin/atd /usr/sbin/atrun ...... /var/spool/at #計劃任務的暫存目錄 /var/spool/at/.SEQ /var/spool/at/spool # 查詢命令是否已經啓動 service atd status atd (pid 2089) is running... # 如果命令沒有啓動的話,將其啓動 systemctl start atd
at 命令的通用格式
at [option] TIME
at命令的常用選項
-V 顯示版本信息: -l: 列出指定隊列中等待運行的作業;相當於atq -d: 刪除指定的作業;相當於atrm -c: 查看具體作業任務 -f /path/from/somefile:從指定的文件中讀取任務 -m:當任務被完成之後,將給用戶發送郵件,即使沒有標準輸出
注意:作業執行命令的結果中的標準輸出和錯誤以郵件通知給相關用戶
TIME 定義什麼時候執行at 這項任務的時間
at命令常用的時間格式
時間格式 | 案例 | 解釋 |
---|---|---|
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 minutes | 在某個時間點再加幾個時間後才進行該項任務 |
at 命令的執行方式
在使用at命令過程中有多種方式,使用起來比較靈活。下面我們就介紹一下這幾種方式的使用,實際上大同小異,可以相互比較着去理解。
交互式
交互式定義計劃任務的方式,是一種比較常用的也比較簡單的方式。管理員可以在命令行直接輸入需要定時執行的任務即可。
注意:交互式定義計劃任務的時候,Ctrl+D 退出命令
#使用at命令定義一個計劃任務 [root@localhost ~]#at 10:55 at> rm -rf /app/hello/ at> <EOT> job 1 at Mon Aug 28 10:55:00 2017 #使用-l 選項查看計劃任務是否設置成功 [root@localhost ~]#at -l 1 Mon Aug 28 10:55:00 2017 a root #查看/var/spool/at 下是否生成了計劃任務的臨時文件#臨時文件在任務執行成功之後,會自動消失 [root@localhost ~]#ls /var/spool/at a00001017e756f spool
下面我們看一張動態圖的效果
輸入重定向
其實at 命令在制定計劃任務的時候,接收的就是標準輸入的內容,不管是使用交互式的時候,還是其他,因此將標準輸入重定向給at命令,也可以輕鬆實現定義計劃任務。
#利用管道 [root@localhost ~]#echo "echo c;echo d" | at 12:00 #利用多行重定向[root@localhost ~]#at 12:00 << EOF > echo a > echo d > EOF job 2 at Mon Aug 28 12:00:00 2017
從文件中讀入
讀取標準輸入還有一種方式就是從文件中讀取,at命令同樣支持這種方式。
#定義一個計劃任務文件 [root@localhost ~]#cat f1 echo a echo b rm -rf /app/hello/ 將計劃任務文件中計劃任務讀取出來,然後使用at命令創建計劃任務 [root@localhost ~]#at -f f1 12:00
at 命令 白名單 黑名單
白名單:/etc/at.allow 默認不存在,只有該文件中的用戶才能執行at命令
黑名單:/etc/at.deny 默認存在,拒絕該文件中用戶執行at命令,而沒有在at.deny 文件中的使用者則可執行
如果兩個文件都不存在,只有 root 可以執行 at 命令,如果兩個文件都存在,則at.deny文件失效,只有at.allow文件中白名單可以執行at命令,不在allow文件中的用戶(除了root),都不能執行at命令。如果at.allow文件爲空,則所有的用戶(除了root)都不能執行at命令,如果兩個文件都不存在,則只有root用戶可以執行at命令,其餘用戶統統拒絕。
週期性的計劃任務 cron
at命令只能定義一次計劃任務,並在某一個時間點執行,執行結束之後,如果我們還想要重複這一操作,就需要重新定義一次計劃任務,這樣的方式在實際使用過程中具有很大的侷限性,所以就需要用到週期性的計劃任務 cron 相關的程序包: cronie: 主程序包,提供crond守護進程及相關輔助工具
cronie-anacron:cronie的補充程序,用於監控cronie任務執行狀況,如cronie中的任務在過去該運行的時間點未能正常運行,則anacron會隨後啓動一次此任務 crontabs:包含CentOS提供系統維護任務
相關的服務,在CentOS 6 和CentOS 7中的名稱是不一致的。相關的查詢方法,可以參考at命令查詢方式,都是相似的。
週期性的計劃任務 分爲三種類型 系統的計劃任務,anacron 計劃任務,普通用戶的計劃任務cron
系統的計劃任務
系統的計劃任務,主要定義在/etc/crontab文件中,crontab文件內容如下所示,這裏描述了我們在定義系統計劃任務過程中需要遵循的格式,其實對於普通用戶的計劃任務的格式也是按照這種方式的,只不過系統的計劃任務只能右root用戶來定義,普通用戶是不能操作這個配置文件的。
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) # | .------------- 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 # | | | | | .---- username # | | | | | | # * * * * * user-name command to be executed # 注意,精確到分鐘,不能精確到秒
我們使用另外一張圖來詳細的瞭解一下,crontab文件的格式內容。
時間的表示有多種方法:
(1) 特定值 給定時間點有效取值範圍內的值。 如
10 13 25 3 * mage rm -rf /app/hello
(2)
*
給定時間點上有效取值範圍內的所有值
表示“每…” 如:* 13 25 3 0 mage rm -rf /app/hello
(3) 離散取值
#,#,#
如:* 13 25 3 0 mage rm -rf /app/hello
(4) 連續取值
#-#
如:* 13-15 25 3 0 mage rm -rf /app/hello
(5) 在指定時間範圍上,定義步長
/#
:#
即爲步長 */10 每10分鐘小時
系統支持的一些計劃任務命令
系統本身支持一些常用的計劃任務命令,使用這些命令可以迅速地指定計劃任務。
@reboot Run once after reboot. @yearly 0 0 1 1 * @annually 0 0 1 1 * @monthly 0 0 1 * * @weekly 0 0 * * 0 @daily 0 0 * * * @hourly 0 * * * *
例如我們想在系統的每次重啓之後,清除日誌文件夾下的所有的日誌文件(當然,實際生產中可不要這樣做啊!!),使用系統提供的計劃任務名稱會很好方便的實現,配置文件如下所示。
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) # | .------------- 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 # | | | | | .---- username # | | | | | | # * * * * * user-name command to be executed @reboot root rm -rf /var/log/* @yearly root rm -rf /var/log/* # 實際上我們就是使用 @yearly 替代了0 0 1 1 * 而已
查看我們定義的計劃任務是否已經成功執行,可以查看系統的計劃任務日誌:
/var/log/cron
Linux 系統中有一些默認的計劃任務,這些計劃任務定義在下面的這些配置文件中,可以使用root用戶去查看。
系統的計劃任務: /etc/crontab /etc/cron.d/ 配置文件 /etc/cron.deny cron黑名單 /etc/cron.hourly/ 每小時執行的任務腳本 /etc/cron.daily/ 每天都要執行的任務腳本 /etc/cron.weekly/ 每週都要執行的任務腳本 /etc/cron.monthly/ 每月都要執行的任務腳本
小貼士
週期性的計劃任務也有黑名單和白名單的設置,他們位於
/etc/cron.deny
和/etc/cron.allow
,關於黑名單和白名單與at命令的使用是一致的,這裏不再重複介紹。
如果我們不想每次都去編輯 /etc/crontab 文件來創建計劃任務的話,還有另外一種方式,我們可以按照crontab的格式寫成配置文件,然後放在/etc/cron.d/目錄下,這樣系統也會每次掃描,並定時執行。這與在crontab 中編寫計劃任務是一致的。
anacron 計劃任務
anacron 計劃任務是對cron計劃任務的一種補充。cron計劃任務的作用是定義計劃任務,並保證週期性的執行,但是這是有個前提的,那就是服務器必須是在開機的情況下,如果cron計劃任務本應該執行的時候,服務器處在關機狀態的話,計劃任務又怎麼能夠執行呢?這時anacron計劃任務的作用就凸顯出來了。
anacron 並不能指定何時執行某項任務, 而是以天爲單位或者是在開機後立刻進行 anacron 的動作,他會去偵測停機期間應該進行但是並沒有進行的 cron服務,如果有就將該任務執行一遍,然後就自動停止。
anacron 由配置文件實現,在/etc/anacrontab按照固定格式定義一些計劃任務,這些任務就會在開機之後按照設定好的計劃去運行。
[root@localhost app]#cat /etc/anacrontab # /etc/anacrontab: configuration file for anacron # See anacron(8) and anacrontab(5) for details. SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # the maximal random delay added to the base delay of the jobs RANDOM_DELAY=45 # the jobs will be started during the following hours only START_HOURS_RANGE=3-22 #period in days delay in minutes job-identifier command 1 5 cron.daily nice run-parts /etc/cron.daily 7 25 cron.weekly nice run-parts /etc/cron.weekly @monthly 45 cron.monthly nice run-parts /etc/cron.monthly
/etc/anacrontab中,各個字段的意思
字段 | 代表的含義 |
---|---|
period in days | 如果在這些日子裏沒有運行這些任務 |
delay in minutes | 在重新引導後等待這麼多分鐘後運行它 |
job-identifier | 任務識別器,在日誌文件中標識 |
command | 要執行的任務 |
系統中原有的anacron計劃任務 由/etc/cron.hourly/0anacron執行,當執行任務時,更新/var/spool/anacron/cron.daily 文件的時間戳
用戶的cron:
普通用戶也可以來制定屬於自己的計劃任務,不過普通用戶不能直接編輯 /etc/crontab 配置文件,只能使用命令來實現,
crontab命令定義,每個用戶都有專用的cron任務文件:/var/spool/cron/USERNAME,如果用戶創建了cron任務,在/var/spool/cron/ 下面就會生成一個與用戶名一致的臨時文件,裏面記錄了需要執行的計劃任務。
crontab命令的使用方式
crontab [-u user] [-l | -r | -e] [-i]
-l: 列出所有任務; -e: 編輯任務; -r: 移除所有任務; -i:同-r一同使用,以交互式模式移除指定任務 -u user: 僅root可運行,指定用戶管理cron任務
下圖演示瞭如何使用crontab 命令來創建計劃任務,以及刪除計劃任務。
在動圖的演示過程中,我們看到/var/spool/cron/這個路徑普通用戶是沒有權限直接訪問的應該使用root用戶來訪問。使用 -r 結合 -i 選項可以交互式刪除計劃任務。
綜上:在使用計劃任務的過程中有一點需要注意,如果計劃任務在執行的過程中產生了標準輸出,系統是不知道應該輸出到哪個終端的,所以只能以郵件的形式,發送給計劃任務的用戶。也就是說,計劃任務是以誰的名義執行的,郵件就會發送給誰。因此,如果在創建計劃任務過程中使用了腳本的話,最好屏蔽掉標準輸出,這樣就不會有多餘的郵件信息。
個人博客地址:http://www.pojun.tech/ 歡迎訪問