3

Bash 支持颜色,即\033[31m切换到红色并\033[0m切换回无色。

我想制作一个小的 bash 包装器,它可以可靠地将 stderr 显示为红色,即它应该放在来自 stderr 的所有内容\033[31m之前和之后。\033[0m

我不确定这是否可行,因为当两个并行进程(甚至一个进程)同时写入 stdout 和 stderr 时,必须有一种方法可以逐个字符地区分两者。

4

2 回答 2

1

着色文本很简单:阅读每一行并在开头和结尾使用适当的转义序列回显它。但是着色标准错误变得棘手,因为标准错误不会传递给管道。

这是一种通过交换标准错误和标准输出,然后过滤标准输出来工作的方法。

这是我们的测试命令:

#!/bin/bash

echo hi
echo 'Error!' 1>&2

wrapper脚本:

#!/bin/bash
(# swap stderr and stdout
 exec 3>&1 # copy stdout to fd 3
 exec 1>&2 # copy stderr to fd 1
 exec 2>&3- # move saved stdout on fd 3 over to 2
 "${@}") | while read line; do
                echo -e "\033[31m${line}\033[0m"
           done

然后:

$ ./wrapper ./test-command
hi
Error! # <- shows up red

不幸的是, wrapper 命令的所有输出都来自stderr, not stdout,因此您无法将输出通过管道传输到任何其他脚本中。您可能可以通过创建一个临时 fifo来解决这个问题……但希望这个小包装脚本足以满足您的需求。

于 2013-01-22T05:46:40.697 回答
1

基于 andrewdotn 的包装器

变化:

  • 将 stderr 输出放回 stderr
  • 避免echo -e处理行中的内容

包装

#!/bin/bash

"${@}" 2> >(
while read line; do
    echo -ne "\033[31m" 1>&2
    echo -n "${line}" 1>&2
    echo -e "\033[0m" 1>&2
done
)

问题:输出行最终分组,而不是混合 stdout/stderr

测试脚本:

#!/bin/bash

echo Hi
echo "\033[32mStuff"
echo message
echo error 1>&2
echo message
echo error 1>&2
echo message
echo error 1>&2

输出:

Hi
\033[32mStuff
message
message
message
error # <- shows up red
error # <- shows up red
error # <- shows up red
于 2015-07-09T18:54:57.187 回答