為什麼 crontab 腳本不起作用?

為什麼 crontab 腳本不起作用?

通常,crontab腳本不會按計劃或按預期執行。原因有很多:

  1. 錯誤的 crontab 表示法
  2. 權限問題
  3. 環境變數

crontab該社群 wiki 旨在匯總腳本未按預期執行的主要原因。將每個原因寫在單獨的答案中。

請為每個答案提供一個原因 - 有關其未執行原因的詳細資訊 - 並針對該原因進行修復。

請僅編寫特定於 cron 的問題,例如從 shell 按預期執行但 cron 執行錯誤的命令。

答案1

環境不同

Cron 將一組最小的環境變數傳遞給您的作業。若要查看差異,請新增一個虛擬作業,如下所示:

* * * * * env > /tmp/env.output

等待/tmp/env.output創建,然後再次刪除作業。現在將 的內容與常規終端機中 run/tmp/env.output的輸出進行比較。env

這裡常見的「問題」是PATH環境變數不同。也許您的 cron 腳本使用了somecommand在 中找到的命令/opt/someApp/bin,您已將其添加到PATH/etc/environment? cron 會忽略PATH該文件,因此somecommand當使用 cron 運行時,從腳本運行將會失敗,但在終端機中運行時會起作用。值得注意的是, from 的變數/etc/environment將傳遞給 cron 作業,而不是 cron 專門設定自己的變量,例如PATH.

要解決這個問題,只需PATH在腳本頂部設定自己的變數即可。例如

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

有些人喜歡只使用所有命令的絕對路徑。我建議反對。考慮一下如果您想在不同的系統上執行腳本,並且在該系統上執行命令,會發生什麼情況/opt/someAppv2.2/bin。您必須仔細檢查整個腳本,/opt/someApp/bin/opt/someAppv2.2/bin不是僅在腳本的第一行進行小編輯。

您也可以在 crontab 檔案中設定 PATH 變量,該變數將套用於所有 cron 作業。例如

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

答案2

我的首要問題:如果您忘記在文件末尾添加換行符crontab。換句話說,crontab 檔案應該以空白行結尾。

以下是此問題的手冊頁中的相關部分(man crontab然後跳到最後):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

答案3

Cron 守護程序未執行。幾個月前我真的搞砸了。

類型:

pgrep cron 

如果你沒有看到數字(即 cron 的主 PID),則 cron 沒有運行。sudo /etc/init.d/cron start可以用來啟動cron。

編輯:不要透過 /etc/init.d 呼叫 init 腳本,而是使用服務實用程序,例如

sudo service cron start

編輯:你也可以在現代Linux中使用systemctl,例如

sudo systemctl start cron

答案4

在許多環境中 cron 使用 執行命令sh,而許多人認為它會使用bash

測試或修復失敗命令的建議:

  • 嘗試運行命令sh看看是否有效:

    sh -c "mycommand"
    
  • 將命令包裝在 bash 子 shell 中以確保它在 bash 中運行:

    bash -c "mybashcommand"
    
  • 透過在 crontab 頂部設定 shell 來告訴 cron 運行 bash 中的所有命令:

    SHELL=/bin/bash
    
  • 如果命令是腳本,請確保腳本包含 shebang:

    #!/bin/bash
    

相關內容