Come verificare se bash può stampare i colori


62

Voglio sapere se esiste un modo per verificare se il mio programma è in grado di produrre output del terminale usando i colori o meno.

Eseguendo comandi simili lesse guardando l'output di un programma che emette utilizzando i colori, l'output viene visualizzato in modo errato, come

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

Grazie



Risposte:


68

L'idea è che la mia applicazione sappia di non colorare l'output se il programma non è in grado di stampare, ad esempio, registrando l'output da un processo cron su un file, non è necessario registrare l'output colorato, ma quando si esegue manualmente, mi piace visualizzare l'uscita colorata

In che lingua stai scrivendo la tua domanda?

L'approccio normale è verificare se il dispositivo di output è un tty e, in tal caso, verificare se quel tipo di terminale supporta i colori.

In bash, sarebbe simile

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

In C, devi fare molto più digitando, ma puoi ottenere lo stesso risultato usando isatty e le funzioni elencate in man 3 terminfo.


^^ che ^^ era esattamente quello che stavo cercando. Grazie.
Tim Kennedy,

Grazie per il suggerimento su tput. Questa è davvero un'ottima risposta
AmadeusDrZaius

24

Questo dovrebbe essere sufficiente:

$ tput colors

spiegazione dei colori di tput:

Se guardi la manpage, noterai questo:

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

E...

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

Il termcap si colorstrova nel database terminfo, quindi puoi richiederlo. Se hai uno stato di uscita pari a zero, viene compilato il termcap. Ma se hai qualcosa del tipo:

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

Questo dimostra che unknowntermcap non esiste. Così questo:

$ tput colors
8
$ echo $?
0

Mostra che il tuo comando era giusto.

Altri modi utili:

  • In C, puoi semplicemente usare isatty e vedere se è un TTY
  • Vedi se si tratta di un terminale stupido che sembra variabile $ TERM

Saluti


colorsnon è documentato nella tputpagina man (!), quindi dovrei cercare un numero> = 8 in stdout o un codice di ritorno di 0?
l0b0

Sembra ovvio, ma il tuo commento mostra che non lo è. Sto aggiungendo queste informazioni (brevemente, i colori sono una capacità del database terminfo)
D4RIO

1
La colorscapacità è documentata in terminfo (5) . Test utilizzando tput -T dumb colors, tput -T vt220 colors, tput -T linux colors, tput -T xterm colorssuggerisce i valori comuni sono -1(senza supporto del colore) e 8(8 colori). Si noti che ciò si applica solo dopo aver verificato che il dispositivo di uscita sia un terminale (ad es. [ -t 1 ]O isatty).
Mikel,

Si noti che tput colorsrestituisce ciò che il database del terminale locale pensa del terminale. Ciò può corrispondere o meno a ciò che il terminale può effettivamente fare, specialmente per un tipo di terminale come quello xtermdisponibile in molte varianti (che vanno dal bianco e nero ai 256 colori).
Gilles 'SO- smetti di essere malvagio'

7

L'idea è che la mia applicazione sappia di non colorare l'output se il programma non è in grado di stampare, ad esempio, registrando l'output da un processo cron su un file, non è necessario registrare l'output colorato, ma quando si esegue manualmente, mi piace visualizzare l'uscita colorata.

Per questo caso d'uso, ciò che i programmi in genere (ad es. GNU ls o GNU grep con --color=auto) è usare i colori se il loro output sta andando su un terminale e nessun colore altrimenti. I terminali che non supportano le sequenze ANSI che cambiano colore sono abbastanza rari da consentire ai loro utenti di ignorare la scelta predefinita. In ogni caso, assicurati che l'applicazione abbia un'opzione per attivare o disattivare i colori.

In uno script di shell, utilizzare [ -t 1 ]per verificare se l'output standard è un terminale.

# 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

Da un programma che utilizza l'API C, chiama 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

Eseguendo comandi come meno e guardando l'output di un programma che emette usando i colori, l'output viene visualizzato in modo errato, come

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

Prova a usare less --RAW-CONTROL-CHARS.

In questo esempio sto usando logtool , che stampa l'output usando i colori.

Senza --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 (Immagina che questo sia in bei colori. Inoltre, non sono sicuro del perché ^Gvenga visualizzato.):

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

2

Sarebbe colpa di lessnon essere impostato per interpretare le fughe ANSI; cercare Rin $LESSOPTS. Per determinare se il sistema sa che il tuo terminale è in grado di gestire i colori, tput colorsprodurrà il numero di colori che supporta o -1se non supporta i colori. (Si noti che alcuni terminali possono utilizzare xterminvece che xterm-colorcome descrizione del terminale, ma supportano comunque i colori.)


L'idea è che la mia applicazione sappia di non colorare l'output se il programma non è in grado di stampare, ad esempio, registrando l'output da un processo cron su un file, non è necessario registrare l'output colorato, ma quando si esegue manualmente, mi piace visualizzare l'uscita colorata.
Angelo Vargas,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.