关于bash:可以通过shell重定向捕获彩色输出吗?

Can colorized output be captured via shell redirect?

本问题已经有最佳答案,请猛点这里访问。

我使用的各种bash命令——花哨的diff、构建脚本等,会产生大量的颜色输出。

当我将这个输出重定向到一个文件,然后catless文件之后,着色就消失了——大概是b/c重定向输出的行为去掉了告诉终端更改颜色的颜色代码。

有没有一种方法来捕获彩色输出,包括彩色化?


捕获彩色输出的一种方法是使用script命令。运行script将启动一个bash会话,在该会话中,所有原始输出都被捕获到一个文件中(默认情况下名为typescript)。


重定向不会去除颜色,但许多命令将在向终端发送输出时进行检测,如果不这样做,则默认情况下不会生成颜色。例如,在Linux上,如果输出到管道或文件,EDOCX1(在很多地方别名为plain ls)将不会生成颜色代码,但ls --color将生成颜色代码。许多其他工具都有类似的覆盖标志,可以让它们将彩色输出保存到文件中,但这些标记都是特定于单个工具的。

即使你在一个文件中有颜色代码,要想看到它们,你需要使用一个保持它们完整的工具。less有一个-r标志,以"原始"模式显示文件数据;显示颜色代码。编辑:稍微更新一点的版本也有一个-r标志,它特别了解颜色代码并正确显示它们,比原始模式更好地支持换行/剪裁等操作,因为很少有人能分辨出哪些是控制代码,哪些实际上是要进入屏幕的字符。


受其他答案的启发,我开始使用script。不过,我不得不用-c让它工作。所有其他答案,包括tee,不同的script例子对我来说都不起作用。

语境:

  • Ubuntu 16.04
  • 使用behave运行行为测试,并在使用python的subprocess.check_call()测试期间启动shell命令。

解决方案:

1
script --flush --quiet --return /tmp/ansible-output.txt --command"my-ansible-command"

开关说明:

  • 需要--flush,因为否则输出就不能很好地进行实时观测,而是成批出现。
  • --quiet支持脚本工具的自己输出
  • -c, --command直接提供要执行的命令,从我的命令到脚本的管道不适合我(没有颜色)
  • --return使脚本传播我的命令的退出代码,这样我就知道我的命令是否失败了。


当一些程序意识到输出不是tty时(即当您将其重定向到另一个程序时),它们会取消着色。您可以告诉其中一些人强制使用颜色,并告诉寻呼机启用着色,例如使用less -R


我发现使用script来保留管道到less时的颜色并不能真正起作用(越少,就越混乱,退出时,bash就越混乱),因为交互越少。script似乎真的把来自stdin的输入搞乱了,即使在退出之后。

因此,不要运行:

1
script -q /dev/null cargo build | less -R

我将/dev/null改向它,然后再改为:

1
script -q /dev/null cargo build < /dev/null | less -R

所以现在,script并没有和stdin搞混,而是得到了我想要的东西。它相当于command | less,但它保留了颜色,同时继续读取附加到文件中的新内容(我尝试的其他方法不会这样做)。


当我的另一个答案(涉及tee)不起作用时,这个关于超级用户的问题帮助了我。它包括使用unbuffer使命令认为它是从shell运行的。

我用sudo apt install expect tcl而不是sudo apt-get install expect-dev安装它。

讽刺的是,我需要在重定向apt的输出时使用这种方法。


我使用tee:将命令的输出通过管道传输到teefilename,它将保持颜色。如果您不想在屏幕上看到输出(这就是tee的作用:同时显示和重定向输出),那么只需将tee的输出发送到/dev/null即可:

command| teefilename> /dev/null