Linux計(jì)劃任務(wù):聽撫琴煮酒分享Crontab使用心得
原創(chuàng)【51CTO獨(dú)家特稿】你用過Crontab嗎?你對Crontab了解嗎?你知道如何以秒為級別執(zhí)行任務(wù)嗎?你知道怎樣讓Crontab執(zhí)行PHP腳本嗎?你知道Crontab的一些特別的用途嗎?在本文中,撫琴煮酒將向大家介紹自己多年來使用Crontab的一些心得。
作者:撫琴煮酒(Andrew.Yu)
職業(yè):Linux/unix系統(tǒng)工程師、項(xiàng)目實(shí)施工程師
服務(wù)器系統(tǒng):64Bit CentOS 5.5
雖然關(guān)于 Crontab 的介紹到處都是,詳細(xì)讀了一遍這個(gè)詞條,收獲還是有的。Crontab 這個(gè)名字來自 “chronos”,一個(gè)古希臘語, “時(shí)間”的意思(以下用法在生產(chǎn)環(huán)境下的服務(wù)器非常有用,撫琴煮酒強(qiáng)烈推薦);關(guān)于crontab的基礎(chǔ)用法和語法我就不推薦了,google和51cto上到處都是,我說的是一些進(jìn)階技巧,里面也有可能是不知道的;Shell腳本均取自于線上服務(wù)器。我安裝的服務(wù)器一般都是采用最小化安裝,安裝以后就發(fā)現(xiàn)啟動(dòng)cron的管理服務(wù)crond默認(rèn)就是啟動(dòng)的,
service crond status crond (pid 3444) is running...
手快的小伙可用chkconfig crond on讓其在level3和level5自動(dòng)運(yùn)行。
cron把命令行保存在crontab(cron table)文件里,這個(gè)文件通常在 /etc 目錄下。每個(gè)系統(tǒng)用戶都可以有自己的crontab(在 /var/spool/cron/ 下)。要查看當(dāng)前用戶的crontab,輸入
crontab -l
要編輯crontab,輸入
crontab -e
要?jiǎng)h除crontab,輸入
crontab -r
如當(dāng)前是root身份,要查看/編輯/刪除/某用戶的crontab,只需在相應(yīng)的命令后加上 -u USERNAME(如 crontab -e -u USERNAME)即可。crontab文件的默認(rèn)編輯器是vi,可以輸入
export VISUAL='editor'
更改默認(rèn)編輯器。
cron服務(wù)每分鐘不僅要讀一次 /var/spool/cron 目錄內(nèi)的所有文件,還需要讀一次 /etc/crontab 文件。配置這個(gè)文件也能讓cron執(zhí)行任務(wù)。使用crontab命令是對用戶級任務(wù)的配置,而編輯 /etc/crontab 文件是對系統(tǒng)級任務(wù)的配置。
撫琴煮酒定義的crontab語法比較好記,推薦記憶學(xué)習(xí)
分 時(shí) 日 月 星期 用戶 帶絕對路徑的命令 腳本或PHP詳細(xì)路徑
細(xì)心的你發(fā)現(xiàn)沒有,crontab最小執(zhí)行時(shí)間為分鐘,如果要求任務(wù)是以秒為級別的怎么辦,其實(shí)是有辦法的,我等會(huì)以實(shí)例說明下;服務(wù)器我建議也以/etc/crontab為主,它更方便控制用戶管理;建議服務(wù)器上的計(jì)劃任務(wù)時(shí)間錯(cuò)開,不要同時(shí)并行任務(wù),不然會(huì)在某時(shí)間段造成系統(tǒng)負(fù)載過大,搞得你的Nagios狂發(fā)報(bào)警郵件。
#p#
玩windows應(yīng)該也會(huì)發(fā)現(xiàn),windows2K系列的每修改一次系統(tǒng)管理員Administrator的密碼就是一次浩大的工程,windows的每個(gè)計(jì)劃任務(wù)scheduler都要更改密碼;CentOS下修改root密碼就簡單多了,一條passwd命令就解決問題了,而且不影響crontab的執(zhí)行。
每條 JOB 執(zhí)行完畢之后,系統(tǒng)會(huì)自動(dòng)將輸出發(fā)送郵件給當(dāng)前系統(tǒng)用戶。日積月累,非常的多,甚至?xí)伪麄€(gè)系統(tǒng)。所以每條 JOB 命令后面進(jìn)行重定向處理是非常必要的: >>/dev/null 2>&1 。前提是對 Job 中的命令需要正常輸出已經(jīng)作了一定的處理, 比如追加到某個(gè)特定日志文件;>> /dev/null 2>&1 表示把所有標(biāo)準(zhǔn)輸出發(fā)送到 /dev/null(linux的回收站),把標(biāo)準(zhǔn)錯(cuò)誤輸出(2)發(fā)送到和標(biāo)準(zhǔn)輸出(1)同樣的地方(即 /dev/null)。運(yùn)行這行命令將不會(huì)產(chǎn)生任何輸出。舉例說明如下:
30 15 13 6 1 * root tar czf /usr/local/backups/daily/etc.tar.gz /etc >> /dev/null 2>&1
CentOS/FreeBSD下用crontab定時(shí)執(zhí)行PHP程序的正確方法如下:
在linux下,可以使用crontab+php的方法:
1、使用crontab –e編輯定時(shí)任務(wù)
內(nèi)容為:
xx:xx:xx 執(zhí)行一個(gè)test.php文件
2、php文件必須在文件頭一行,加上解釋器路徑(就象perl做的那樣)
#!/usr/local/bin/php
PHP的執(zhí)行需要Apache的支持,shell腳本的執(zhí)行需要Linux的支持,而Linux支持定時(shí)運(yùn)行某個(gè)程序的功能。
---------------------------------------------------------------
將PHP作為Shell腳本語言使用(轉(zhuǎn)載)
--英文原著:Darrell Brogdon,發(fā)表于 http://www.phpbuilder.com/columns/darrell20000319.php3)
※我比較懶哈,以前的方法就是直接在/etc/crontab里直接帶上php路徑,如
*/5 * * * * root php test.php
也能正確執(zhí)行;有興趣的朋友可寫一個(gè)hello程序測試,將其所有輸出到一個(gè)文件即可測試,我做了大量測試證明其可執(zhí)行性;當(dāng)然你的php要保證其正確性,建議你的每一個(gè)crontab計(jì)劃任務(wù)先在shell中先正確運(yùn)行一次后再寫進(jìn)crontab里,這是保證成功的必要條件。
crontab如何以秒為執(zhí)行你的Linux計(jì)劃任務(wù)呢,許多同事和同學(xué)都問過我這個(gè)問題。其實(shí)這個(gè)問題很簡單,我以實(shí)例說明下:
我以前的辦公室是一臺ubuntu服務(wù)器,連接ADSL作NAT帶辦公室的機(jī)器上網(wǎng),很不幸的發(fā)現(xiàn),這樣ADSL愛掉線,一掉線網(wǎng)關(guān)gateway就沒了,所以寫了一個(gè)shell腳本
#!/bin/bash while : do if route | tail -l | grep "0.0.0.0" then &>/dev/null else adsl-stop adsl-start fi sleep 10 done
將程序放進(jìn)后臺執(zhí)行。
執(zhí)行腳本方法 nuhup sh route.sh &,注意前面要用上nohup,這樣避免root用戶logout時(shí)此腳本也退出生效的問題。
程序的運(yùn)行間隔時(shí)間是10s,很多同學(xué)不明解為什么要加一個(gè)sleep 10;大家可以拿虛擬機(jī)測試下,如果沒有這條sleep 10的語句,你的Linux服務(wù)器會(huì)運(yùn)行大量此route.sh,很快耗光你的服務(wù)器資源,你的系統(tǒng)負(fù)載會(huì)很快上去,Nagios馬上會(huì)叫起來的~
#p#
另一個(gè)就是監(jiān)控負(fù)載均衡器Nginx的shell腳本,用于 Nginx+Keepalived負(fù)載均衡高可用環(huán)境:
#!/bin/bash while : do nginxpid=`ps -C nginx --no-header | wc -l` if [ $nginxpid -eq 0 ];then /usr/local/nginx/sbin/nginx sleep 5 nginxpid=`ps -C nginx --no-header | wc -l` if [ $nginxpid -eq 0 ];then /etc/init.d/keepalived stop fi fi sleep 5 done
另外,這里附帶說下crontab的一個(gè)妙用:
我在配置一臺服務(wù)器的iptables時(shí),不小心設(shè)置了某一項(xiàng)錯(cuò)誤參數(shù),結(jié)果鎖定了SSH會(huì)話,導(dǎo)致我們經(jīng)理及另一系統(tǒng)管理員員連不上服務(wù)器,郁悶之余,看到此法特推薦給大家,極其有用,建議大家學(xué)習(xí)參考:可以配置一計(jì)劃任務(wù)crontab,每5分鐘運(yùn)行一次,即*/5 * * * * root /bin/sh /root/firestop.sh
firestop.sh內(nèi)容為
#/bin/bash service iptables stop
這樣即使你的腳本存在錯(cuò)誤設(shè)置(或丟失的)規(guī)則時(shí),也不至于將你鎖在計(jì)算機(jī)外而無法返回與計(jì)算機(jī)的連接,讓你放心大膽的調(diào)試你的腳本。
最后說明下Crontab任務(wù)的執(zhí)行環(huán)境問題。
盡管可以更改執(zhí)行 cron 任務(wù)時(shí)使用的環(huán)境,但經(jīng)常最好創(chuàng)建一個(gè)包裝腳本,以在運(yùn)行實(shí)際需要的命令前定義任何環(huán)境境變量(如PATH)。
這樣做的部分原因是出于安全考慮;向 crontab 作業(yè)開放的區(qū)域越多,越可能得到包含可疑內(nèi)容的東西。另一個(gè)原因是,這樣可確保即使更改了環(huán)境中的一個(gè)依賴關(guān)系,你的crontab作仍將執(zhí)行。
掌握以上crontab的用法后,我相信大家用Linux更可以得心應(yīng)手,工作更加happy和輕松了,希望這篇文章能給大家的運(yùn)維工作帶來幫助!
【編輯推薦】