我想运行几个命令,并将所有输出捕获到日志文件中。我还想将任何错误打印到屏幕上(或者可以选择将输出邮寄给某人)。
这是一个例子。以下命令将运行三个命令,并将所有输出(STDOUT 和 STDERR)写入单个日志文件。
{ command1 && command2 && command3 ; } > logfile.log 2>&1
以下是我想对这些命令的输出执行的操作:
- 所有命令的 STDERR 和 STDOUT 都会进入一个日志文件,以备日后需要——除非有问题,否则我通常不会查看这里。
- 将 STDERR 打印到屏幕上(或者可选地,通过管道传输到/bin/mail),以便突出显示任何错误并且不会被忽略。
如果返回码仍然可用就好了,这样我就可以进行一些错误处理。如果出现错误,我可能想发送电子邮件,如下所示:
{ 命令 1 && 命令 2 && 命令 3 ; } > 日志文件.log 2>&1 || mailx -s “出现错误” stefanl@example.org
我遇到的问题是 STDERR 在 I/O 重定向期间丢失上下文。 '2>&1' 会将 STDERR 转换为 STDOUT,因此如果执行 2> error.log
,我将无法查看错误这里有几个更有趣的例子。假设我正在运行一些熟悉的构建命令,但我不希望整个构建仅仅因为一个错误而停止,所以我使用了“--keep-going”标志。
{ ./configure && make --keep-going && make install ; } > build.log 2>&1
或者,这是一个简单的(也许草率的)构建和部署脚本,它会在出现错误时继续运行。
{ ./configure && make --keep-going && make install && rsync -av --keep-going /foo devhost:/foo} > build-and-deploy.log 2>&1
我认为我想要的涉及某种 Bash I/O Redirection , 但我想不通。
最佳答案
(./doit >> log) 2>&1 | tee -a log
这将获取标准输出并将其附加到日志文件。
然后 stderr 将转换为 stdout,通过管道传输到 tee
,后者将其附加到日志(如果您有 Bash 4,您可以替换 2>&1 |
使用 |&
) 并将其发送到标准输出,标准输出将出现在 tty 上或可以通过管道传输到另一个命令。
我对两者都使用了追加模式,这样无论 shell 重定向和 tee
打开文件的顺序如何,您都不会破坏原始文件。也就是说,stderr/stdout 可能以意想不到的方式交错。
关于bash - 将 STDOUT 和 STDERR 写入日志文件,同时将 STDERR 写入屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2871233/