Cómo verificar si bash puede imprimir colores

62

Quiero saber si hay alguna forma de verificar si mi programa puede generar salida de terminal usando colores o no.

Ejecutando comandos como lessy mirando la salida de un programa que sale usando colores, la salida se muestra mal, como

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

Gracias

Angelo Vargas
fuente

Respuestas:

68

La idea es que mi aplicación sepa que no debe colorear la salida si el programa no puede imprimir, digamos, registrando la salida de un trabajo cron a un archivo, no es necesario registrar la salida en color, pero cuando se ejecuta manualmente, me gusta ver la salida coloreada

¿En qué idioma escribe su solicitud?

El enfoque normal es verificar si el dispositivo de salida es un tty, y si es así, verificar si ese tipo de terminal admite colores.

En bash, eso se vería como

# 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.

En C, debe escribir mucho más, pero puede lograr el mismo resultado utilizando isatty y las funciones enumeradas en man 3 terminfo.

Mikel
fuente
^^ que ^^ era exactamente lo que estaba buscando. Gracias.
Tim Kennedy el
Gracias por la pista sobre tput. Esta es una gran respuesta.
AmadeusDrZaius
24

Esto debería ser suficiente:

$ tput colors

colores de tput explicados:

Si miras la página de manual, notarás esto:

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

Y...

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

El termcap colorsestá en la base de datos terminfo, por lo que puede solicitarlo. Si tiene un estado de salida cero, entonces se compila el termcap. Pero si tiene algo como:

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

Esto muestra que unknowntermcap no existe. Así que esto:

$ tput colors
8
$ echo $?
0

Muestra que tu comando era correcto.

Otras formas útiles:

  • En C, puede usar isatty y ver si es un TTY
  • Vea si es una terminal tonta que busca la variable $ TERM

Salud

D4RIO
fuente
colorsno está documentado en la tputpágina del manual (!), entonces ¿debería buscar un número> = 8 en stdout o un código de retorno de 0?
l0b0
Parecía obvio, pero tu comentario muestra que no lo es. Estoy agregando esa información (brevemente, los colores son una capacidad de la base de datos terminfo)
D4RIO
1
La colorscapacidad está documentada en terminfo (5) . Las pruebas utilizando tput -T dumb colors, tput -T vt220 colors, tput -T linux colors, tput -T xterm colorssugiere valores comunes son -1(sin soporte de color) y 8(8 colores). Tenga en cuenta que esto solo se aplica después de comprobar que el dispositivo de salida es un terminal (p . Ej. [ -t 1 ]O isatty).
Mikel
Tenga en cuenta que tput colorsdevuelve lo que la base de datos del terminal local piensa del terminal. Esto puede corresponder o no a lo que el terminal realmente puede hacer, especialmente para un tipo de terminal como el xtermque viene en muchas variantes (que van desde el blanco y negro hasta los 256 colores).
Gilles 'SO- deja de ser malvado'
7

La idea es que mi aplicación sepa que no debe colorear la salida si el programa no puede imprimir, digamos, registrando la salida de un trabajo cron a un archivo, no es necesario registrar la salida en color, pero cuando se ejecuta manualmente, me gusta ver La salida de color.

Para este caso de uso, lo que suelen hacer los programas (por ejemplo, GNU ls o GNU grep con --color=auto) es usar colores si su salida va a un terminal, y no hay colores de otro modo. Los terminales que no admiten secuencias de cambio de color ANSI son lo suficientemente raros como para que sea aceptable hacer que sus usuarios anulen la opción predeterminada. En cualquier caso, asegúrese de que su aplicación tenga la opción de activar o desactivar los colores.

En un script de shell, use [ -t 1 ]para probar si la salida estándar es un terminal.

# 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

Desde un programa que usa la API C, llame 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);
Gilles 'SO- deja de ser malvado'
fuente
5

Ejecutando comandos como less y mirando la salida de un programa que sale usando colores, la salida se muestra mal, como

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

Intenta usarlo less --RAW-CONTROL-CHARS.

En este ejemplo estoy usando logtool , que imprime la salida usando colores.

Sin --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

Con --RAW-CONTROL-CHAR (Imagine que esto está en bonitos colores. Además, no estoy seguro de por qué ^Gse está mostrando eso ):

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

Eso sería culpa de lessno estar configurado para interpretar escapes de ANSI; buscar Ren $LESSOPTS. En cuanto a determinar si el sistema sabe que su terminal puede manejar colores, tput colorsgenerará la cantidad de colores que admite o -1si no admite colores. (Tenga en cuenta que algunos terminales pueden usar en xtermlugar de xterm-colorcomo su descripción de terminal, pero aún admiten colores).

geekosaur
fuente
La idea es que mi aplicación sepa que no debe colorear la salida si el programa no puede imprimir, digamos, registrando la salida de un trabajo cron a un archivo, no es necesario registrar la salida en color, pero cuando se ejecuta manualmente, me gusta ver La salida de color.
Angelo Vargas