如何设置STDOUT和STDERR的字体颜色

ung*_*ban 38 unix shell terminal

我想区分终端中的STDOUT和STDERR消息.如果脚本或命令在终端中打印消息,我想按颜色区分; 可能吗?

(例如stderr字体颜色为红色,stdout字体颜色为蓝色.)

示例(使用粗体):

$date
Wed Jul 27 12:36:50 IST 2011

$datee
bash: datee: command not found

$alias ls
alias ls='ls --color=auto -F'

$aliass ls
bash: aliass: command not found

kil*_*sh9 55

在bash shell或脚本中创建一个函数:

color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

$ color command -program -args
Run Code Online (Sandbox Code Playgroud)

它将stderr以红色显示命令.

继续阅读以了解其工作原理.此命令演示了一些有趣的功能.

  • color()... - 创建一个名为color的bash函数.
  • set -o pipefail - 这是一个shell选项,用于保存输出通过管道传输到另一个命令的命令的错误返回码.这是在子shell中完成的,子shell由括号创建,以便不更改外壳中的pipefail选项.
  • "$@" - 作为新命令执行函数的参数. "$@"相当于"$1" "$2" ...
  • 2>&1-重定向的stderr命令,以stdout使其变成sedstdin.
  • >&3- 简写1>&3,重定向stdout到新的临时文件描述符3. 3被送回stdout以后.
  • sed ...- 由于上面的重定向,sed's stdinstderr执行命令的.它的功能是用颜色代码包围每一行.
  • $'...' 一个bash结构,使它能理解反斜杠转义的字符
  • .* - 匹配整条线.
  • \e[31m - ANSI转义序列,导致以下字符为红色
  • &- sed替换字符,扩展为整个匹配的字符串(在本例中为整行).
  • \e[m - 重置颜色的ANSI转义序列.
  • >&2-速记1>&2,这个重定向sedstdoutstderr.
  • 3>&1- 将临时文件描述符重定向3stdout.

  • russ我希望我能给你一个巨大的赏金.+1 (2认同)
  • +1我必须承认,你的答案比我的好(但我不能转让它的接受).你的传奇是我穿上T恤的东西.:) (2认同)
  • @ killdash9-感谢您共享脚本。我发现,当它们交错插入时,它会始终交换某些stdout和stderr的顺序。有简单的解决方法吗?如果我想出一个,我会在这里发布一个。 (2认同)

Cos*_*atu 23

这是我想到的一个黑客,它似乎工作:

鉴于以下别名的可读性:

alias blue='echo -en "\033[36m"'
alias red='echo -en "\033[31m"'
alias formatOutput='while read line; do blue; echo $line; red; done'
Run Code Online (Sandbox Code Playgroud)

现在,您需要先将终端中的字体颜色设置为红色(默认情况下,将用于stderr).然后,运行您的命令并通过formatOutput上面定义的stdout管道(它只是将每一行打印为蓝色,然后将字体颜色重置为红色):

shell$ red
shell$ ls / somenonexistingfile | formatOutput
Run Code Online (Sandbox Code Playgroud)

上面的命令将在stderr和stdout中打印,你会看到线条的颜色不同.

希望这可以帮助


更新:

为了使这个可重用,我把它全部放在一个小脚本中:

$ cat bin/run 
#!/bin/bash
echo -en "\033[31m"  ## red
eval $* | while read line; do
    echo -en "\033[36m"  ## blue
    echo $line
    echo -en "\033[31m"  ## red
done
echo -en "\033[0m"  ## reset color
Run Code Online (Sandbox Code Playgroud)

现在您可以在任何命令中使用它:

$ run yourCommand
Run Code Online (Sandbox Code Playgroud)


gos*_*pes 12

我通过将文件描述符链接到自定义函数来为stderr red着色,该函数为通过它的所有内容添加颜色.添加到以下内容.bashrc:

export COLOR_RED="$(tput setaf 1)"
export COLOR_RESET="$(tput sgr0)"

exec 9>&2
exec 8> >(
    perl -e '$|=1; while(sysread STDIN,$a,9999) {print 
"$ENV{COLOR_RED}$a$ENV{COLOR_RESET}"}'
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; } 
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'
Run Code Online (Sandbox Code Playgroud)

那么发生了什么?调试陷阱在执行命令之前和之后立即执行.因此,在执行命令之前重定向stderr以启用红色输出.在显示提示之前评估PROMPT_COMMAND,并将此恢复stderr恢复到正常状态.这是必要的,因为PS1PS2(你的提示)打印在stderr上,我不想要红色提示.瞧,红色输出超过stderr!

  • @LukeDavis在这里,由于链接问题的答案,我提出了两个可能的解决方案,其中第二个更容易阅读:https://pastebin.com/QQQFTP4X和https://pastebin.com/ n1n9PcDD.我没有彻底测试过他们中的任何一个.在这个帖子中看到病人的答案.stderrred可能是要走的路. (2认同)