手動在CentOS中執行sh腳本,調用java程序,一切正常;java
將該sh加入crontab中定時調度以後,掛了,徹底沒有執行到的感受啊!!!shell
查看crontab執行日誌:vim
cat /var/log/cron 有執行記錄,google
難道用crontab調用執行會報錯,打印日誌先:spa
crontab -erest
40 10 * * * /home/job.sh 2>>/home/log日誌
再調度一次,查看日誌:orm
cat /home/logblog
還真報錯了:crontab
Exception in thread "main" java.lang.ClassFormatError: SystemInfo (unrecognized class file version)
...
不能識別的java版本,大膽的懷疑crontab用的環境變量是他自個的:
cat /etc/crontab
果真,crontab本身有一個PATH變量,修改之:
vim /etc/crontab
從新用crontab調用程序,報錯依舊,重啓之:
service crond restart
再調用,繼續報錯,難道crontab的PATH是個擺設!
google之,baidu之,原來這是個坑人無數的問題,如下是查到的一些有用的資料:
http://xiachaofeng.iteye.com/blog/1405184
今天碰見一個問題,crontab的定時任務不能自動執行,可是手動執行腳本一直能成功。查到最後,發現是腳本里用了系統的環境變量。下面開始解釋:
1.crontab與環境變量
不要假定cron知道所須要的特殊環境,它其實並不知道。因此你要保證在shelll腳本中提供全部必要的路徑和環境變量,除了一些自動設置的全局變量。因此注意以下3點:
1)腳本中涉及文件路徑時寫全局路徑;
2)腳本執行要用到java或其餘環境變量時,經過source命令引入環境變量,如:
cat start_cbp.sh
#!/bin/sh
source /etc/profile
export RUN_CONF=/home/d139/conf/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.其餘應該注意的問題
1)新建立的cron job,不會立刻執行,至少要過2分鐘才執行。若是重啓cron則立刻執行。
2)每條 JOB 執行完畢以後,系統會自動將輸出發送郵件給當前系統用戶。日積月累,很是的多,甚至會撐爆整個系統。因此每條 JOB 命令後面進行重定向處理是很是必要的: >/dev/null 2>&1 。前提是對 Job 中的命令須要正常輸出已經做了必定的處理, 好比追加到某個特定日誌文件。
3)當crontab忽然失效時,能夠嘗試/etc/init.d/crond restart解決問題。或者查看日誌看某個job有沒有執行/報錯tail -f /var/log/cron。
4)千萬別亂運行crontab -r。它從Crontab目錄(/var/spool/cron)中刪除用戶的Crontab文件。刪除了該用戶的全部crontab都沒了。
5)在crontab中%是有特殊含義的,表示換行的意思。若是要用的話必須進行轉義\%,如常常用的date ‘+%Y%m%d’在crontab裏是不會執行的,應該換成date ‘+\%Y\%m\%d’`。
3.crontab中的輸出配置
crontab中常常配置運行腳本輸出爲:>/dev/null 2>&1,來避免crontab運行中有內容輸出。
shell命令的結果能夠經過‘> ’的形式來定義輸出
/dev/null 表明空設備文件
> 表明重定向到哪裏,例如:echo "123" > /home/123.txt
1 表示stdout標準輸出,系統默認值是1,因此">/dev/null"等同於"1>/dev/null"
2 表示stderr標準錯誤
& 表示等同於的意思,2>&1,表示2的輸出重定向等同於1
那麼重定向輸出語句的含義:
1>/dev/null 首先表示標準輸出重定向到空設備文件,也就是不輸出任何信息到終端,不顯示任何信息。
2>&1 表示標準錯誤輸出重定向等同於標準輸出,由於以前標準輸出已經重定向到了空設備文件,因此標準錯誤輸出也重定向到空設備文件。