繁体   English   中英

将 stdout 和 stderr 显示到控制台和文件,将 stderr 着色为红色并在生成时显示 stdout 和 stderr

[英]Display stdout and stderr to both console and file, color stderr red and display stdout and stderr as they are being produced


我严格要求 *stdout* 和 *stderr* 同时重定向到控制台和文件,其中 *stderr* output 被涂成红色。
此外,*stdout* 和 *stderr* 行应该按照它们产生的顺序显示(我会更好地解释我的意思)。
我的问题是在 bash 脚本中完全实现这一点,因为每个单独的步骤并不是真正的大挑战。


a) 在控制台和文件中显示 *stdout* 和 *stderr*
有很多信息如何实现这一点。 就像是:
 mycommand 2>&1 | tee mylog.log

但是,如前所述,我需要的还不止这些。

b) 在控制台上将stderr 涂成红色
同样,不是一个大问题:

 exec 3>&1 mycommand 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' EXIT_CODE=${PIPESTATUS[0]} #exit status of command exec 3>&- #housekeeping, close file handle 3

基本上,每条标准输出行都被注入 ansi 代码以将它们变为红色。 当然,需要一个与 ansi 兼容的控制台——我正在为 Windows 使用 cmder/ConEmu。

无论如何,output 正是我所需要的。 事实上,这就是我所说的“ stdoutstderr按它们的生成顺序显示”的意思:

正确的输出 (图 1 - 右输出)

c) 联合起来
这也应该很简单,例如:

 myfunc() { exec 3>&1 set -o pipefail mycommand 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' EXIT_CODE=${PIPESTATUS[0]} #exit status of $EXEC_COMMAND exec 3>&- #housekeeping, close file handle 3 echo exit_code: $EXIT_CODE } myfunc | tee mylog.log echo "EXIT_CODE: $EXIT_CODE"

但这并不简单。 至少对我来说不是,即因为现在 mycommand 的stderr仅在我退出我的应用程序后才显示(它是在运行“mycommand”时执行的):

错误的输出 (图 2 - 错误输出)

此外,作为副作用,我无法设法在 function 之外获取 EXIT_CODE 值。
我看到了类似的问题,但似乎都与在子 shell 中运行的 while 循环、“重定向”和\或“进程替换”有关。 我仍然无法解决我的具体问题。


所以,我的问题是:

  1. 如何将标准输出和标准错误同时用于控制台和文件,有红色的标准错误行和“标准输出和标准错误在生成时显示”(见图 1)?
  2. 如何获取 function 主体之外的 EXIT_CODE 值?


感谢您的时间!

即因为现在 mycommand 的 stderr 仅在我退出我的应用程序后才显示

如何将标准输出和标准错误同时用于控制台和文件,有红色的标准错误行和“标准输出和标准错误在生成时显示”(见图 1)?

当 output 不是终端时,程序的 stderr 和 stdout 都会变成块缓冲。 stdout是块缓冲的,因为mycommand没有输出到终端,并且sed s output 不是终端,它正在输出 stderr,因此 stderr 也成为块缓冲。 配置您的程序以将其 stdout/stderr 配置为行缓冲,或者您可以使用stdbuf -oL -eL设置初始缓冲并使用sed -ustdbuf -oL sed

如何获取 function 主体之外的 EXIT_CODE 值?

  1. 创建一个临时文件。
  2. $EXIT_CODE写入临时文件。
  3. 阅读那个文件。

或从您的 function 返回退出代码并像您一样使用 PIPESTATUS 。

myfunc() {
  {
      stdbuf -oL -eL mycommand 2>&1 >&3 | sed -u $'s,.*,\e[31m&\e[m,'
      EXIT_CODE=${PIPESTATUS[0]}
  } 3>&1  
  echo exit_code: $EXIT_CODE
  return "$EXIT_CODE"
}
myfunc | tee mylog.log
echo "EXIT_CODE: ${PIPESTATUS[0]}"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM