crontab 不能執行的原因總結,和查殺Crontab服務的僵屍進程方法


關於crontab不能執行的,初步總結了有以下幾個原因:
第一,腳本的原因:大多數情況下,我們要相信科學,相信計算機,不是有鬼,就是我們的腳本的問題,這種問題導致crontab不能執行的概率占到70%以上。因為程序執行到某一步導致crontab終止執行,我就碰到一次在遷移代碼的時候將數據庫連錯了。導致無法訪問而死在那里了。
第二,執行環境問題,當我們碰到第一情況下,一般都可以通過手動執行程序將問題扼殺在搖籃里,一般情況下高手是不應該犯第一種錯誤的。問題是當我們手動執行成功而crontab不能執行的時候,筆者碰到一次就是執行環境的問題,例如相關路徑的設置問題。解決方案:在代碼最前面執行 source /home/user/.bash_profile
第三,系統時間不正確。這種問題最好理解,也是比較常見和隱蔽的問題,解決方案:date -s ********
第四,就是我們的腳本是否有可執行權限。必須保證執行腳本的用戶有執行改文件的權限。
第五,crontab 守護進程死掉了。這種情況是極少發生的,但也不排除,當我們實在是找不到其他原因的時候可以用。解決方案:重啟該進程。
另外,介紹大家一個關於如何查看crontab最修修改時間的方法:
進入目錄/var/spool/cron/里面會有N個用戶名為文件名的文件,只要建立過crontab的用戶在這里都會有以該用戶名為文件名的文件,該文件的最后修改時間就是該用戶的的crontab的最后修改時間。just do it


有時候前置機會出現死進程等,做了這個自動查殺的腳本,已在sco unix505中測試通過,如想測試,可ps -efl >file ,自行修改file里的進程狀態及占用時間,再將腳本的輸入源由ps -efl改為從file得到,屏敝 kill -9 $pid, 即可通過tty輸出及日志文件觀察到正確結果
請大家斧正.謝謝!
(如將此腳本加入crontab,時間自定,即可達到自動查殺超時或僵死的進程)


#!/bin/ksh
#自動查殺超時或僵死的進程的腳本   V050930
#crontab -e  
#0,5,10,15,20,25,30,40,45,50,55 * * * * /usr/bin/autokill.sh &  #設置為每5分鍾檢查一次超時進程
#為了安全保險起見,此版腳本的清除范圍為:由終端啟動的,占用CUP時間超過指定時間長度的,非root用戶的進程或僵屍進程  ^_^
#檢測參數
killlog="/tmp/kill.log"    #默認自動清除超時進程或僵死進程的日志
out=60                     # 默認的超時時間,以秒為單位,默認為60秒,范圍為10秒--36000秒
trap 'rm /tmp/kill.tmp 2>/dev/null' 0 1 2 3 9 15
test $LOGNAME != root && { echo "Sorry ! 本 腳 本 只 能 由 root 操 作 !\n\n" ; exit 1 ; }
test "$out" || { echo "\n  超時時限不能為空\n" ; exit 1 ; }
test "$(echo $out | sed -n '/^[0-9][0-9]*$/p')" || { echo "\n  超時時限只能為整數值\n" ; exit 1 ; }
test $out -ge 10 -a $out -le 36000 || { echo "\n  超時時限范圍為10秒--36000秒\n" ; exit 1 ; }
#查找超時或僵屍進程
ps -efl |awk -v outtest=$out '{ outtime=timetest($14) }
$2~/Z/ || ( $3!~/root/ && $13!~/\?/ && outtime=="outtime" ) \
{print $3,$4,$13,$2,$14,$15 }
function timetest(ot)
{
hour=substr(ot,1,2)
min=substr(ot,4,2)
sec=substr(ot,7,8)
if ( hour*3600+min*60+sec > outtest)
return "outtime"
else
return "good" 
} ' >/tmp/kill.tmp 2>/dev/null
#保存清除列表
if [ -s /tmp/kill.tmp ]
then
pass=0 
error=0
echo "\n清 除 時 間:  "$(date +%y/%m/%d-%H:%M:%S)"\n" >> $killlog
awk 'BEGIN{printf("%-8s%-8s%-8s%-7s%-10s%-30s\n"),"用戶名","進程號","終端號","狀態","占用時間","任務名"} 
{ state=statetest($4) ; printf("%-8s%-8s%-8s%-7s%-10s%-30s\n"),$1,$2,$3,state,$5,$6} END{print "\n"}
function statetest(test)
{  
if (test=="S") return "睡眠"
if (test=="R") return "運行"
if (test=="Z") return "僵屍"
if (test=="O") return "不存在"
if (test=="B") return "等待"
if (test=="T") return "停止"
if (test=="I") return "中間"
}' /tmp/kill.tmp >> $killlog 2>/dev/null
#清除進程
for pid in $(awk '{print $2}' /tmp/kill.tmp |sort -rn) 
do 
kill -9 $pid  
test $? -eq 0 && \
{ echo "自動清除進程 $pid 成功" | awk '{printf("\n%-14s%-10s%-4s"),$1,$2,$3}' ; 
echo "自動清除進程 $pid 成功"   | awk '{printf("%-14s%-10s%-4s\n"),$1,$2,$3}' \
>> $killlog 2>/dev/null ;  pass=$((pass+1)) ; } || \
{ echo "自動清除進程 $pid 失敗" | awk '{printf("\n%-14s%-10s%-4s"),$1,$2,$3}' ; 
echo "自動清除進程 $pid 失敗"   | awk '{printf("%-14s%-10s%-4s\n"),$1,$2,$3}' \
>> $killlog 2>/dev/null ; error=$((error+1)) ; }
done
#保存最終統計結果
test $error -eq 0 && \
{ echo "此次共清除 ${pass} 個進程成功" | awk '{printf("\n\n%-14s%-4s%-10s\n\n"),$1,$2,$3}'
  echo "此次共清除 ${pass} 個進程成功" | awk '{printf("\n%-14s%-4s%-10s\n\n"),$1,$2,$3}' \
>> $killlog 2>/dev/null ; } || \
{ echo "此次共清除 ${pass} 個進程成功 ${error} 個進程失敗" | \
awk '{printf("\n\n%-14s%-4s%-16s%-10s%-10s\n\n"),$1,$2,$3,$4,$5}' ; 
  echo "此次共清除 ${pass} 個進程成功 ${error} 個進程失敗" | \
awk '{printf("\n\n%-14s%-4s%-16s%-10s%-10s\n\n"),$1,$2,$3,$4,$5}' >> $killlog 2>/dev/null ; }
fi



這個是UNix上寫的shell,不知在Linux上可以用不,值得探究。
來源:http://hi.baidu.com/zengyinfei/blog/item/6c2232164d239c4220a4e980.html
         http://www.oschina.net/bbs/thread/6561?lp=193


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM