最近更新日期:2009/09/11
1. 什麼是例行性工作排程
1.1 Linux 工作排程的種類: at, crontab 1.2 Linux 上常見的例行性工作 2. 僅執行一次的工作排程 2.1 atd 的啟動與 at 運作的方式: /etc/at.deny 2.2 實際運作單一工作排程: at, atq & atrm, batch 3. 循環執行的例行性工作排程 3.1 使用者的設定: /etc/cron.deny, crontab 3.2 系統的設定檔: /etc/crontab 3.3 一些注意事項 4. 可喚醒停機期間的工作任務 4.1 什麼是 anacron 4.2 anacron 與 /etc/anacrontab 5. 重點回顧 6. 本章習題 7. 針對本文的建議:http://phorum.vbird.org/viewtopic.php?t=23889 什麼是例行性工作排程 每個人或多或少都有一些約會或者是工作,有的工作是例行性的, 例如每年一次的加薪、每個月一次的工作報告、每週一次的午餐會報、每天需要的打卡等等; 有的工作則是臨時發生的,例如剛好總公司有高官來訪,需要你準備演講器材等等! 用在生活上面,例如每年的愛人的生日、每天的起床時間等等、還有突發性的電腦大降價 (啊!真希望天天都有!) 等等囉。 像上面這些例行性工作,通常你得要記錄在行事曆上面才能避免忘記!不過,由於我們常常在電腦前面的緣故, 如果電腦系統能夠主動的通知我們的話,那麼不就輕鬆多了!嘿嘿!這個時候 Linux 的例行性工作排程就可以派上場了! 在不考慮硬體與我們伺服器的連結狀態下,我們的 Linux 可以幫你提醒很多任務,例如:每一天早上 8:00 鐘要伺服器連接上音響,並啟動音樂來喚你起床;而中午 12:00 希望 Linux 可以發一封信到你的郵件信箱,提醒你可以去吃午餐了; 另外,在每年的你愛人生日的前一天,先發封信提醒你,以免忘記這麼重要的一天。 那麼 Linux 的例行性工作是如何進行排程的呢?所謂的排程就是將這些工作安排執行的流程之意!
咱們的 Linux 排程就是透過 crontab 與 at 這兩個東西!這兩個玩意兒有啥異同?就讓我們來瞧瞧先! Linux 工作排程的種類: at, cron 從上面的說明當中,我們可以很清楚的發現兩種工作排程的方式:
那麼在 Linux 底下如何達到這兩個功能呢?那就得使用 at 與 crontab 這兩個好東西囉!
底下我們先來談一談 Linux 的系統到底在做什麼事情,怎麼有若干多的工作排程在進行呢?然後再回來談一談 at 與 crontab 這兩個好東西! Linux 上常見的例行性工作 如果你曾經使用過 Linux 一陣子了,那麼你大概會發現到 Linux 會主動的幫我們進行一些工作呢! 比方說自動的進行線上更新 (on-line update)、自動的進行 updatedb (第七章談到的 locate 指令) 更新檔名資料庫、自動的作登錄檔分析 (所以 root 常常會收到標題為 logwatch 的信件) 等等。這是由於系統要正常運作的話, 某些在背景底下的工作必須要定時進行的緣故。基本上 Linux 系統常見的例行性任務有:
其實你的系統會進行的例行性工作與你安裝的軟體多寡有關,如果你安裝過多的軟體,某些服務功能的軟體都會附上分析工具, 那麼你的系統就會多出一些例行性工作囉!像鳥哥的主機還多加了很多自己撰寫的分析工具,以及其他第三方協力軟體的分析軟體, 嘿嘿!俺的 Linux 工作量可是非常大的哩!因為有這麼多的工作需要進行,所以我們當然得要瞭解例行性工作的處理方式囉! 僅執行一次的工作排程 首先,我們先來談談單一工作排程的運作,那就是 at 這個指令的運作! atd 的啟動與 at 運作的方式 要使用單一工作排程時,我們的 Linux 系統上面必須要有負責這個排程的服務,那就是 atd 這個玩意兒。 不過並非所有的 Linux distributions 都預設會把他打開的,所以呢,某些時刻我們必須要手動將他啟用才行。 啟用的方法很簡單,就是這樣:
重點是那個『正在啟動(或 starting)』項目的 OK 啦!那表示啟動是正常的!這部份我們在第十八章會談及。
如果您真的有興趣,那麼可以自行到 /etc/init.d/atd 這個 shell script 內去瞧一瞧先! ^_^。
至於那個 chkconfig ,你也可以使用 man 先查閱一下啊!我們第十八章再介紹啦!
既然是工作排程,那麼應該會有產生工作的方式,並且將這些工作排進行程表中囉!OK!那麼產生工作的方式是怎麼進行的? 事實上,我們使用 at 這個指令來產生所要運作的工作,並將這個工作以文字檔的方式寫入 /var/spool/at/ 目錄內,該工作便能等待 atd 這個服務的取用與執行了。就這麼簡單。 不過,並不是所有的人都可以進行 at 工作排程喔!為什麼?因為安全的理由啊∼ 很多主機被所謂的『綁架』後,最常發現的就是他們的系統當中多了很多的怪客程式 (cracker program), 這些程式非常可能運用工作排程來執行或蒐集系統資訊,並定時的回報給怪客團體! 所以囉,除非是你認可的帳號,否則先不要讓他們使用 at 吧!那怎麼達到使用 at 的列管呢? 我們可以利用 /etc/at.allow 與 /etc/at.deny 這兩個檔案來進行 at 的使用限制呢! 加上這兩個檔案後, at 的工作情況其實是這樣的:
透過這個說明,我們知道 /etc/at.allow 是管理較為嚴格的方式,而 /etc/at.deny 則較為鬆散 (因為帳號沒有在該檔案中,就能夠執行 at 了)。在一般的 distributions 當中,由於假設系統上的所有用戶都是可信任的, 因此系統通常會保留一個空的 /etc/at.deny 檔案,意思是允許所有人使用 at 指令的意思 (您可以自行檢查一下該檔案)。 不過,萬一你不希望有某些使用者使用 at 的話,將那個使用者的帳號寫入 /etc/at.deny 即可! 一個帳號寫一行。 實際運作單一工作排程 單一工作排程的進行就使用 at 這個指令囉!這個指令的運作非常簡單!將 at 加上一個時間即可!基本的語法如下:
老實說,這個 at 指令的下達最重要的地方在於『時間』的指定了!鳥哥喜歡使用『 now + ... 』 的方式來定義現在過多少時間再進行工作,但有時也需要定義特定的時間點來進行!底下的範例先看看囉!
事實上,當我們使用 at 時會進入一個 at shell 的環境來讓使用者下達工作指令,此時,建議你最好使用絕對路徑來下達你的指令,比較不會有問題喔!由於指令的下達與 PATH 變數有關, 同時與當時的工作目錄也有關連 (如果有牽涉到檔案的話),因此使用絕對路徑來下達指令,會是比較一勞永逸的方法。 為什麼呢?舉例來說,你在 /tmp 下達『 at now 』然後輸入『 mail root -s "test" < .bashrc 』, 問一下,那個 .bashrc 的檔案會是在哪裡?答案是『 /tmp/.bashrc 』!因為 at 在運作時,會跑到當時下達 at 指令的那個工作目錄的緣故啊! 有些朋友會希望『我要在某某時刻,在我的終端機顯示出 Hello 的字樣』,然後就在 at 裡面下達這樣的資訊『 echo "Hello" 』。等到時間到了,卻發現沒有任何訊息在螢幕上顯示,這是啥原因啊?這是因為 at 的執行與終端機環境無關,而所有 standard output/standard error output 都會傳送到執行者的 mailbox 去啦!所以在終端機當然看不到任何資訊。那怎辦?沒關係, 可以透過終端機的裝置來處理!假如你在 tty1 登入,則可以使用『 echo "Hello" > /dev/tty1 』來取代。
at 有另外一個很棒的優點,那就是『背景執行』的功能了!什麼是背景執行啊?很難瞭解嗎?其實與 bash 的 nohup (第十七章) 類似啦! 鳥哥提我自己的幾個例子來給您聽聽,您就瞭了!
由於 at 工作排程的使用上,系統會將該項 at 工作獨立出你的 bash 環境中,
直接交給系統的 atd 程式來接管,因此,當你下達了 at 的工作之後就可以立刻離線了,
剩下的工作就完全交給 Linux 管理即可!所以囉,如果有長時間的網路工作時,嘿嘿!
使用 at 可以讓你免除網路斷線後的困擾喔! ^_^
那麼萬一我下達了 at 之後,才發現指令輸入錯誤,該如何是好?就將他移除啊!利用 atq 與 atrm 吧!
如此一來,你可以利用 atq 來查詢,利用 atrm 來刪除錯誤的指令,利用 at 來直接下達單一工作排程!很簡單吧!
不過,有個問題需要處理一下。如果你是在一個非常忙碌的系統下運作 at ,
能不能指定你的工作在系統較閒的時候才進行呢?可以的,那就使用 batch 指令吧!
其實 batch 是利用 at 來進行指令的下達啦!只是加入一些控制參數而已。這個 batch 神奇的地方在於:他會在 CPU 工作負載小於 0.8 的時候,才進行你所下達的工作任務啦! 那什麼是負載 0.8 呢?這個負載的意思是: CPU 在單一時間點所負責的工作數量。不是 CPU 的使用率喔! 舉例來說,如果我有一隻程式他需要一直使用 CPU 的運算功能,那麼此時 CPU 的使用率可能到達 100% , 但是 CPU 的工作負載則是趨近於『 1 』,因為 CPU 僅負責一個工作嘛!如果同時執行這樣的程式兩支呢? CPU 的使用率還是 100% ,但是工作負載則變成 2 了!瞭解乎? 所以也就是說,當 CPU 的工作負載越大,代表 CPU 必須要在不同的工作之間進行頻繁的工作切換。 這樣的 CPU 運作情況我們在第零章有談過,忘記的話請回去瞧瞧!因為一直切換工作,所以會導致系統忙碌啊! 系統如果很忙碌,還要額外進行 at ,不太合理!所以才有 batch 指令的產生! 那麼 batch 如何下達指令呢?很簡單啊!與 at 相同啦!例如下面的範例:
你會發現其實 batch 也是使用 atq/atrm 來管理的!這樣瞭解乎? 循環執行的例行性工作排程 相對於 at 是僅執行一次的工作,循環執行的例行性工作排程則是由 cron (crond)
這個系統服務來控制的。剛剛談過 Linux 系統上面原本就有非常多的例行性工作,因此這個系統服務是預設啟動的。另外,
由於使用者自己也可以進行例行性工作排程,所以囉, Linux 也提供使用者控制例行性工作排程的指令 (crontab)。
底下我們分別來聊一聊囉! 使用者的設定 使用者想要建立循環型工作排程時,使用的是 crontab 這個指令啦∼不過,為了安全性的問題, 與 at 同樣的,我們可以限制使用 crontab 的使用者帳號喔!使用的限制資料有:
與 at 很像吧!同樣的,以優先順序來說, /etc/cron.allow 比 /etc/cron.deny 要優先, 而判斷上面,這兩個檔案只選擇一個來限制而已,因此,建議你只要保留一個即可, 免得影響自己在設定上面的判斷!一般來說,系統預設是保留 /etc/cron.deny , 你可以將不想讓他執行 crontab 的那個使用者寫入 /etc/cron.deny 當中,一個帳號一行! 當使用者使用 crontab 這個指令來建立工作排程之後,該項工作就會被紀錄到 /var/spool/cron/ 裡面去了,而且是以帳號來作為判別的喔!舉例來說, dmtsai 使用 crontab 後, 他的工作會被紀錄到 /var/spool/cron/dmtsai 裡頭去!但請注意,不要使用 vi 直接編輯該檔案, 因為可能由於輸入語法錯誤,會導致無法執行 cron 喔!另外, cron 執行的每一項工作都會被紀錄到 /var/log/cron 這個登錄檔中,所以囉,如果你的 Linux 不知道有否被植入木馬時,也可以搜尋一下 /var/log/cron 這個登錄檔呢! 好了,那麼我們就來聊一聊 crontab 的語法吧!
預設情況下,任何使用者只要不被列入 /etc/cron.deny 當中,那麼他就可以直接下達『 crontab -e 』去編輯自己的例行性命令了!整個過程就如同上面提到的,會進入 vi 的編輯畫面, 然後以一個工作一行來編輯,編輯完畢之後輸入『 :wq 』儲存後離開 vi 就可以了! 而每項工作 (每行) 的格式都是具有六個欄位,這六個欄位的意義為:
比較有趣的是那個『週』喔!週的數字為 0 或 7 時,都代表『星期天』的意思!另外, 還有一些輔助的字符,大概有底下這些:
我們就來搭配幾個例子練習看看吧!底下的案例請實際用 dmtsai 這個身份作看看喔!後續的動作才能夠搭配起來!
那個 crontab 每個人都只有一個檔案存在,就是在 /var/spool/cron 裡面啊! 還有建議您:『指令下達時,最好使用絕對路徑,這樣比較不會找不到執行檔喔!』
真的是很簡單吧!呵呵!那麼,該如何查詢使用者目前的 crontab 內容呢?我們可以這樣來看看:
看到了嗎? crontab 『整個內容都不見了!』所以請注意:『如果只是要刪除某個 crontab 的工作項目,那麼請使用 crontab -e 來重新編輯即可!』如果使用 -r 的參數,是會將所有的 crontab 資料內容都刪掉的!千萬注意了! 系統的設定檔: /etc/crontab 這個『 crontab -e 』是針對使用者的 cron 來設計的,如果是『系統的例行性任務』時, 該怎麼辦呢?是否還是需要以 crontab -e 來管理你的例行性工作排程呢?當然不需要,你只要編輯 /etc/crontab 這個檔案就可以啦!有一點需要特別注意喔!那就是 crontab -e 這個 crontab 其實是 /usr/bin/crontab 這個執行檔,但是 /etc/crontab 可是一個『純文字檔』喔!你可以 root 的身份編輯一下這個檔案哩! 基本上, cron 這個服務的最低偵測限制是『分鐘』,所以『 cron 會每分鐘去讀取一次 /etc/crontab 與 /var/spool/cron 裡面的資料內容 』,因此,只要你編輯完 /etc/crontab 這個檔案,並且將他儲存之後,那麼 cron 的設定就自動的會來執行了!
廢話少說,我們就來看一下這個 /etc/crontab 的內容吧!
看到這個檔案的內容你大概就瞭解了吧!呵呵,沒錯!這個檔案與將剛剛我們下達 crontab -e 的內容幾乎完全一模一樣!只是有幾個地方不太相同:
由於 CentOS 提供的 run-parts 這個 script 的輔助,因此 /etc/crontab 這個檔案裡面支援兩種下達指令的方式, 一種是直接下達指令,一種則是以目錄來規劃,例如:
好!你現在大概瞭解了這一個咚咚吧!OK!假設你現在要作一個目錄,讓系統可以每 2 分鐘去執行這個目錄下的所有可以執行的檔案,你可以寫下如下的這一行在 /etc/crontab 中: */2 * * * * root run-parts /etc/cron.min 當然囉, /etc/cron.min 這個目錄是需要存在的喔!那如果我需要執行的是一個『程式』而已, 不需要用到一個目錄呢?該如何是好?例如在偵測網路流量時,我們希望每五分鐘偵測分析一次, 可以這樣寫: */5 * * * * root /bin/mrtg /etc/mrtg/mrtg.cfg 如何!建立例行性命令很簡單吧!如果你是系統管理員而且你的工作又是系統維護方面的例行任務時, 直接修改 /etc/crontab 這個檔案即可喔!又便利,又方便管理呢! 一些注意事項 有的時候,我們以系統的 cron 來進行例行性工作的建立時,要注意一些使用方面的特性。
舉例來說,如果我們有四個工作都是五分鐘要進行一次的,那麼是否這四個動作全部都在同一個時間點進行?
如果同時進行,該四個動作又很耗系統資源,如此一來,每五分鐘不是會讓系統忙得要死?
呵呵!此時好好的分配一些執行時間就 OK 啦!所以,注意一下:
當大量使用 crontab 的時候,總是會有問題發生的,最嚴重的問題就是『系統資源分配不均』的問題, 以鳥哥的系統為例,我有偵測主機流量的資訊,包括:
如果每個流程都在同一個時間啟動的話,那麼在某個時段時,我的系統會變的相當的繁忙, 所以,這個時候就必須要分別設定啦!我可以這樣做:
看到了沒?那個『 , 』分隔的時候,請注意,不要有空白字元!(連續的意思)如此一來,
則可以將每五分鐘工作的流程分別在不同的時刻來工作!則可以讓系統的執行較為順暢呦!
另外一個困擾發生在『 當有執行成果或者是執行的項目中有輸出的資料時,該資料將會
mail 給 MAILTO 設定的帳號 』,好啦,那麼當有一個排程一直出錯(例如 DNS
的偵測系統當中,若 DNS 上層主機掛掉,那麼你就會一直收到錯誤訊息!)怎麼辦?呵呵!還記得十一章談到的資料流重導向吧?
直接以『命令重導向』將輸出的結果輸出到 /dev/null
這個垃圾桶當中就好了!
很多時候被植入木馬都是以例行命令的方式植入的,所以可以藉由檢查 /var/log/cron
的內容來視察是否有『非您設定的 cron 被執行了?』這個時候就需要小心一點囉!
另一個需要注意的地方在於:『你可以分別以週或者是日月為單位作為循環,但你不可使用「幾月幾號且為星期幾」的模式工作』。 這個意思是說,你不可以這樣編寫一個工作排程:
本來你以為九月十一號且為星期五才會進行這項工作,無奈的是,系統可能會判定每個星期五作一次,或每年的 9 月 11 號分別進行,如此一來與你當初的規劃就不一樣了∼所以囉,得要注意這個地方!上述的寫法是不對的喔! 可喚醒停機期間的工作任務 如果你的 Linux 主機是作為 24 小時全天、全年無休的伺服器之用,那麼你只要有 atd 與 crond
這兩個服務來管理你的例行性工作排程即可。如果你的伺服器並非 24 小時無間斷的開機,那麼你該如何進行例行性工作?
舉例來說,如果你每天晚上都要關機,等到白天才啟動你的 Linux 主機時,由於 CentOS 預設的工作排程都在
4:02am 每天進行,唔!如此一來不就一堆系統例行工作都沒有人在做了!那可怎麼辦?此時就得要 anacron 這傢伙了! 什麼是 anacron anacron 並不是用來取代 crontab 的,anacron 存在的目的就在於我們上頭提到的,在處理非 24 小時一直啟動的 Linux 系統的 crontab 的執行!所以 anacron 並不能指定何時執行某項任務, 而是以天為單位或者是在開機後立刻進行 anacron 的動作,他會去偵測停機期間應該進行但是並沒有進行的 crontab 任務,並將該任務執行一遍後,anacron 就會自動停止了。 由於 anacron 會以一天、七天、一個月為期去偵測系統未進行的 crontab 任務,因此對於某些特殊的使用環境非常有幫助。 舉例來說,如果你的 Linux 主機是放在公司給同仁使用的,因為週末假日大家都不在所以也沒有必要開啟, 因此你的 Linux 是週末都會關機兩天的。但是 crontab 大多在每天的凌晨以及週日的早上進行各項任務, 偏偏你又關機了,此時系統很多 crontab 的任務就無法進行。 anacron 剛好可以解決這個問題! 那麼 anacron 又是怎麼知道我們的系統啥時關機的呢?這就得要使用 anacron 讀取的時間記錄檔 (timestamps) 了! anacron 會去分析現在的時間與時間記錄檔所記載的上次執行 anacron 的時間,兩者比較後若發現有差異, 那就是在某些時刻沒有進行 crontab 囉!此時 anacron 就會開始執行未進行的 crontab 任務了! 所以 anacron 其實也是透過 crontab 來運作的!因此 anacron 運作的時間通常有兩個,一個是系統開機期間運作,一個是寫入 crontab 的排程中。 這樣才能夠在特定時間分析系統未進行的 crontab 工作嘛!瞭解乎! anacron 與 /etc/anacrontab anacron 其實是一支程式並非一個服務!這支程式在 CentOS 當中已經進入 crontab 的排程喔! 不相信嗎?你可以這樣追蹤看看:
基本上, anacron 的語法如下:
所以我們發現其實 /etc/cron.daily/0anacron 僅進行時間戳記的更新,而沒有進行任何 anacron 的動作! 在我們的 CentOS 中,anacron 的進行其實是在開機完成後才進行的一項工作任務,你也可以將 anacron 排入 crontab 的排程中。但是為了擔心 anacron 誤判時間參數,因此 /etc/cron.daily/ 裡面的 anacron 才會在檔名之前加個 0 (0anacron),讓 anacron 最先進行!就是為了讓時間戳記先更新!以避免 anacron 誤判 crontab 尚未進行任何工作的意思。 接下來我們看一下 /etc/anacrontab 的內容好了:
由於 /etc/cron.daily 內的任務比較多,因此我們使用每天進行的任務來解釋一下 anacron 的運作情況好了。 anacron 若下達『 anacron -s cron.daily 』時,他會這樣運作的:
所以說,時間戳記是非常重要的!anacron 是透過該記錄與目前的時間差異,瞭解到是否應該要進行某項任務的工作! 舉例來說,如果我的主機在 2009/03/15(星期天) 18:00 關機,然後在 2009/03/16(星期一) 8:00 開機,由於我的 crontab 是在早上 04:00 左右進行各項任務,由於該時刻系統是關機的,因此時間戳記依舊為 20090315 (舊的時間), 但是目前時間已經是 20090316 (新的時間),因此 run-parts /etc/cron.daily 就會在開機過 65 分鐘後開始運作了。 所以囉, anacron 並不需要額外的設定,使用預設值即可!只是我們的 CentOS 只有在開機時才會執行 anacron 就是了。如果要確定 anacron 是否開機時會主動的執行,你可以下達下列指令:
現在你知道為什麼隔了一陣子才將 CentOS 開機,開機過後約 1 小時左右系統會有一小段時間的忙碌!而且硬碟會跑個不停!那就是因為 anacron 正在執行過去 crontab 未進行的各項工作排程啦!這樣對 anacron 有沒有概念了呢? ^_^ 重點回顧
本章習題 ( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )
簡答題:
2002/05/30:第一次完成 2003/02/10:重新編排與加入 FAQ 2005/09/07:將舊的文章移動到 此處 。 2005/09/07:呼呼!終於完成風格囉∼同時加入一些習題練習。 2009/03/12:將舊的文件移動到此處。 2009/03/14:加入 batch 這個項目的說明!與 at 有關! 2009/03/15:加入了 anacron 這玩意的簡單說明! 2009/09/11:稍微修訂一下說明語氣與連結資料。 |
||||||||||||||||||||||||||||||||||||||||||||||||