
有一個透過 cron 運行的腳本,其中包含以下行:
0 * * * * (/var/script.sh | tee -a /var/script.log)
如何重寫 cron 條目以捕獲正常輸出stdout
和錯誤stderr
輸出?它們將被放置在不同的文件中。
答案1
cron
作業預設運行sh
,無論是sh
Bourne 還是 POSIXsh
或相容的,語法都是:
0 * * * * /var/script.sh 2>&1 | tee -a /var/script.log
其中,|
導致任一側的兩個命令與管道連接並行運行,左側命令的 stdout (fd 1) 插入管道的寫入端,右側命令的 stdin (fd 0) 插入管道的寫入端閱讀結束。
透過加入2>&1
左側,我們使 fd 2 (stderr) 指向與 fd 1 所指出的相同資源:管道的寫入端,因此 的正常輸出和錯誤輸出都會script.sh
轉到管道 to tee
。
tee
會將其寫入其標準輸出(在 cron 作業的情況下是一個管道或臨時文件,將用於向用戶發送電子郵件)和script.log
.
該語法在fish
shell 中也適用。
使用(t)csh
,zsh
或bash
(4.0 或更高版本),您還可以執行以下操作:
SHELL=/bin/zsh # or tcsh, bash ...
0 * * * * /var/script.sh |& tee -a /var/script.log
(在哪裡SHELL=/bin/zsh
告訴你如何cron
使用不同的 shell 來解釋命令列)。
在 中fish
,您可以使用&|
代替|&
.
對於rc
( 的一次後繼者sh
) 或導數,語法為:
SHELL=/bin/rc # or es, akanga
0 * * * * /var/script.sh >[2=1] | tee -a /var/script.log
使用zsh
,您也可以不使用它,這tee
要歸功於它的MULT_IOS
功能:
SHELL=/bin/zsh
0 * * * * /var/script.sh >&1 2>&2 >>& /var/script.log
這也有利於保留 的script.sh
退出狀態,並且還可以將script.sh
的 stderr 保持為原始 stderr script.log
(儘管這在 cron 作業中沒有太大區別,其中 stdout 和 stderr 通常會轉到無論如何都是同一個地方)。
一些 Bourne/POSIX 之類的 shell(至少bash
)有一個選項,您可以使用它來報告管道任何組件中的錯誤:ksh93
zsh
yash
mksh
pipefail
SHELL=/bin/ksh # or zsh, bash...
0 * * * * set -o pipefail && /var/script.sh 2>&1 | tee -a /var/script.log
答案2
cron 想要告訴您任何產生輸出的 cron 作業。它想透過電子郵件將結果發送給您。如果您不想接收 cron 的電子郵件,請確保您的作業不會產生輸出:不要使用tee
,只需重定向輸出
0 * * * * /var/script.sh >> /var/script.log 2>&1
另請注意,我刪除了括號:在子 shell 中運行腳本是沒有意義的。