為什麼我的 cronjob 不執行我的 shell 腳本?

為什麼我的 cronjob 不執行我的 shell 腳本?

我有一個 crontab,每天晚上都會建立資料庫轉儲:

20 3 * * * /path/to/dailydump.sh

dailydump.sh包含:

#!/bin/sh

DATENAME=`date +%Y%m%d`

BASENAME="/path/to/dumps/db_${DATENAME}.sql"

/usr/bin/mysqldump -hhost -uusername -ppassword databasename > ${BASENAME}

權限是:

-rwx---r-x 1 ... dailydump.sh
drwxr-xrwx 2 ... dumps

為什麼我的 cronjob 不起作用?

我在沒有 root 存取權限的共用伺服器上。沒有登入/var/log/cron/var/log/syslog/var/mail/<user_name>或中沒有郵件(事實上,和/var/spool/mail/<user_name>中根本沒有任何內容),不郵寄任何錯誤訊息,也不保存任何日誌檔案。什麼也不返回。 (看/var/mail//var/spool/[email protected]1 2 * * * /path/to/your/command &>/path/to/mycommand.logps -ef | grep cron | grep -v grep?https://serverfault.com/a/449652

整個設定工作正常,直到我將所有檔案移至新網域並必須設定新的 crontab。 (是的,我更新了所有路徑和資料庫登入資訊。我也檢查了多次。)我在同一台電腦上使用相同的託管供應商,因此環境沒有改變。

任何幫助將不勝感激。


“解決方案”

好吧,這是最奇怪的。我的提供者的幫助中心說,如果 cronjob 執行的腳本位於受密碼保護的目錄中,我需要-auth=user:password -source在腳本的路徑之前添加。所以我添加了這一點(透過正確的身份驗證):

20 3 * * * -auth=user:password -source /path/to/dailydump.sh

結果是透過電子郵件向我發送了一條錯誤訊息(如此MAILTO=有效),告訴我/bin/sh: -=: invalid option並列出可用的選項。幫助中心的例子實際上並沒有給出物理路徑(/path/to/file),而是一個URL(http://...),所以我再次刪除authsource保存了crontab,並且現在該死的 cronjob 運行了!「crontab 看起來和以前一模一樣,一個字符一個字符,但現在它運行了,代碼沒有明顯的變化。

我不知道問題是什麼,但插入錯誤的程式碼並再次刪除它就成功了。 o_O 看起來好像 cronjob 實際上做過一直運行(因為當它不運行時,它顯然會拋出錯誤),只是它什麼也沒做!非常神秘。如果有人可以向我解釋這一點(以可重現的方式),我將提供 200 的賞金並授予它(在必要的兩天等待後)。

另外,@chaos 給了我另一個解決方案,完全避免了 shell 腳本並讓 cron 直接轉儲資料庫(請參閱下面對他的答案的評論):

20 3 * * * /usr/bin/mysqldump -hhost -uusername -ppassword 資料庫名稱 > /path/to/dumps/db_$(date +\%Y\%m\%d).sql

只是不要忘記轉義百分號,否則腳本會發現「意外的 EOF」。

感謝大家的幫忙。我又學到了很多(雖然不是這裡出了什麼問題)。

答案1

為了確保cron守護程序正在運行並遵守crontab,您可以進行一個小測試。crontab使用以下條目編輯您的:

* * * * * /bin/date >>/tmp/test

一分鐘後檢查檔案 /tmp/test.txt如果沒有文件,則守護程式很可能沒有運行。如果是這種情況,我會聯絡提供者的支援人員。

編輯:

要確定 cron 實例中的環境,您需要:

* * * * * /usr/bin/id >>/tmp/test
* * * * * /usr/bin/env >>/tmp/test

現在查看文件的內容。

答案2

  1. 直接執行腳本並檢查是否有效。
  2. 當腳本在 crontab 下執行時,某些 shell 環境變數可能無法使用,具體取決於您設定腳本的方式。

嘗試修改腳本來測試環境變數是否是問題所在:

sh --login -c "/usr/bin/mysqldump -hhost -uusername -ppassword databasename > ${BASENAME} >  /path/to/LogFile.txt 2>&1"

相關內容