web-dev-qa-db-fra.com

tput setaf color table? Comment déterminer les codes couleurs?

Je suis en train de coloriser PS1.

Je mets des variables de couleur en utilisant tput; par exemple, voici le violet:

PURPLE=$(tput setaf 125)

Question:

Comment trouver les codes de couleur (par exemple 125) d'autres couleurs?

Y a-t-il un guide de tableau de couleurs/un aide-mémoire quelque part?

Je ne sais tout simplement pas ce que 125 est… Existe-t-il un moyen de prendre une couleur hexadécimale et de la convertir en un nombre que setaf peut utiliser?

90
mhulse

Le nombre de couleurs disponibles pour tput est donné par tput colors.

Pour voir les 8 couleurs de base (telles qu'utilisées par setf dans le terminal urxvt et setaf dans le terminal xterm):

$ printf '\e[%sm▒' {30..37} 0; echo           ### foreground
$ printf '\e[%sm ' {40..47} 0; echo           ### background

Et généralement nommé comme ceci:

Color       #define       Value       RGB
black     COLOR_BLACK       0     0, 0, 0
red       COLOR_RED         1     max,0,0
green     COLOR_GREEN       2     0,max,0
yellow    COLOR_YELLOW      3     max,max,0
blue      COLOR_BLUE        4     0,0,max
Magenta   COLOR_Magenta     5     max,0,max
cyan      COLOR_CYAN        6     0,max,max
white     COLOR_WHITE       7     max,max,max

Pour voir les 256 couleurs étendues (telles qu'utilisées par setaf dans urxvt):

$ printf '\e[48;5;%dm ' {0..255}; printf '\e[0m \n'

Si vous voulez des nombres et une sortie ordonnée:

#!/bin/bash
color(){
    for c; do
        printf '\e[48;5;%dm%03d' $c $c
    done
    printf '\e[0m \n'
}

IFS=$' \t\n'
color {0..15}
for ((i=0;i<6;i++)); do
    color $(seq $((i*36+16)) $((i*36+51)))
done
color {232..255}

256 color chart in sequence, labeled with their index


Les 16 millions de couleurs ont besoin d'un peu de code (certaines consoles ne peuvent pas le montrer).
Les bases sont:

fb=3;r=255;g=1;b=1;printf '\e[0;%s8;2;%s;%s;%sm▒▒▒ ' "$fb" "$r" "$g" "$b"

fb est front/back ou 3/4.

Un simple test de la capacité de votre console à présenter autant de couleurs est:

for r in {200..255..5}; do fb=4;g=1;b=1;printf '\e[0;%s8;2;%s;%s;%sm   ' "$fb" "$r" "$g" "$b"; done; echo

red line, fading from darker to lighter (left-to-right) Il présentera une ligne rouge avec un très petit changement de ton de gauche à droite. Si ce petit changement est visible, votre console est capable de 16 millions de couleurs.

Chaque r, g et b est une valeur de 0 à 255 pour RVB (rouge, vert, bleu).

Si votre type de console le prend en charge, ce code créera une table de couleurs:

mode2header(){
    #### For 16 Million colors use \e[0;38;2;R;G;Bm each RGB is {0..255}
    printf '\e[mR\n' # reset the colors.
    printf '\n\e[m%59s\n' "Some samples of colors for r;g;b. Each one may be 000..255"
    printf '\e[m%59s\n'   "for the ansi option: \e[0;38;2;r;g;bm or \e[0;48;2;r;g;bm :"
}
mode2colors(){
    # foreground or background (only 3 or 4 are accepted)
    local fb="$1"
    [[ $fb != 3 ]] && fb=4
    local samples=(0 63 127 191 255)
    for         r in "${samples[@]}"; do
        for     g in "${samples[@]}"; do
            for b in "${samples[@]}"; do
                printf '\e[0;%s8;2;%s;%s;%sm%03d;%03d;%03d ' "$fb" "$r" "$g" "$b" "$r" "$g" "$b"
            done; printf '\e[m\n'
        done; printf '\e[m'
    done; printf '\e[mReset\n'
}
mode2header
mode2colors 3
mode2colors 4

chart of sample foreground colors with their index as labels

chart of sample background colors with their index as labels

Pour convertir une valeur de couleur hexadécimale en un indice de couleur 0-255 (le plus proche):

fromhex(){
    hex=${1#"#"}
    r=$(printf '0x%0.2s' "$hex")
    g=$(printf '0x%0.2s' ${hex#??})
    b=$(printf '0x%0.2s' ${hex#????})
    printf '%03d' "$(( (r<75?0:(r-35)/40)*6*6 + 
                       (g<75?0:(g-35)/40)*6   +
                       (b<75?0:(b-35)/40)     + 16 ))"
}

Utilisez-le comme:

$ fromhex 00fc7b
048
$ fromhex #00fc7b
048

Pour trouver le numéro de couleur utilisé dans format de couleurs HTML :

#!/bin/dash
tohex(){
    dec=$(($1%256))   ### input must be a number in range 0-255.
    if [ "$dec" -lt "16" ]; then
        bas=$(( dec%16 ))
        mul=128
        [ "$bas" -eq "7" ] && mul=192
        [ "$bas" -eq "8" ] && bas=7
        [ "$bas" -gt "8" ] && mul=255
        a="$((  (bas&1)    *mul ))"
        b="$(( ((bas&2)>>1)*mul ))" 
        c="$(( ((bas&4)>>2)*mul ))"
        printf 'dec= %3s basic= #%02x%02x%02x\n' "$dec" "$a" "$b" "$c"
    Elif [ "$dec" -gt 15 ] && [ "$dec" -lt 232 ]; then
        b=$(( (dec-16)%6  )); b=$(( b==0?0: b*40 + 55 ))
        g=$(( (dec-16)/6%6)); g=$(( g==0?0: g*40 + 55 ))
        r=$(( (dec-16)/36 )); r=$(( r==0?0: r*40 + 55 ))
        printf 'dec= %3s color= #%02x%02x%02x\n' "$dec" "$r" "$g" "$b"
    else
        gray=$(( (dec-232)*10+8 ))
        printf 'dec= %3s  gray= #%02x%02x%02x\n' "$dec" "$gray" "$gray" "$gray"
    fi
}

for i in $(seq 0 255); do
    tohex ${i}
done

Utilisez-le comme ("de base" est les 16 premières couleurs, "couleur" est le groupe principal, "gris" est les dernières couleurs grises):

$ tohex 125                  ### A number in range 0-255
dec= 125 color= #af005f
$ tohex 6
dec=   6 basic= #008080
$ tohex 235
dec= 235  gray= #262626
169
user79743

La réponse courte est que vous pouvez trouver sur les tableaux Web des couleurs et les faire correspondre au numéro de couleur.

La réponse longue est que le mappage correct dépend du terminal -

Le 125 est un paramètre d'une séquence d'échappement appelée setaf dans la description du terminal. tput n'attache aucune signification particulière au nombre. Cela dépend en fait de l'émulateur de terminal particulier.

Il y a quelque temps, l'ANSI a défini des codes pour 8 couleurs, et il y avait deux schémas pour les numéroter. Les deux sont vus dans certaines descriptions de terminaux comme les paires setf/setb ou setaf/setab. Puisque ce dernier a la connotation de "couleurs ANSI", vous verrez que cela est utilisé plus souvent. Le premier (setf/setb) a changé l'ordre du rouge/bleu comme indiqué dans les ncurses FAQ Pourquoi le rouge/le bleu sont-ils interchangés?, mais dans les deux cas, le schéma a été établi pour simplement numéroter les couleurs. Il n'y a pas de relation prédéfinie entre ces nombres et le contenu RVB.

Pour des émulateurs de terminaux spécifiques, il existe des palettes de couleurs prédéfinies qui peuvent être énumérées assez facilement - et peuvent être programmées à l'aide de ces séquences d'échappement. Il n'y a pas de normes pertinentes, et vous verrez des différences entre les émulateurs de terminaux, comme indiqué dans le xterm FAQ je n'aime pas cette nuance de ble.

Cependant, la convention est souvent confondue avec les normes. Dans le développement de xterm au cours des 20 dernières années, il a incorporé des couleurs ANSI (8), adapté les couleurs de la fonction aixterm (16), ajouté des extensions pour 88 et 256 couleurs. Une grande partie de cela a été adoptée par d'autres développeurs pour différents émulateurs de terminaux. Cela est résumé dans le xterm FAQ Pourquoi ne pas faire "xterm" égal à "xterm-256color"?.

Le code source xterm comprend des scripts pour démontrer les couleurs, par exemple, en utilisant les mêmes séquences d'échappement que tput utiliserait.

Cette question/réponse peut également vous être utile: valeurs RVB des couleurs dans l'index de couleurs étendu Ansi (17-255)

15
Thomas Dickey

L'utilitaire tput utilise une table de recherche de 256 couleurs pour imprimer séquences d'échappement ANSI 8 bits (commençant par Esc et [) qui utilise capacités du terminal , donc ces séquences de contrôle peuvent être interprétées comme des couleurs. Il s'agit d'un ensemble prédéfini de 256 couleurs couramment utilisé sur les cartes graphiques.

Pour imprimer les 256 couleurs du terminal, essayez la doublure suivante:

for c in {0..255}; do tput setaf $c; tput setaf $c | cat -v; echo =$c; done

Astuce: ajouter | column pour classer la liste.

Ce tableau de recherche de 256 couleurs peut également être trouvé sur le page Wikipedia comme suit:

Chart; ANSI escape code; 8-bit 256-color lookup table at Wikipedia; 256-color mode — foreground: ESC[38;5;#m background: ESC[48;5;#m

11
kenorb

Avec zsh et dans un terminal semblable à xterm (terminaux basés sur xterm et vte comme gnome-terminal, xfce4-terminal... au moins), vous pouvez faire:

$ read -s -t1 -d $'\a' $'c?\e]4;125;?\a' && echo "${c##*;}"
rgb:afaf/0000/5f5f

L'équivalent bash:

read -s -t1 -d $'\a' -p $'\e]4;125;?\a' c && echo "${c##*;}"

(vous voulez que la séquence d'échappement interroge la couleur à envoyer après la discipline terminale echo est désactivée (avec -s) sinon la réponse serait affichée par la discipline de ligne la moitié du temps, d'où son envoi dans le cadre de l'invite read (var?prompt en zsh comme en ksh, -p Prompt en bash)).

pour obtenir la définition de la couleur 125 (ici en tant que spécification RVB, chaque nombre étant l'intensité des composants Rouge, Vert et Bleu sous la forme d'un nombre hexadécimal compris entre 0 et FFFF).

Vous pouvez faire de même pour les 16 premières couleurs avec la commande xtermcontrol:

$ xtermcontrol --get-color1
rgb:cdcd/0000/0000
3
Stéphane Chazelas

Couleurs ANSI sur le terme console

Préambule: environ $TERM variable

Vérifiez votre environnement avec: tput colors

Si vous utilisez une console compatible xterm, votre $TERM peut contenir quelque chose comme xterm*:

echo $TERM
xterm

tput colors
8

D'autres démos ne fonctionneront pas: vous obtiendrez une image ressemblant à:

enter image description here

sauf si vous définissez ce paramètre sur xterm-256color:

export TERM=xterm-256color ; reset

tput colors
256

(Vous pouvez même essayer de l'exécuter après avoir défini export TERM=xterm-mono;)

Faire simplement le travail en utilisant tput

Selon le protocole de terme utilisé par votre console, la séquence peut être: \e[38;5;XXXm ou \e[3XXXmXXX correspond au numéro ansi.

Pour vous assurer que vous utilisez la bonne séquence ANSI, vous devez utiliser tput.

Concernant code d'échappement ANSI de Wikipedia , j'ai écrit ceci:

#!/bin/bash

for ((i=0; i<256; i++)) ;do
    echo -n '  '
    tput setab $i
    tput setaf $(( ( (i>231&&i<244 ) || ( (i<17)&& (i%8<2)) ||
        (i>16&&i<232)&& ((i-16)%6 <(i<100?3:2) ) && ((i-16)%36<15) )?7:16))
    printf " C %03d " $i
    tput op
    (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
        printf "\n" ''
done

Pourrait rendre quelque chose comme:

enter image description here

Optimisation bash : réduction des fourches en exécutant la tâche backgroung

... Ensuite, parce que je déteste courir plus de 200 fourchettes dans un petit script, j'ai écrit ceci:

#!/bin/bash

# Connector fifos directory
read TMPDIR < <(mktemp -d /dev/shm/bc_Shell_XXXXXXX)

fd=3
# find next free fd
nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;}

tputConnector() {
    mkfifo $TMPDIR/tput
    nextFd TPUTIN
    eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)"
    nextFd TPUTOUT
    eval "exec $TPUTOUT<$TMPDIR/tput"
}
myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2
}
tputConnector

myTput op op
myTput "setaf 7" grey
myTput "setaf 16" black
fore=("$black" "$grey")
for ((i=0; i<256; i++)) ;do
    myTput "setab $i" bgr
    printf "  %s%s  %3d  %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)||
        (i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58
        ? 1 : 0 ]}" $i "$op"
    (( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
        printf "\n" ''
done

Avec seulement 1 fourchette! Même résultat, mais environ 10 fois plus rapide!

Si le premier script s'exécute en ~ 1,12 seconde sur mon bureau, cela prend jusqu'à ~ 47,4 secondes sur mon raspberry-pi !!

Alors que le deuxième script s'exécute en ~ 0.11 seconde sur mon bureau et ~ 4.97 secondes sur ma framboise.

3
F. Hauri