彩色xtrace输出 [英] Colored xtrace output

查看:75
本文介绍了彩色xtrace输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个.sh脚本,该脚本使用 set -o xtrace 打印以下所有命令.我想给这些命令上色.我试图像这样使用PS4变量:

I have a .sh-script that uses set -o xtrace to print all following commands. I want to color these commands. I tried to use the PS4 variable like this:

export PS4='\[\e[36m\]\+ \[\e[m\]'

但是这只会为 + 字符着色,如果我遗漏了 \ [\ e [m \] ,则我的完整输出和已执行程序的输出将被着色.在打印的命令之后是否附加了另一个变量,我可以在其中重置颜色,或者还有其他方法.谢谢.

But this colors only the +-character and if i leave out \[\e[m\] my complete output and the output of the executed program is colored. Is there another variable that is appended after the printed command where I can reset the color or is there another way. Thanks.

推荐答案

要点

由于终端着色的工作方式,再加上say bash跟踪的工作方式,因此实现起来很丑陋,但这是您的做法:

The Gist

Because of the way terminal coloring works, combined with the say bash tracing works, it's pretty ugly to implement, but here's how you do it:

首先,您需要找到一些不会出现在跟踪,stdout和stderr中的唯一字符串.在我的示例中,它是 @@@ .

First, you need to find some unique string that will appear neither in the trace, nor in stdout, nor in stderr. In my example, it's @@@.

然后,如果您的脚本名为 example.sh ,则运行

Then, if your script is called example.sh, you run

$ ./color_trace.sh example.sh 

其中 ./color_trace.sh 是此脚本:

#!/bin/bash

RED=1
UNIQUE_STR='@@@'

COLOR=$RED

normal()
{
    tput sgr0 # tell the terminal to not style the output
}

colored()
{
    tput setaf $COLOR # tell the terminal to set forward color to $COLOR
}

export PS4="+${UNIQUE_STR}" # artificially insert $UNIQUE_STR to the trace
exec &> >(sed "s/\(\+\)*\+\(${UNIQUE_STR}\)\(.*\)$/$(colored)\1+\3$(normal)/") # see below
set -x # set trace
source "$@" # run the commands in the current shell so that all settings apply

这将为跟踪命令着色红色.

它的执行方式如下:

  • $ UNIQUE_STR 插入输出中
  • 通过命令( exec&>>(...))
  • 路由所有输出-stdout和stderr-
  • 命令( sed )假定跟踪的形式为 +++ $ {UNIQUE_STR}<一些有趣的跟踪>
  • 使用 $ UNIQUE_STR ( s/... \($ {UNIQUE_STR} \).../)查找行并将其删除(/... \ 1+ \ 3 .../,其中 \ 1 ++ \ 3 <一些有趣的痕迹> )
  • 如果该行确实包含 $ UNIQUE_STR ,请告诉终端将颜色设置为该行之前的红色,并取消设置该行之后的颜色(/$(colored)...$(normal)/).
  • Insert $UNIQUE_STR to the output
  • Route all output - stdout and stderr - through a command (exec &> >(...))
  • The command (sed) assumes the trace is of the form +++${UNIQUE_STR} <some interesting trace>
  • Find lines with $UNIQUE_STR (s/...\(${UNIQUE_STR}\).../) and remove it (/...\1+\3.../, where \1 is ++ and \3 is <some interesting trace>)
  • If the line does containe $UNIQUE_STR, tell the terminal to set the coloring to red before the line, and to unset coloring after the line (/$(colored)...$(normal)/).

首先,函数 colored() normal()不接受要着色的文本.相反,他们指示终端将颜色设置为接下来要写入的内容,并在写入之后指示其取消设置颜色.这就是Unix终端中着色或任何样式的工作方式.

First, the functions colored() and normal() don't accept a piece of text to color. Instead, they instruct the terminal to set the color to whatever is going to be written next, and after it's written, instruct it to unset coloring. This is just how coloring, or any kind of styling, works in Unix terminals.

第二,跟踪到达stderr,因此它将与stderr的其他输出混合.可以使用 BASH_XTRACEFD 进行更改,但是在这里不能很好地工作.

Second, The trace goes to stderr, so it will be mixed with other output of stderr. This could be changed using BASH_XTRACEFD, but it wouldn't work well here.

由于您要着色,因此假定您要将迹线与其他输出区分开,因此假定所有输出(包括stdout,stderr和迹线)都将到达终端.

Since you want coloring, it is assumed that you want to differentiate the trace from other output, so it is assumed that all the output, including stdout, stderr, and the trace, is going to the terminal.

如果所有内容都将发送到终端,则为了使跟踪与实际输出正确交织,所有输出-stdout,stderr和跟踪-必须在同一文件描述符上执行.这就是为什么我们必须通过 sed 重定向所有内容,而不仅仅是跟踪.如果我们仅重定向跟踪,那么您将从各种命令中获得一堆输出,只有在此之后,您才能看到这些命令的所有跟踪,例如

If everything is going to the terminal, then in order for the trace to be properly interleaved with the actual output, all output - stdout, stderr, and the trace - need to be executed on the same file descriptor. That's why we have to redirect everything through sed, not just the trace. If we only redirected the trace, then you'll get a bunch of output from various commands, and only afterwards you'll see all the traces for these commands, e.g.

... actual output from /etc/passwd...
... actual output from /etc/group...
+source ./script.sh
++cat_file /etc/passwd
++cat /etc/passwd
++cat_file /etc/group
++cat /etc/group

如果不是因为文件描述符问题,我们就不需要 UNIQUE_STR ,我们可以使用类似这样的东西:

If it weren't for the file descriptor problem, we wouldn't need UNIQUE_STR, we could have just used something like:

exec 19> >(sed "s/^.*$/$(colored)&$(normal)/")
BASH_XTRACEFD=19
set -x
source "$@"

值得注意的是,即使在此版本中,我们也必须打开和关闭每一行的颜色,因为实际输出"的行需要不着色.

It's worth noting that even in this version we would have to turn colors on and off every line, because lines of "real output" need to be uncolored.

这篇关于彩色xtrace输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