crontab 條目中有 7 個項目是什麼意思?
一些同事建議我添加一個 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
會創建一個 emptysomeFile
,它告訴我這兩行* * * * * 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.bash
user身份執行.
。這可能不是它的意思。為了簡單起見,我建議這樣做(在使腳本可執行並添加適當的 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
不太可能在全球範圍內工作,因為.
可能不是有效的使用者名。