捕获正常(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 中运行脚本是没有意义的。

相关内容