tabella dei colori di tput setaf? Come determinare i codici colore?


79

Sto colorando il mio terminale PS1.

Sto impostando le variabili di colore usando tput; per esempio, ecco il viola:

PURPLE=$(tput setaf 125)

Domanda:

Come trovo i codici colore (ad es. 125) Di altri colori?

C'è una guida alla tabella dei colori / cheat sheet da qualche parte?

Non sono sicuro di cosa 125sia ... C'è un modo per prendere un colore esadecimale e convertirlo in un numero che setafpuò usare?


Risposte:


153

Il conteggio dei colori disponibili per tput è dato da tput colors.

Per visualizzare gli 8 colori di base (utilizzati da setfnel terminale urxvt e setafnel terminale xterm):

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

E di solito chiamato come questo:

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

Per vedere i 256 colori estesi (come usato da setafin urxvt):

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

Se vuoi numeri e un output ordinato:

#!/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 colori in sequenza, etichettati con il loro indice


I 16 milioni di colori richiedono un po 'di codice (alcune console non possono mostrarlo).
Le basi sono:

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

fbè front/backo 3/4.

Un semplice test della capacità della tua console di presentare così tanti colori è:

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

linea rossa, sfumando dal più scuro al più chiaro (da sinistra a destra) Presenterà una linea rossa con una piccolissima variazione di tono da sinistra a destra. Se è visibile quel piccolo cambiamento, la tua console è in grado di 16 milioni di colori.

Ciascuno r, ged bè un valore compreso tra 0 e 255 per RGB (rosso, verde, blu).

Se il tuo tipo di console lo supporta, questo codice creerà una tabella di colori:

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

grafico dei colori di primo piano di esempio con il loro indice come etichette

grafico dei colori di sfondo del campione con il loro indice come etichette

Per convertire un valore di colore esadecimale in un indice di colore 0-255 (più vicino):

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 ))"
}

Usalo come:

$ fromhex 00fc7b
048
$ fromhex #00fc7b
048

Per trovare il numero di colore utilizzato nel formato di colori 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

Usalo come ("base" sono i primi 16 colori, "colore" è il gruppo principale, "grigio" è gli ultimi colori grigi):

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

La tua funzione fromhex è fantastica! Grazie mille!
mhulse,

Lovin ' fromhex. Grazie ancora! Inoltre, ho aggiunto un controllo per# . Risposta?
mhulse,

