Linux的crontab設定筆記

我有建立一個Linux環境做一些網路爬蟲的資料收集, 用的是在crontab建立定時排程, 執行python指令收集資料。已經收集好一段時間, 過程中也遇到一些狀況, 學習及調整, 今天把這些學到的內容和最新的做法, 做個筆記, 以免日後忘記了。

  • crontab的基本操作和設定就不在此說, 例如時間的定義
  • crontab中存取檔案或叫用程式, 最好都加上完整路徑, 因為crontab執行時用的身份和前景使用者不同, 若沒指明路徑, 可能會無法正確找到檔案來執行
  • stdout及stderr: crontab執行的結果分為正常輸出和錯誤輸出, 在設定時也會用對應的代號來標示
    • stdout, 正常輸出, 用代號1表示
    • stderr, 錯誤輸出, 用代號2表示
    • 若要丟棄輸出結果, 可以指定給 1>/dev/null 來表示, 這裡預設對象是正常輸出的代號1, 所以也可以簡單寫成 >/dev/null
    • 若要把錯誤輸出一同寫到正常輸出的地方(檔案), 可以用 2>&1 表示
  • crontab中, 可以用&&串接多個指令, 會由左至右依序執行, 但串接多個指令, 再加上以上寫到的標示完整檔案路徑, 以及輸出結果的標示, 會使指令很長, 不便於檢視, 另外也無法使用\做換行標示
  • crontab開頭可以宣告變數, 例如: PATH=/path/to/file , 在執行指令中就可以用 $PATH 來代表這個設定的變數值, crontab中的變數宣告, 不可指定動態變數值, 例如: 日期、時間
  • 針對以上2點限制, 可以改成以.sh指令檔來執行, 如下:
    • 把要執行的指令改寫到.sh檔中
    • 可以在.sh開頭用source 再引入另一個.sh
    • .sh中可以宣告動態變數值
    • 可以用\來表示換行, 以便於編排成易於閱讀的樣式。\後面不要有多餘空白, 換行後的開頭也不要有多餘字元, 以免解析整串指令錯誤
#!/bin/bash
source /path/to/base.sh
LOG_FILE=data_$($PA/date +\%4Y-\%m-\%d).log
cd $REPO && $PA/git pull -q >/dev/null 2>>$LOG/$LOG_FILE \
&& $PA/git lfs lock $REPO/data.db >>$LOG/$LOG_FILE 2>&1
  • 給予.sh檔有執行權限
chmod +x /path/to/*.sh
  • 最後再於crontab中改成以.sh檔案執行, 整個清爽很多

更新: 2024-06-14

我會每日定時把當日排程執行的Log以e-mail發給自己, 方便自己可以收e-mail就知道執行結果, 而且無須連線到crontab執行的環境中。另外, 我是把log檔內容當成e-mail的內文來發送, 而不是當成附件。不過, 排程不是每日都有安排, 當沒執行時, 就不會產生log檔, 這時若還是發-email, 就會收到一封例外的e-mail, 如下:

/bin/sh: 列 1: /path/to/log/git_2024-06-12.log: 沒有此一檔案或目錄

因此上網查也問問ChatGPT, 在排程執行時如何同時檢查檔案是否存在的做法, 就如下, 加上 [ -e /path/to/log/file.log ] 的判斷, 另外, 加上如果沒有log檔案時簡單以echo指定內文發e-mail。這裡也要注意, 中刮號[ ]和其內容設定的前後都要隔一個空格, 不要貼著內容, 否則會被當成格式不正確。

0 19 * * * [ -e $LOG/git_$($PA/date +\%4Y-\%m-\%d).log ] && mail -s "crontab result" $MAILTO < $LOG/git_$($PA/date +\%4Y-\%m-\%d).log || echo "file not exists !" | mail -s "crontab result" $MAILTO

參考資料:

https://unix.stackexchange.com/questions/461602/does-crontab-accept-commands-with-several-lines-as-shell-expected

https://www.cnblogs.com/tinywan/p/6025468.html

https://unix.stackexchange.com/questions/711595/how-to-run-a-crontab-job-only-if-a-file-exists

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料