彩色 xtrace 输出

2024-04-04

我有一个 .sh 脚本,它使用set -o xtrace打印以下所有命令。 我想为这些命令着色。我尝试像这样使用 PS4 变量:

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

但这只是颜色+- 角色,如果我省略\[\e[m\]我的完整输出和执行程序的输出是彩色的。 是否有另一个变量附加在打印命令之后,我可以在其中重置颜色,或者是否有其他方法。 谢谢。


The Gist

由于终端着色的工作方式,再加上 bash 跟踪的工作方式,实现起来相当难看,但实现方法如下:

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

然后,如果您的脚本被调用example.sh, 你跑

$ ./color_trace.sh example.sh 

Where ./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

这将为跟踪命令着色red https://linux.101hacks.com/ps1-examples/prompt-color-using-tput/.

解释

它的实现方式如下:

  • Insert $UNIQUE_STR到输出
  • 通过命令路由所有输出 - stdout 和 stderr (exec &> >(...))
  • 命令 (sed) 假设轨迹的形式为+++${UNIQUE_STR} <some interesting trace>
  • 查找带有以下内容的行$UNIQUE_STR (s/...\(${UNIQUE_STR}\).../)并将其删除(/...\1+\3.../, where \1 is ++ and \3 is <some interesting trace>)
  • 如果该行确实包含$UNIQUE_STR,告诉终端在该行之前将颜色设置为红色,并在该行之后取消设置颜色(/$(colored)...$(normal)/).

什么不起作用

一、功能colored() and normal()不接受一段文字要着色。相反,它们指示终端将颜色设置为接下来要写入的内容,并在写入后指示它取消设置颜色。这就是着色或任何类型的样式在 Unix 终端中的工作方式。

其次,跟踪转到 stderr,因此它将与 stderr 的其他输出混合。这可以改变使用BASH_XTRACEFD https://askubuntu.com/questions/811439/bash-set-x-logs-to-file,但在这里效果不佳。

由于您需要着色,因此假定您希望将跟踪与其他输出区分开来,因此假定所有输出(包括 stdout、stderr 和跟踪)都将发送到终端。

如果所有内容都发送到终端,那么为了使跟踪与实际输出正确交错,所有输出(stdout、stderr 和跟踪)都需要在同一文件描述符上执行。这就是为什么我们必须通过以下方式重定向一切sed,不仅仅是痕迹。如果我们只重定向跟踪,那么您将获得来自各种命令的一堆输出,只有在之后您才会看到这些命令的所有跟踪,例如

... 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,我们可以使用类似的东西:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

彩色 xtrace 输出 的相关文章

  • 批量检测系统是32位还是64位

    有谁知道如何创建一个批处理文件 如果是 64 位系统 可以对一个程序进行 shell 处理 如果是 32 位系统 则可以对另一个程序进行 shell 处理 检查 PROCESSOR ARCHITECTURE being x86 if PRO
  • grep 彩色线条

    我编写了一个简单的 PHP shell 脚本 它解析文件并输出某些元素 它产生大量的输出 采用不同的 bash 颜色 绿色表示正常 黄色表示警告 红色表示错误等 在开发过程中我想过滤掉一些行 例如 所有包含红色文本的行 我可以使用grep
  • HBase Shell 日志记录

    使用 HBase shell 时 我收到大量日志记录 包括 INFO 和 DEBUG 消息 虽然这对于学习 HBase 内部结构来说很有趣 但它非常冗长并且可能会掩盖输出 我尝试过以多种不同的方式更改日志记录级别 包括所描述的here ht
  • rsync --include 选项不排除其他文件

    尝试rsync某些扩展名 sh 的文件 但下面的bash脚本仍然传输所有文件 为什么 from home xxx rsync zvr include sh from root host home tmp 您需要添加 exclude all
  • 如何在不使用 MacPorts 或 Fink 的情况下在 OS X Leopard 上安装 lxml?

    我过去曾多次尝试过此操作并遇到问题 有没有人有在没有 MacPorts 或 Fink 的情况下在 OS X 上安装 lxml 的方法 并且绝对有效 最好有完整的 1 2 3 步骤来下载和构建每个依赖项 感谢 Twitter 上的 jesse
  • 从文件中随机采样行

    我有一个大约 40gb 和 1800000 行的 csv 文件 我想随机采样 10 000 行并将它们打印到一个新文件中 现在 我的方法是将 sed 用作 sed n vars lt input txt gt output txt Wher
  • “./somescript.sh”和“. ./somescript.sh”有什么区别

    今天我按照一些说明在 Linux 中安装软件 有一个需要首先运行的脚本 它设置一些环境变量 指令告诉我执行 setup sh 但是我执行时犯了一个错误 setup sh 所以环境没有设置 最后我注意到了这一点并继续进行 我想知道这两种调用脚
  • PHP 日志文件颜色

    我正在编写一个 PHP 日志文件类 但我想为写入文件的行添加颜色 我遇到的问题是颜色也会改变终端的颜色 我想要实现的是仅更改写入日志文件的行的颜色 class logClass extends Singleton private funct
  • 水银大号

    你知道如何让 Quicksilver 在屏幕上显示大量的大字体吗 通过点击 然后输入自由文本 选择 操作 下的 查看大字体 并按 Enter 键 好吧 有谁知道一种以编程方式做到这一点的方法吗 另外 quicksilver 是必需的还是内置
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 如何编写 bash 函数来包装另一个命令?

    我正在尝试编写一个函数包装器mysql command If my cnf存在于 pwd 中 我想自动附加 defaults file my cnf到命令 这就是我正在尝试的 function mysql if e my cnf then
  • 如何获取 bash 中从 Ping 接收到的数据包的百分比?

    当 ping 主机时 我希望输出仅显示收到的数据包 已发送 5 个 的百分比 我想我需要使用grep不知怎的 但我不知道如何 我是 bash 编程的新手 这是我所在的地方 ping c 5 q host grep grep 中应该包含什么
  • 如何从源 bash 脚本返回错误

    我对 bash 脚本相当陌生 我有 4 个嵌套的 bash 脚本 并且我无法正确地从第四个脚本传播错误 例如 script1 sh source script2 sh
  • 如何使用ansible运行询问用户输入的脚本?

    我想使用 ansible 运行 shell 脚本 但 shell 脚本需要用户输入才能成功执行 例如 我的 shell 脚本询问唯一的 idossec agent 通过ansible我可以预定义我的unique id user input
  • 通过 Bash 命令在文本文件中查找并替换

    例如 对给定输入字符串进行查找和替换的最简单方法是什么abc 并替换为另一个字符串 例如XYZ在文件中 tmp file txt 我正在编写一个应用程序并使用 IronPython 通过 SSH 执行命令 但我不太了解 Unix 也不知道要
  • bash 递归xtrace

    有没有办法运行 bash 脚本 X 以便如果 X 调用可执行 bash 脚本 Y 则 Y 以 sh eux 开头 X sh Y sh Y sh bin sh echo OK 可以通过导出子 shell 使用父 shell 中设置的相同 sh
  • 从文件开头开始 grep (grep -f )

    I use commands grep f file从文件中提取管道内容 但是 我只想在匹配字符串位于行开头时才提取 通常我使用grep string 但它不适用于grep f grep f file grep No such file o
  • 如何按文件大小对查找结果进行排序

    如何按文件大小对 find 命令的结果进行排序 我试图对这个 find 命令的结果进行排序 find src type f print0 我不需要目录的大小 我需要仅按大小排序的文件相对路径 这是如何做的using find command
  • shell中基于正则表达式的颜色突出显示输出

    我想知道是否可以用颜色突出显示与某些字符串匹配的 shell 命令的输出 例如 如果我运行 myCommand 输出如下 gt myCommand DEBUG foo bar INFO bla bla ERROR yak yak 我希望所有
  • 使用 BASH 和 AWK 创建 HTML 表

    我在创建 html 表来显示文本文件中的统计信息时遇到问题 我确信有 100 种方法可以做得更好 但这里是 以下脚本中的注释显示了输出 bin bash function getapistats curl s http api exampl

随机推荐