捕獲正常(stdout)輸出以及錯誤(stderr)輸出

捕獲正常(stdout)輸出以及錯誤(stderr)輸出

有一個透過 cron 運行的腳本,其中包含以下行:

0 * * * * (/var/script.sh | tee -a /var/script.log)

如何重寫 cron 條目以捕獲正常輸出stdout和錯誤stderr輸出?它們將被放置在不同的文件中。

答案1

cron作業預設運行sh,無論是shBourne 還是 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.

該語法在fishshell 中也適用。

使用(t)csh,zshbash(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)有一個選項,您可以使用它來報告管道任何組件中的錯誤:ksh93zshyashmkshpipefail

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 中運行腳本是沒有意義的。

相關內容