上一節學習了 at 指令是針對僅運作一次的任務,循環運作的例行性計劃任務,Linux 系統則是由 cron(crond)這個系統服務來控制的。Linux 系統上面原本就有非常多的計劃性工作,是以這個系統服務是預設啟動的。另外,由于使用者自己也可以設定計劃任務,是以,Linux 系統也提供了使用者控制計劃任務的指令:crontab 指令。
一、crond 簡介
crond 是Linux 下用來周期性的執行某種任務或等待處理某些事件的一個守護程序,與Windows 下的計劃任務類似,當安裝完成作業系統後,預設會安裝此服務工具,并且會自動啟動 crond 程序,crond 程序每分鐘會定期檢查是否有要執行的任務,如果有要執行的任務,則自動執行該任務。
Linux 下的任務排程分為兩類,系統任務排程和使用者任務排程。
系統任務排程:系統周期性所要執行的工作,比如寫緩存資料到硬碟、日志清理等。在 /etc 目錄下有一個 crontab 檔案,這個就是系統任務排程的配置檔案。
通過檢視 /etc/crontab 檔案,我們能發現,該檔案中,前四行是永愛配置 crond 任務運作的環境變量,第一行 shell 變量指定了系統要使用哪個shell ,第二行PATH 變量指定了系統執行指令的路徑,第三行 MATLTO 變量指定了crond 的任務執行資訊将通過電子郵件發送給 root 使用者,如果 MAILTO 變量的值為空,則表示不發送任務執行資訊給使用者,第四行的 HOME 變量指定了在執行指令或者腳本時使用的主目錄。
使用者任務排程:使用者定期要執行的工作,比如使用者資料備份、定時郵件提醒等。使用者可以使用 crontab 工具定制自己的計劃任務。所有使用者定義的 crontab 檔案都被 儲存在 /var/spool/cron 目錄中。其檔案名與使用者名一緻。
使用者權限檔案:
/etc/cron.deny 該檔案中所列使用者不允許使用 crontab 指令
/etc/cron.allow 該檔案中所列使用者允許使用 crontab 指令
/var/spool/cron 所有使用者 crontab 檔案存放的目錄,以使用者名命名
crontab 檔案的含義:
使用者所建立的 crontab 檔案中,每一行都代表一項任務,每行的每個字段代表一項設定,它的格式共分為 六個字段,前五段是時間設定段,第六段是要執行的指令段,格式如下:
minute hour day month week command
分 時 天 月 周 指令
在以上各個字段中,還可以使用一些特殊字元:
星号(*):代表所有可能的值,例如month 字段如果是星号,則表示在滿足其他字段的制約條件後每月都該執行該指令操作。
逗号(,):可以用逗号隔開的值指定一個清單範圍,例如,“1,2,3,4”
中杠(-):可以用整數之間的中杠表示一個整數範圍,例如 “2-6”表示“2,3,4,5,6”
正斜杠(/):可以用正斜杠指定時間的間隔頻率,例如“0-23/2”表示每兩個小時執行 一次。同時正斜杠可以和星号一起使用,例如 */10,如果用在 minute 字段,表示 每十分鐘執行一次。
二、crond 服務
安裝 crondtab: yum install crontabs
服務操作說明:
/sbin/service crond start, stop,restart,reload
檢視 crontab 服務是否已設定為開機啟動,執行指令:ntsysv
加入開機自啟動: chkconfig -level 35 crond on
三、crontab 指令詳解
1.指令格式:
crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]
2.指令功能:
通過crontab 指令,我們可以在固定的間隔執行指定的系統指令或 shell script 腳本。時間間隔的機關可以是分鐘、小時、日、月、周及以上的任意組合。
這個指令非常适合周期性的日志分析或資料備份等工作。
3.指令參數:
-u user:用來設定某個使用者的 crontab 服務,例如,“-u ixdba” 表示設定 ixdba 使用者的crontab 服務,此參數一般有root 使用者來運作。
file:file 是指令檔案的名字,表示将 file 作為 crontab 的任務清單檔案并載入 crontab。如果在指令行中沒有指定這個檔案,crontab 指令将接收标準輸入(鍵盤)上鍵入的指令,并将他們載入 crontab。
-e: 編輯某個使用者的 crontab 檔案内容。如果不指定使用者,則表示編輯目前使用者的 crontab 檔案。
-l: 顯示某個使用者的crontab 檔案内容,如果不指定使用者,則表示顯示目前使用者的crontab 檔案内容。
-r: 從 /var/spool/cron 目錄中删除某個使用者的 crontab 檔案,如果不指定使用者,則預設删除目前使用者的 crontab 檔案。
-i: 在删除使用者的 crontab 檔案時給确認提示。
4.常用方法:
1)建立一個新的 crontab 檔案
在考慮向cron 程序送出一個 crontab 檔案之前,首先要做的一件事情就是設定環境變量 EDITOR。cron 程序根據它來确定使用哪個編輯器編輯 crontab 檔案。
99%的 Unix 和Linux 使用者都是使用 vi,如果你也是這樣,那麼你就編輯 $HOME 目錄下的 .profile檔案,在其中加入這樣一行:
EDITOR=vi; export EDITOR
然後儲存并退出。不妨建立一個名為 user cron 的檔案,其中 user 是使用者名,例如,davecron 在該檔案中加入如下的内容。
# (put your own initials here) echo the date to the console every
# 15 munutes between 6pm and 6 am
0,15,30,45 18-06 * * * /bin/echo `date` > /dev/console >>>>>>>>>>> */15 18-06 * * * 指令
儲存并退出,确信前面5個域用空格分隔
在上面的例子中,系統将每隔15 分鐘向控制台輸出一次目前時間。如果系統崩潰或者挂起,從最後所顯示的時間就可以一樣看出系統是什麼時間停止工作的。在有些系統中,用 TTY1 來表示控制台,可以根據實際情況對上面的例子進行相應的修改,為了送出你剛剛建立的crontab 檔案,可以把這個新建立的檔案作為 cron 指令的參數:
$ crontab davecron
現在該檔案已經送出給 cron 程序,它将每隔 15 分鐘運作一次。
同時,新建立檔案的一個副本已經 被放在 /var/spool/cron 目錄中,檔案名就是使用者名(即 dave).
2)列出crontab 檔案
為了列出 crontab 檔案,可以用:
$ crontab -l
*/15 18-06 * * * /bin/echo `date` > dev/tty1
還可以使用這種方法在 $HOME 目錄中對 crontab 檔案做一備份:
$crontab -l > $HOME/mycron
3)編輯 crontab 檔案
如果希望添加、删除或者編輯 crontab 檔案中的條目,而 EDITOR 環境變量又設定為 VI ,那麼就可以用 VI 編輯器來編輯,相應的指令為 : crontab -e
可以像使用 vi 編輯其他任何檔案那樣修改 crontab 檔案并退出。如果修改了某些條目或添加了新的條目,那麼在儲存該檔案時, cron 會對其進行必要的完整性檢查。如果其中的某個域出現了超出允許範圍的值,它會提示你。
我們在編輯 crontab 檔案時,沒準會加入新的條目。例如,加入下面的一條:
# DT: delete core files , at 3.30am on 1,7,14,21,26 days of each mouth
30 3 1,7,14,21,26 * * /bin/find -name " core" -exec rm {} \;
現在儲存并退出。最好在crontab 檔案的每一個條目之上加入一條注釋,這樣就可以知道它的功能、運作時間,更為重要的是,知道這是哪位使用者的作業。
4)删除 crontab 檔案:
要删除 crontab 檔案,可以用: crontab -r
5)恢複丢失的crontab 檔案
如果不小心誤删了 crontab 檔案,假設你在自己的 $HOME 目錄下還有一個備份,那麼可以将其拷貝到 /var/spool/cron/<username>,其中<username>是使用者名。如果由于權限問題無法完成拷貝,可以用:
$ crontab <filename>
其中,<filename> 是你在 $HOME 目錄中副本的檔案名。
我建議你在自己的 $HOME 目錄中儲存一個該檔案的副本。我就有過類似的經曆,有數次誤删了 crontab 檔案(因為 r 鍵緊挨着e 鍵的右邊)。這就是為什麼會有些系統文檔不要直接編輯 crontab 檔案,而是編輯該檔案的一個副本,然後重新送出新的檔案。
有些 crontab 的變體 有些怪異,是以在使用 crontab 指令時要格外小心。如果遺漏了任何選項,crontab 可能會打開一個空檔案,或者看起來像是個空檔案。這時敲delete 鍵退出,不要 按 ctrl +D,否則你将丢失 crontab 檔案。
5.使用執行個體
執行個體1:每1分鐘執行一次 command
指令:
* * * * * command
執行個體2:每小時的第3和第15分鐘執行
指令: 3,15 * * * * command
執行個體3:在上午8點到11點的第3和第15分鐘執行
指令: 3,15 8-11 * * * command
執行個體4:每隔兩天的上午8點到11點的 第 3和 第 15分鐘執行
指令: 3,15 8-11 */2 * * command
執行個體5:每個星期一的上午8點到11點的第3和第15分鐘執行
指令:3,15 8-11 * * 1 command
執行個體6:每晚的 21:30重新開機SMB
指令:30 21 * * * /etc/init.d/smb restart
執行個體7:每月 1、10、22日的4:45 重新開機smb
指令:45 4 1,10,22 * * /init.d/smb restart
執行個體8:每周六、周日的 1:10 重新開機smb
指令: 10 1 * * 6,0 /etc/init.d/smb restart
執行個體11:每一小時重新開機 smb
指令:* */1 * * * /etc/init.d/smb restart
執行個體12:每晚11點到早上7點之間,每個一小時重新開機 smb
指令: * 23-7/1 * * * /etc/init.d/smb restart
執行個體13:每月的4号與每周一到周三的11點重新開機 smb
指令:0 11 4 * mon-wed /etc/init.d/smb restart
執行個體14:一月一号的4點重新開機smb
指令:0 4 1 jan * /etc/init.d/smb restart
執行個體15: 每小時執行 /etc/cron.hourly 目錄内的腳本
指令:0 1 * * * * root run-parts /etc/cron.hourly
run-parts 這個參數,如果去掉這個參數的話,後面就可以寫要運作的某個腳本名,而不是目錄名了。
四、使用注意事項
1.注意環境變量問題
有時我們建立了一個crontab ,但是這個任務卻無法自動執行,而手動執行這個任務卻沒有問題,這種情況一般是由于在 crontab 檔案中沒有配置環境變量引起的。
在crontab 檔案中定義多個排程任務時,需要特别注意的一個問題就是環境變量的設定,因為我們手動執行某個任務時,是在目前shell 環境下進行的,程式當然能找到環境變量,而系統自動執行任務排程時,是不會加載任何環境變量的,是以,就需要在 crontab 檔案中指定任務運作所需的所有環境變量,這樣,系統執行任務排程時就沒有問題了。
不要假定cron 知道所需要的特殊環境,它其實并不知道。是以你要保證在 shell 腳本中提供所有必要的 路徑和環境變量,除了一些自動設定的全局變量。是以注意如下3點:
1)腳本中涉及檔案路徑時寫全局路徑;
2)腳本執行要用到Java 或其它環境變量時,通過source 指令引入換将變量,如:
cat start_cbp.sh
#!/bin/sh
source /etc/profile
export RUN_CONF=/home/d139/platform/cbp/cbp_jboss.conf
/usr/local/jboss-4.0.5/bin/run.sh -c mev &
3)當手動執行腳本OK,但是 crontab 死活不執行時,這時必須大膽懷疑是環境變量惹的禍,并可以嘗試在 crontab 中直接引入環境變量解決問題。如:
0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
2.注意清理系統使用者的郵件日志
每條任務排程執行完畢,系統都會将任務輸出資訊通過電子郵件的形式發送給目前系統使用者,這樣日積月累,日志資訊會非常大,可能會影響系統的正常運作,是以,将每條任務進行重定向處理非常重要。
例如,可以在crontab 檔案中設定如下形式,忽略日志輸出:
0 */3 * * * /user/local/apache2/apachectl restart >/dev/null 2>&1
該指令表示先将标準輸出重定向到 /dev/null, 然後将标準錯誤重定向到标準輸出,由于标準輸出已經重定向到了 /dev/null, 是以标準錯誤也會重定向到/dev/null,這樣日志輸出問題就解決了。----沒看懂,錯誤日志不是應該留着做分析麼?重定向到 /dev/null不就沒了麼?
3. 系統級任務排程與使用者級任務排程
系統級任務排程主要完成系統的一些維護操作,使用者級任務排程主要完成使用者自定義的一些任務,可以将使用者級任務排程放到系統級任務排程來完成(不建議這麼做),
但是反過來卻不行,root使用者的任務排程操作可以通過 “crontab -uroot -e ”來設定,也可以将排程任務直接寫入 /etc/crontab 檔案,需要注意的是,如果要定義一個定時重新開機系統的任務,就必須将任務放到 /etc/crontab 檔案,即使在root 使用者下建立一個定時重新開機系統的任務也是無效的。
4.其他注意事項
新建立的 cron job, 不會馬上執行,至少要過2分鐘才執行,如果重新開機cron 則馬上執行。
當 crontab 突然失效時,可以嘗試 /etc/init.d/crond restart 解決問題。或者檢視日志看某個job 有沒有執行 報錯 tail -f /var/log/cron。
千萬别亂運作 crontab -r , 它從 crontab 目錄(/var/spool/cron)中删除使用者的 crontab 檔案。删除了該使用者的所有 crontab 都沒了。
在 crontab 中 %是有特殊含義的,表示換行的意思。如果要用的話必須進行轉義 \% , 如經常用的 date ‘+%Y%m%d’ 在 crontab 裡是不會執行的,應該換成
date ‘+\%Y\%m\%d’