Comment vérifier si bash peut imprimer des couleurs

62

Je veux savoir s'il existe un moyen de vérifier si mon programme peut générer une sortie de terminal en utilisant des couleurs ou non.

Exécuter des commandes telles lessque regarder et regarder la sortie d’un programme qui sort en couleurs, la sortie est mal affichée, comme

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

Merci

Angelo Vargas
la source

Réponses:

68

L'idée est que mon application sache ne pas colorer la sortie si le programme ne peut pas imprimer, par exemple, en enregistrant la sortie d'un fichier cron via un travail cron, pas besoin d'enregistrer une sortie colorée, mais lors de l'exécution manuelle, j'aime voir la sortie colorée

Dans quelle langue écrivez-vous votre candidature?

L'approche normale consiste à vérifier si le périphérique de sortie est un terminal, et si c'est le cas, vérifiez si ce type de terminal prend en charge les couleurs.

Dans bash, cela ressemblerait à

# 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, vous devez taper beaucoup plus, mais vous pouvez obtenir le même résultat avec isatty et les fonctions listées dans man 3 terminfo.

Mikel
la source
^^ ça ^^ était exactement ce que je cherchais. Merci.
Tim Kennedy
Merci pour l'allusion sur tput. C'est une très bonne réponse.
AmadeusDrZaius
24

Cela devrait suffire:

$ tput colors

tput couleurs a expliqué:

Si vous regardez la page de manuel, vous remarquerez ceci:

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

Et...

   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 se colorstrouve dans la base de données terminfo, vous pouvez donc le demander. Si vous avez un statut de sortie nul, alors termcap est compilé. Mais si vous avez quelque chose comme:

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

Cela montre que unknowntermcap n'existe pas. Donc ça:

$ tput colors
8
$ echo $?
0

Montre que votre commande avait raison.

Autres moyens utiles:

  • En C, vous pouvez simplement utiliser isatty et voir si c'est un ATS
  • Voir si c'est une borne stupide à la recherche d'une variable $ TERM

À votre santé

D4RIO
la source
colorsn’est pas documenté dans la tputpage de manuel (!), devrais-je donc rechercher un nombre> = 8 dans stdout ou un code retour égal à 0?
l0b0
Cela semblait évident, mais votre commentaire montre que ce n'est pas le cas.
J'ajoute
1
La colorscapacité est documentée dans terminfo (5) . Test en utilisant tput -T dumb colors, tput -T vt220 colors, tput -T linux colors, tput -T xterm colorssuggère des valeurs communes sont -1(pas de support de couleur) et 8(8 couleurs). Notez que cela ne s'applique qu'après avoir vérifié que le périphérique de sortie est un terminal (par exemple [ -t 1 ]ou isatty).
Mikel
Notez que tput colorsrenvoie ce que la base de données du terminal local pense du terminal. Cela peut correspondre ou non à ce que le terminal peut réellement faire, en particulier pour un type de terminal similaire à xtermcelui proposé dans de nombreuses variantes (allant du noir et blanc à 256 couleurs).
Gilles, arrête d'être méchant '
7

L'idée est que mon application sache ne pas colorer la sortie si le programme ne peut pas imprimer, par exemple, en enregistrant la sortie d'un fichier cron via un travail cron, pas besoin d'enregistrer une sortie colorée, mais lors de l'exécution manuelle, j'aime voir la sortie colorée.

Dans ce cas d'utilisation, ce que font généralement les programmes (par exemple, GNU ls ou GNU grep avec --color=auto), consiste à utiliser des couleurs si leur sortie est dirigée vers un terminal, et aucune couleur sinon. Les terminaux qui ne prennent pas en charge les séquences de changement de couleur ANSI sont suffisamment rares pour que leurs utilisateurs puissent remplacer le choix par défaut. Dans tous les cas, assurez-vous que votre application dispose d'une option pour forcer l'activation ou la désactivation des couleurs.

Dans un script shell, utilisez [ -t 1 ]pour tester si la sortie standard est 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

Depuis un programme utilisant l’API C, appelez 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, arrête de faire le mal
la source
5

En exécutant des commandes comme less et en regardant la sortie d'un programme qui utilise des couleurs, la sortie est mal affichée, comme

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

Essayez d'utiliser less --RAW-CONTROL-CHARS.

Dans cet exemple, j'utilise logtool , qui imprime la sortie en couleurs.

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

Avec --RAW-CONTROL-CHAR (imaginez que ce soit dans de jolies couleurs. De plus, je ne suis pas sûr de savoir pourquoi cela ^Gest affiché.):

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

Ce serait la faute de lessne pas être configuré pour interpréter les fuites ANSI; chercher Rdans $LESSOPTS. Pour déterminer si le système sait que votre terminal peut gérer les couleurs, tput colorsil affichera le nombre de couleurs qu’il prend en charge ou -1non. (Notez que certains terminaux peuvent utiliser xtermau lieu de xterm-colorcomme description de terminal, mais prennent toujours en charge les couleurs.)

geekosaur
la source
L'idée est que mon application sache ne pas colorer la sortie si le programme ne peut pas imprimer, par exemple, en enregistrant la sortie d'un fichier cron via un travail, pas besoin d'enregistrer une sortie colorée, mais lors de l'exécution manuelle, j'aime voir la sortie colorée.
Angelo Vargas