bash包装为颜色stderr红色

时间:2013-01-22 04:30:23

标签: bash colors

Bash支持颜色,即\033[31m切换为红色,\033[0m切换回未着色。

我想制作一个小的bash-wrapper,可以可靠地将stderr输出为红色,即它应该放在\033[31m之前,\033[0m放在stderr的所有内容之后。

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

2 个答案:

答案 0 :(得分: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,而不是stdout,所以你不能将输出传递给任何进一步的脚本。你可以通过creating a temporary fifo解决这个问题...但希望这个小包装脚本足以满足你的需求。

答案 1 :(得分: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