1. 程式人生 > >shell在crontab中不能執行問題的解決方案

shell在crontab中不能執行問題的解決方案

問題描述

最近在實現一個定時重啟tomcat的工作,指令碼寫好之後執行沒有問題,但是放到crontab中卻一直無法執行。具體表現就是重啟tomcat的過程中並沒有將舊的tomcat程序刪除就起了新的tomcat程序,由此引起程序過多的問題。

解決思路

指令碼很簡單,直接執行沒有問題,所以不是指令碼內容的問題。很明確問題來自於crontab執行指令碼過程。指令碼執行可能產生問題的可以先向許可權、路徑、環境變數這三個方向排查。

  • 許可權:當前crontab使用者可能沒有許可權執行指令碼的一些需要較高許可權的語句。解決些類問題只需將指令碼放在擁有較要許可權的使用者之下就可以了。
  • 路徑:對於shell在crontab中無法執行的問題,許可權不足的問題相對來說發現的比較容易,但是此類問題佔的比例未不多。路徑和環境變數佔有很大的比重。路徑主要指的是crontab配置任務時指定的指令碼路徑,最好使用絕對路徑。
  • 環境變數:寫好指令碼直接執行其實是在互動式的shell中執行,互動式shell的環境變數與crontab中的不同就是產生問題的根源,需要在指令碼的開頭加入環境變數的設定。

解決方案

  1. 將指令碼任務置於與之許可權相適應的使用者的crontab之下。
  2. 修改原有crontab中的任務設定,指令碼的路徑使用絕對路徑,注意一些轉義字元的使用。(PS:路徑寫法中有很多細節的部分,後面有時間的話再補充完善,目前就先作個引子)
    以重啟tomcat任務為例:
0 1 * * * /root/restart.sh

改後為

0 1 * * * /root/&&bash restart.sh
  1. 設定指令碼的環境變數,在原有指令碼的開頭加入
    PATH=/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/home/x/bin ①
    ①是echo $PATH的結果
    當然要是一些特殊的環境變數,也需要在指令碼的開頭一併寫明

思考

關於shell環境變數的問題
什麼是shell環境變數?shell作為核心的一個外殼,通過它我們可以直接把命令列遞交給核心,當然核心也會處理後返回。shell有一個父程序,我們執行的任何shell程式,都是由此產生的一個sub-shell(子shell),所謂環境變數其實就是那些會傳給子程序的變數。

最後的最後,如果分析得深入一點還涉及到linux啟動過程與shell的關係,偽終端與shell的關係。限於本人對linux理解有限就在此瞎BB了,有興趣的話可以檢視《Linux與unix shell程式設計指南》和《shell十三問》