2007年5月24日 星期四

Cron , Anacron

工作排程 :
指定的時間一到 , 系統就會執行我們所指定的工作 .
工作的時間設定有 "分" , "時" , "日" , "月" , "週" , 五個欄位來設定運用 .
而工作的內容可以是任何可以在 Shell 下執行的指令或程式 .


像系統對於一些 Log files , 就是利用工作排程 ,
每天檢查各個 logfile 是否須要 rotate(/etc/cron.daily/logrotate) .

一般 RedHat 系列的 Linux 發行版內預設都會有安裝 cron 的相關 rpm 套件 ,
(如 vixie-cron , crontabs , anacron)


cron


啟動指令為
service  crond  start

/etc/rc.d/init.d/crond  start


請確認每次開機時 , crond 都會自動啟動 .
chkconfig  crond  on



cron 的主要設定檔為 /etc/crontab


檔案中
第一行是設定 cron 在執行工作時 , 所使用的 shell , 預設為 /bin/bash ,
第二行設定 PATH 變數 ,
第三行設定管理員的 mail 位置 , 工作排程所執行的各個指令或 script file ,
            若有 "標準輸出" 及 "錯誤輸出" 的資訊 , 它都會把這些資訊寄到這裡設定的 mail 帳號 .
第四行設定執行排程內的指令或 script file 時的家錄目位置 .