1
Sì, rimuovere un '#' iniziale è una protezione ragionevole. Trovo molto più semplice da usare hex=${1#"#"}. Non rimuoverà nulla se $1non ha un #e lo rimuoverà se esiste. Vedi il mio codice aggiornato.

Bello! Molto più compatto. Aggiornamento del mio codice ora. Grazie!!!!
mhulse,

Si noti che almeno nella mia versione di xterm il \e[0;%s8;2;%s;%s;%smnon mi dà 16M colori, solo il colore nella tavolozza 240 colori che è più vicino all'rgb richiesto.
Stéphane Chazelas,

14

La risposta breve è che puoi trovare sulle tabelle di colori dei web e abbinarle al numero di colore.

La risposta lunga è che la mappatura corretta dipende dal terminale -

La 125è un parametro per una sequenza di escape denominato setafnella descrizione del terminale. tputnon attribuisce un significato particolare al numero. Questo in realtà dipende dal particolare emulatore di terminale.

Qualche tempo fa, ANSI ha definito i codici per 8 colori e c'erano due schemi per numerarli. I due sono visti in alcune descrizioni dei terminali come coppie setf/setbo setaf/setab. Poiché quest'ultimo ha la connotazione di "colori ANSI", vedrai che viene usato più spesso. Il primo (setf / setb) ha cambiato l'ordine per rosso / blu come indicato nelle FAQ di ncurses Perché il rosso / blu sono scambiati? , ma in entrambi i casi, lo schema è stato stabilito solo per numerare i colori. Non esiste una relazione predefinita tra quei numeri e il contenuto RGB.

Per emulatori di terminali specifici, esistono tavolozze di colori predefinite che possono essere enumerate abbastanza facilmente e possono essere programmate usando queste sequenze di escape. Non ci sono nessun norme pertinenti, e vedrete le differenze tra emulatori di terminale, come indicato nella FAQ xterm non mi piace che la tonalità di blu .

Tuttavia, la convenzione è spesso confusa con gli standard. Nello sviluppo di xterm negli ultimi 20 anni, ha incorporato i colori ANSI (8), adattato le aixtermcaratteristiche (16) colori, aggiunto estensioni per 88 e 256 colori. Gran parte di questo è stato adottato da altri sviluppatori per diversi emulatori di terminali. Questo è riassunto nelle FAQ di xterm Perché non rendere "xterm" equiparato a "xterm-256color"? .

Il codice sorgente di xterm include script per dimostrare i colori, ad esempio, usando le stesse sequenze di escape che tputverrebbero utilizzate.

Potresti trovare utile anche questa domanda / risposta: valori RGB dei colori nell'indice dei colori estesi Ansi (17-255)


Grazie mille per il tuo aiuto Thomas, lo apprezzo davvero! Sono su un Mac / OS X con iTerm. La tua spiegazione mi aiuta davvero a capire di più sulla mia configurazione (ho fatto un sacco di copia / incolla dai vari colori di prompt di altre persone sul web). Apprezzo molto che tu abbia dedicato del tempo a scrivermi una risposta dettagliata e informativa. :)
mhulse,

9

L' tpututilità utilizza una tabella di ricerca a 256 colori per stampare sequenze di escape ANSI a 8 bit (a partire da Esce [) che fa uso di funzionalità terminali , quindi queste sequenze di controllo possono essere interpretate come colori. Si tratta di un set predefinito di 256 colori utilizzato comunemente tra le schede grafiche.

Per stampare tutti i 256 colori nel terminale, provare la seguente riga singola:

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

Suggerimento: | columnaggiungi all'elenco di colonne.

Questa tabella di ricerca a 256 colori è disponibile anche nella pagina Wikipedia come segue:

Grafico;  Codice di escape ANSI;  Tabella di ricerca a 256 colori a 8 bit su Wikipedia;  Modalità 256 colori - primo piano: ESC [38; 5; #m sfondo: ESC [48; 5; #m


3

Con zsh e in un xtermterminale simile ( xterme vteterminali basati come gnome-terminal, xfce4-terminalalmeno ...), puoi fare:

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

L'equivalente bash:

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

(si desidera che la sequenza di escape richieda il colore da inviare dopo che la disciplina terminale echoè disabilitata (con -s) altrimenti la risposta verrà visualizzata dalla disciplina di linea per metà del tempo, quindi l'invio di esso come parte del readprompt ( var?promptin zsh come in ksh, -p promptin bash)).

per ottenere la definizione di colore 125 (qui come specifica RGB, ogni numero è l'intensità dei componenti Rosso, Verde e Blu come un numero esadecimale compreso tra 0 e FFFF).

Puoi fare lo stesso per i primi 16 colori con il xtermcontrolcomando:

$ xtermcontrol --get-color1
rgb:cdcd/0000/0000

Fantastico, grazie mille per l'aiuto! +1
mhulse,

@Gilles, si desidera che la query venga inviata tramite il prompt dopo che l'eco della disciplina terminale è disabilitata. Vedi modifica.
Stéphane Chazelas,

@ StéphaneChazelas Usando un altro programma terminale (gnome-terminal) (che è un terminale xterm) ho fatto in modo che il tuo codice funzionasse correttamente (sia in bash che in zsh) Stranamente: tput colorsriporta solo 8se il terminale è in grado di presentare 256 colori. Inoltre, il xterm-color (Konsole) tput colorsriporta solo 8se quel terminale è in grado di presentare 16 milioni di colori (e naturalmente tutti i 256 colori). E no, nessun tmux o schermo che potrebbe "colorare" :-) (cambia cioè) i risultati (ero a conoscenza di quel dettaglio). In breve: il codice potrebbe non riuscire in alcuni terminali / console.

Ah, il tohex ha aggiunto alla mia risposta, un po 'più lungo di quello che mi aspettavo, ma i 256 colori hanno un bel po' di stranezze.

0

Colori ANSI a termine console

A seconda del protocollo a termine utilizzato dalla console, la sequenza potrebbe essere: \e[38;5;XXXmo \e[3XXXmdove XXXcorrisponde al numero ansi.

Per assicurarti di usare la giusta sequenza ANSI, devi usare tput.

Per quanto riguarda il codice di escape ANSI di Wikipedia , ho scritto questo:

#!/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

Potrebbe rendere qualcosa del tipo:

inserisci qui la descrizione dell'immagine

... Quindi, poiché odio correre più di 200 forchette in una piccola sceneggiatura, ho scritto questo:

#!/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

Con solo 1 forchetta! Stesso risultato, ma molto più veloce!

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.