Cron

crontab 條目中有 7 個項目是什麼意思?

  • August 10, 2022

一些同事建議我添加一個 cron 作業來做一些事情,但執行crontab -e並添加以下行:

0 1 * * * . /path/to/some/file.bash

為了確保這件事正常工作,我將其更改為

0 1 * * * . /path/to/some/file.bash && date >> /some/log

這樣我就可以檢查/some/log每天確實沒有更多的線路。

然而這並沒有發生。

出於調試的目的,我剛剛將這三行添加到crontab -e,

* * * * * echo "uffa" >> /home/me/without-user
* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user

我的使用者名在哪裡me,這導致創建了所有三個文件,但只有第一個文件每分鐘增長一行,正如您從我在 8 分鐘後所做的檢查中看到的那樣:

$ for f in ~/with*; do echo ''; echo $f; cat $f; done

/home/emdeange/with-any-user

/home/emdeange/without-user
uffa
uffa
uffa
uffa
uffa
uffa
uffa
uffa

/home/emdeange/with-user

發生了什麼?第二行和第三行是否使用了錯誤的語法,因為該行多了一個條目?如果是這樣,那為什麼還要創建文件呢?


我剛剛驗證了執行一個像這樣的廢話命令jflkdasjflaksd > someFile會創建一個 empty someFile,它告訴我這兩行

* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user

只是錯誤的,並且文件是在錯誤發生之前創建的,因為 shell 命令行處理是如何工作的。

然而,這些是為其他人工作的線路。怎麼了?

好的,首先,有兩種略有不同的crontab格式。一個用於每個使用者的 crontab,另一個用於系統 crontab(/etc/crontab和 中的文件/etc/cron.d/)。

個人 crontab 有五個欄位用於時間和日期,其餘行用於命令。系統 crontab 有五個欄位用於時間和日期,第六個欄位用於使用者執行命令,其餘行用於命令。總共 6 和 7,如果您願意,儘管命令的最後一個“欄位”與其他“欄位”的定義略有不同。

個人 crontab 沒有使用者名欄位,因為它是 crontab 中隱含的所有者是誰,並且不允許普通使用者以其他人的身份執行程序。

(正如評論中所指出的,root使用者的個人 crontab 也只是像任何其他使用者一樣的個人 crontab。它沒有使用者名欄位,儘管root在其他方面有點特殊。所以不僅是/etc/crontab與以 root 身份獲得的crontab -e,它也有不同的格式。)


然後是.. 它告訴 shell 讀取作為參數命名的腳本,並在目前 shell中執行它(一些 shellsource稱為 的別名.)。此後,任何函式定義和變數分配都是可見的,這與將腳本作為單獨的程序執行時不同。

0 1 * * * . /path/to/some/file.bash

告訴 shell(即 cron 啟動).../file.bash在同一個 shell 中執行。我不確定他們為什麼建議這樣做,而不是直接執行命令而不使用點。不必初始化新的 shell 可能會有輕微的優化,但缺點是腳本必須可以在 cron 啟動的 shell 中執行。如果 cron 啟動例如一個普通的 sh,這將不起作用,但該腳本是用於 zsh 或 Python 的。

如果該行在全域 crontab 中,則意味著以/path/to/some/file.bashuser身份執行.。這可能不是它的意思。

為了簡單起見,我建議這樣做(在使腳本可執行並添加適當的 hashbang 行之後,如果尚未完成):

0 1 * * * /path/to/some/file.bash

然後,如果. /some/script && date >> logfile沒有工作,首先要看的是腳本是否因錯誤退出。您在&&那裡使用了運算符,它告訴外殼程序僅在左側命令成功退出時才執行右側命令。你可以. /some/script; date >> logfile無條件地執行它。或者,您也可以嘗試. /some/script; printf "run at %s, exit status %d\n" "$(date)" "$?" >> logfile保存退出狀態。


至於這些:

* * * * * echo "uffa" >> /home/me/without-user
* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user

在個人 crontab 中,第一個告訴 shell 執行echo,第二個執行一個名為 的命令me,第三個呼叫一個名為 的腳本echo。所有都包含一個重定向,並且重定向在命令啟動之前由 shell 處理,因此在所有情況下都會創建您的文件。(它們必須是,因為 shell 在嘗試執行之前無法知道命令是否可執行,如果成功,控制權將傳遞給該命令,因此 shell 不能再對重定向做任何事情。)

後面的兩個可能會提供錯誤消息,如果您的 cron 設置正確,您應該在電子郵件中收到這些消息。


然而,這些是為其他人工作的線路。怎麼了?

如上所述,. /path/to/some/script嘗試在 shell 中執行給定的腳本,它會因二進制命令而失敗,因此. echo ...不太可能工作。0 1 * * * username echo ...可以在全域 crontab 中工作,但可能不在個人 crontab 中。0 1 * * * . whatever不太可能在全球範圍內工作,因為.可能不是有效的使用者名。

引用自:https://unix.stackexchange.com/questions/713149