井字號(#) 開頭的那行是說明 , 不會執行 .


再下來就是設定什麼時間點要做什麼事情的設定了 .
這裡我們分兩個部份來看 ,


前五個欄位是設定時間點 , 第六個欄位以後就是要執行的指令了 ,
前五個欄位分別代表的是 "分" , "時" , "日" , "月" , "週" .
設定方式 :
: 0 到 59 中間的任意整數 .
: 0 到 23 中間的任意整數 .
: 1 到 31 中間的任意整數 .
: 1 到 12 中間的任意整數 .
: 是指星期幾的意思 , 可設定 0 到 7 中間的任意整數 .( 0 and 7 都是指星期天)


星號(*) 代表任意數 ,
放在 "分" 的欄位代表每分鐘 , 放在 "時" 的欄位代表每小時 ,
放在 "日" 的欄位代表每天 ...............................


也可以用區間表示法 , 如 1-5 , 放在 "日" 的欄位時 , 代表 1 日到 5 日 .


若時間不是連續的 , 如 1 , 3 , 5 , 則可用逗點分開 ,
要是在 "週" 的欄位設定 1,3,5 , 代表星期一 ,  星期三 , 星期五 這三天 .


如果是要設定每隔多少時間要來執行指令 , 則可用斜線(/) 來表示 ,
如 , 每隔十分鐘可這樣寫 */10 , 每隔三天可這樣寫 */3 .



換個方式舉例說明 :
範例 說明
 1  1  *  *   *   * 每小時一分的時候
 2  2  4   *   *   * 每天凌晨四點零二分的時候
 3  22  4  *  *  0 每個星期天的凌晨四點二十二分的時候
 4  42  4  1  *  * 每個月一號的凌晨四點四十二分的時候
 5  */10  *  *  *  * 每十分鐘
 6  *  *  1,3,5  *  * 每個月一號,三號,五號的時候





第六個欄位以後 , 就是要執行的指令了 ,
再一次來看看設定檔 /etc/crontab



第六個欄位開始 :
root 是指用 root 的身份執行 ,
run-parts 是 crontabs 套件附的 Script , 其後必須跟著一個資料夾的路徑 ,
它會去執行這個資料夾內的所有執行檔 .


換個方式再解釋一次 :


01  *  *  *  *  root  run-parts  /etc/cron.hourly
每小時一分的時候 , 用 root 的身份執行 /etc/cron.hourly 資料夾內的所有執行檔 .


02  4  *  *  * root  run-parts  /etc/cron.daily
每天凌晨四點零二分的時候 , 用 root 的身份執行 /etc/cron.daily 資料夾內的所有執行檔 .


22  4  *  *  0 root  run-parts  /etc/cron.weekly
每個星期天凌晨四點二十二分的時候 , 用 root 的身份執行 /etc/cron.weekly 資料夾內的所有執行檔 .


42  4  1  *  * root  run-parts  /etc/cron.monthly
每個月一號凌晨四點四十二分的時候 , 用 root 的身份執行 /etc/cron.monthly 資料夾內的所有執行檔 .




看到這兒 , 就可以很明顯的看出來 , 這個排程的套件 , 已經安排好排程設定的架構 ,


如果我們小時都要執行某一支 Script ,
只要把這支 Script 或其連結檔(link file)放在 /etc/cron.hourly 資料夾內就可以了,


如果我們都要執行某一支 Script ,
只要把這支 Script 或其連結檔(link file)放在 /etc/cron.daily 資料夾內就可以了,


如果我們每一都要執行某一支 Script ,
只要把這支 Script 或其連結檔(link file)放在 /etc/cron.weekly 資料夾內就可以了,


如果我們每個都要執行某一支 Script ,
只要把這支 Script 或其連結檔(link file)放在 /etc/cron.monthly 資料夾內就可以了,



Q : 那又如果我要執行某一支 Script 或指令的時間 , 並不在它預設好的時間內怎麼辦呢 ?


A : 這時可以自己寫一個排程的設定檔 , 把這個設定檔放到 /etc/cron.d 的資料夾下即可 .
設定檔的格式 , 就依照上面說明的格式 :
一行一個排程 , 前五個欄位是時間點 , 後面跟著指令或 script file 的位置 .


譬如說 , 我要每天凌晨零點零分時 , 對 "國家時間與頻率標準實驗室" 所提供的 ntp server 做網路校時的動作 , 所以我可以寫一個排程的設定檔 , 放在 /etc/cron.d 之內 ,
設定檔 /etc/cron.d/ntp 的內容如下 :
0  0  *  *  *  /usr/sbin/ntpdate  time.stdtime.gov.tw


P.S. ntpdate 指令 , 請參考 "NTP 網路校時client端設定" 一文 .



crond 會每分鐘去讀取一次 /etc/crontab 及 /etc/cron.d/ 內的排程設定檔 , 所以如果對某一設定檔有做過修改 , 一分鐘後會自動生效 , 不須要重新啟動 crond .









Q : 排程的時間還沒到 , 就把系統關機了 , 時間過後才再開機 , 這些排程不就執行不到了嗎 ?
A : 是的 . 這是必須要注意的地方 .
Q : 可是我看 /var/log/ 下的各個 log 檔都有 rotate , 也就是說 /etc/cron.daily/logrotate 這個檔還是有執行啊 !!
A : 是的 . 這個檔還是有執行 .
Q : ............................................ 搞我啊 !?
A : 不是的 . 這個問題 , 是由另一個機制來解決的 , 請繼續往下看吧 !







anacron



啟動指令為
service  anacron  start

/etc/rc.d/init.d/anacron  start


請確認每次開機時 , anacron 都會自動啟動 .
chkconfig  anacron  on



anacron 的設定檔為 /etc/anacrontab , 檔案內容如下 :



同樣的 , 井字號(#) 開頭的那行是說明 , anacron 不會參考到 .
在下來的變數設定與 /etc/crontab 檔一樣 , 不再說明 .
後面三行便是主角了 , 每一行分四個部份 , 分別是 :


period : ==> 要執行工作的週期(單位:天) .
delay : ==> 延遲的時間(單位:分鐘) .
job-identifier : ==> 記錄檔檔名 .
command : ==> 工作內容(指令或 Script 檔)


anacron 的動作就是檢查某個指令或 Script(command) , 在指定的時間內(period)是否有執行過 .
如果這個指令或 Script 在指定的時間內沒有被執行過 , 那麼在另一個指定的時間過後(delay) , 執行該指令或 Script , 並把執行時的時間 , 記錄在指定的檔案內(job-identifier).


以第一個排程設定行來說明 :
1        65        cron.daily        run-parts  /etc/cron.daily
檢查 /etc/cron.daily 資料夾內的所有執行檔是否在 1 天內(period) 有被執行過 ,
如果沒有 , 那麼過 65 分鐘(delay) 後 , 執行 run-parts  /etc/cron.daily(command) ,
並把執行的時間 , 記錄在 /var/spool/anacron/cron.daily 這個檔案內(job-identifier) .



到這裡就可以很清楚的知道 , 為什麼 crond 該執行 /etc/cron.daily/logrotate 的時間前 , 系統明明關機了 ,
但開機後卻發現 /etc/cron.daily/logrotate 還是有被執行到 .
它當然不可能是在關機期間執行的 , 是開機後 , anacron 檢查出它沒有被執行到 , 才補執行的 .



另外要注意的是 , 預設的 anacron 只有設定三行 ,



若沒有自行設定 anacron , 在
/etc/cron.daily
/etc/cron.weekly
/etc/cron.monthly
這三個資料夾外的 crond 排定工作 , 是不會補執行的哦 !











參考資料













沒有留言: