如何检查bash是否可以打印颜色


62

我想知道是否有任何方法可以检查我的程序是否可以使用颜色输出终端输出。

运行类似命令less并查看使用颜色输出的程序的输出,输出显示错误,例如

[ESC[0;32m0.052ESC[0m ESC[1;32m2,816.00 kbESC[0m]

谢谢



Answers:


68

我的应用程序的想法是,如果程序无法打印,例如,将通过cron作业将输出记录到文件中,而无需记录彩色输出,则我的应用程序不对输出进行着色,但是当手动运行时,我喜欢查看输出彩色

您用什么语言编写应用程序?

正常方法是检查输出设备是否为tty,如果是,则检查该类型的终端是否支持颜色。

在中bash,看起来像

# check if stdout is a terminal...
if test -t 1; then

    # see if it supports colors...
    ncolors=$(tput colors)

    if test -n "$ncolors" && test $ncolors -ge 8; then
        bold="$(tput bold)"
        underline="$(tput smul)"
        standout="$(tput smso)"
        normal="$(tput sgr0)"
        black="$(tput setaf 0)"
        red="$(tput setaf 1)"
        green="$(tput setaf 2)"
        yellow="$(tput setaf 3)"
        blue="$(tput setaf 4)"
        magenta="$(tput setaf 5)"
        cyan="$(tput setaf 6)"
        white="$(tput setaf 7)"
    fi
fi

echo "${red}error${normal}"
echo "${green}success${normal}"

echo "${green}0.052${normal} ${bold}${green}2,816.00 kb${normal}"
# etc.

在C语言中,您必须进行更多输入,但是使用isatty和中列出的功能可以达到相同的结果man 3 terminfo


^^ that ^^ 正是我想要的。谢谢。
蒂姆·肯尼迪

感谢您提供有关tput的提示。这是一个非常好的答案。
AmadeusDrZaius

24

这应该足够了:

$ tput colors

颜色颜色说明:

如果查看联机帮助页,您会注意到以下几点:

SYNOPSIS
       tput [-Ttype] capname [parms ... ]

和...

   capname
          indicates the capability from the terminfo database.  When term
          cap  support is compiled in, the termcap name for the capability
          is also accepted.

termcap colors在terminfo数据库中,因此您可以要求它。如果退出状态为零,则将编译termcap。但是如果您有类似以下内容:

$ tput unknowntermcap
tput: unknown terminfo capability 'unknowntermcap'
$ echo $?
4

这表明unknowntermcap不存在。所以这:

$ tput colors
8
$ echo $?
0

显示您的命令正确。

其他有用的方法:

  • 在C语言中,您可以只使用isatty并查看它是否为TTY
  • 看看它是否是一个哑终端,看起来像$ TERM变量

干杯


colors没有在tput手册页中记录(!),因此我应该在stdout中查找数字> = 8还是返回码0?
l0b0 2011年

似乎很明显,但您的评论表明事实并非如此。我要添加该信息(简短地说,颜色是terminfo数据库的功能)
D4RIO 2011年

1
colors功能记录在terminfo(5)中。使用测试tput -T dumb colorstput -T vt220 colorstput -T linux colorstput -T xterm colors建议常用的值是-1(无颜色支持)和8(8色)。请注意,这仅在检查输出设备为端子(例如[ -t 1 ]isatty)后才适用。
Mikel

注意,tput colors返回本地终端数据库对终端的看法。这可能与终端的实际功能相对应,也可能与之不对应,特别是对于像xterm这样的终端类型而言,有很多变体(从黑白到256色不等)。
吉尔斯(Gilles)

7

我的应用程序的想法是,如果程序无法打印,例如,将通过cron作业将输出记录到文件中,而无需记录彩色输出,则我的应用程序不对输出进行着色,但是当手动运行时,我喜欢查看输出为彩色。

对于这种用例,程序通常要做的事情(例如,带有的GNU ls或GNU grep --color=auto)是如果输出将输出到终端,则使用颜色,否则不使用颜色。不支持ANSI换色序列的终端非常罕见,以至于可以让其用户覆盖默认选项。无论如何,请确保您的应用程序具有强制打开或关闭颜色的选项。

在Shell脚本中,用于[ -t 1 ]测试标准输出是否为终端。

# option processing has set $color to yes, no or auto
if [ $color = auto ]; then
  if [ -t 1 ]; then color=yes; else color=no; fi
fi

在使用C API的程序中,调用isatty(1)

# option processing has set use_color to 0 for no, 1 for yes or 2 for auto
if (use_color == 2) use_color = isatty(1);

5

运行较少的命令,并查看使用颜色输出的程序的输出,输出显示错误,例如

[ESC [0; 32m0.052ESC [0m ESC [1; 32m2,816.00 kbESC [0m]

尝试使用less --RAW-CONTROL-CHARS

在此示例中,我使用logtool,该工具使用颜色打印输出。

没有--RAW-CONTROL-CHARS:

$ head -20 /var/log/messages | logtool | less
ESC[0mESC[0;37mMar 20 11:43:52ESC[0mESC[1;36m host1ESC[0mESC[0;37m rsyslogd:ESC[0m ^GESC[0;31mlast message repeated 14 timesESC[0mESC[0m

使用--RAW-CONTROL-CHAR(可想象这是漂亮的颜色。此外,我不确定为什么^G会显示它。):

$ head -20 /var/log/messages | logtool | less --RAW-CONTROL-CHARS
Mar 20 11:43:52 host1 rsyslogd: ^Glast message repeated 14 times

2

那可能是less没有设置为解释ANSI转义的错误。寻找R$LESSOPTS。至于确定系统是否知道您的终端可以处理颜色,tput colors将输出其支持的颜色数量或-1不支持的颜色。(请注意,某些终端可能使用xterm而不是xterm-color作为其终端描述,但仍支持颜色。)


我的应用程序的想法是,如果程序无法打印,例如,将通过cron作业将输出记录到文件中,而无需记录彩色输出,则我的应用程序不对输出进行着色,但是当手动运行时,我喜欢查看输出为彩色。
Angelo Vargas

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.