首頁 > 軟體

Linux系統crontab定時執行shell指令碼失敗的問題及解決

2023-04-08 06:02:19

1.最近開始學習Linux系統使用

經過一段時間學習終於學到了shell指令碼,因為學的東西比較零散,突發奇想我學過了crontab定時任務,今天也學了shell指令碼的編寫,為何不組合一下,既能提升學習深度,又能鍛鍊自學能力,何樂而不為呢?但是沒想到,我已步入了Linux的坑。

2.指令碼倒是很簡單

因為剛學習,寫的命令都很簡單,請各位大神不要笑我,我寫這篇部落格目的一是為了記錄踩過的坑,加深映像,二是給和我一樣的新手提個醒,避免長時間陷入到坑裡。

以下是我shell指令碼的程式碼

#!/bin/bash
date >> /myshell/date.log

 這個指令碼的作用是每次執行該指令碼,將當前時間累加寫入在/myshell/資料夾下的date.log檔案中

首先我們要給這個指令碼新增執行許可權用新增許可權的命令就行了

chmod 777 time.sh

目前我遇到的問題是要執行該指令碼,目前只能在指令碼所在目錄用./time.sh執行。所以為了解決這個問題,我經過思考和某度,找到了兩種方式讓我們的指令碼在其他目錄直接使用time.sh命令都可以執行指令碼。

第一種

我們使用$PATH檢視系統現有的環境變數目錄,也就是如果將我們的指令碼放到這些任一個目錄中,就可以在其他目錄使用time.sh來執行我們的指令碼。

但是由於這些目錄存放的檔案都是比較重要的。

或是系統檔案,所以這種方式我覺得不太推薦,當然,高手的話隨意就行,對於我這種初學者的話就儘量避開這種危險的東西。

第二種

我思考既然通過$PATH看到的這些目錄,把指令碼放進去就可以在其他地方執行,那我們應該也可以把我們寫的指令碼所在的目錄新增到這個環境變數中,這樣就可以達到我們的目的,於是根據這個思路,我又進行了某度,找到了解決方法。

可以用

vim /etc/profile

開啟這個檔案,在檔案中新增如下程式碼:

export PATH=/myshell:$PATH

新增後儲存退出,這段程式碼的原理就是在系統呼叫這個檔案的時候,將環境變數PATH和我們需要自定義的目錄拼接起來重新生成的PATH環境變數替換以前的,達到我們需要設定自定義目錄的目的,要讓我們編輯的內容生效,相當於讓系統重新載入我們修改過的這個檔案

用如下命令就行:

source /etc/profile

這樣,再用$PATH命令檢視,就可以看到我們自定義的資料夾也到PATH這個環境變數的值中了。

這時候執行一下命令time.sh發現/myshell目錄下就多了一個date.log檔案了。

再其他目錄執行time.sh命令,然後檢視date.log命令,相應時間也在檔案中累加了。

原以為再用crontab把定時執行任務設定好就大功告成,可是更大的坑才剛剛開始。

新增定時執行任務

* 11 * * * time.sh

這個任務意思就是在十一點到十二點這個範圍內,每隔一分鐘執行一下time.sh這個指令碼。具體的語法不知道的初學者可以某度一下,資料很多的。

重啟一下crontab服務

service crond restart

然後使用命令實時檢視date.log檔案累加內容的情況

tail -f date.log

等了很長時間,內容都沒變,是定時任務沒執行成功?還是指令碼出錯了?

然後趕緊瘋狂某度一下crontab執行的紀錄檔記錄檔案存放位置,實時更新檢視一下:

tail -f /var/log/cron

等了幾分鐘,發現每隔一分鐘定時任務有執行記錄

但是檢視date.log檔案,發現內容並沒有累加。

看來可能是crontab執行時候出錯了。

於是修改定時任務語句,將定時任務執行的錯誤資訊也寫入到date.log檔案中,看看報錯內容是什麼。

將定時任務修改為以下程式碼

* 11 * * * time.sh >> /myshel/date.log 2>&1

等幾分鐘,檢視date.log的內容,顯示如下

沒有找到命令,可是我剛才不管是在檔案目錄還是其他目錄都執行成功指令碼了啊,為什麼crontab執行還是報錯找不到指令碼呢?

會不會是環境變數的問題呢,帶著猜想我再次進行某度,過程很艱辛,最後算是證實我的猜想是對的,就是系統環境變數和crontab使用的環境變數不一樣導致的,其中過程由於篇幅有限,我就不細述了,直接說解決辦法

最後我找到兩解決辦法 

第一:定時任務語句中以root使用者來執行,修改定時任務語句如下:

* 11 * * * su - root -c time.sh

而後發現指令碼成功執行了。

第二:定時任務指令碼前面加上指令碼所在目錄絕對路徑,定時任務語句修改為:

* 11 * * * /myshell/time.sh

再次觀察,指令碼也成功執行了。

當然,我還查到了其他很多方法,時間有限,沒有一一測試,大家有興趣的話可以多試試其他方法。

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com