bash - 将 STDOUT 和 STDERR 写入日志文件,同时将 STDERR 写入屏幕

标签 bash unix shell

我想运行几个命令,并将所有输出捕获到日志文件中。我还想将任何错误打印到屏幕上(或者可以选择将输出邮寄给某人)。

这是一个例子。以下命令将运行三个命令,并将所有输出(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/

相关文章:

regex - 为什么这个 `grep -o` 会失败,我应该如何解决它?

linux - 命令后更改环境

bash - 使用变量提供密码以成为 Jenkins 中的 sudo 用户

bash - 根据内容将输入拆分为多个输出?

unix - 通过wget从Dropbox链接下载包含子文件夹的文件夹到Unix服务器

linux - 尝试在我的 shell 脚本中实现 CASE

bash - 在 shell 脚本的一行末尾有多余的分号吗?

bash - 如何在bash中设置时间限制

php - 无法删除 php shell_exec() 返回值中的换行符

vb.net - Shell命令使用字符串确定文件名