tput setaf Farbtabelle? Wie bestimme ich Farbcodes?

79

Ich bin dabei, meine Terminals einzufärben PS1.

Ich setze Farbvariablen mit tput; Zum Beispiel ist hier lila:

PURPLE=$(tput setaf 125)

Frage:

Wie finde ich die Farbcodes (zB 125) anderer Farben?

Gibt es irgendwo einen Farbtabellenführer / Spickzettel?

Ich bin mir nur nicht sicher, was 125ist ... Gibt es eine Möglichkeit, eine Hex-Farbe zu nehmen und in eine Zahl umzuwandeln, setafdie verwendet werden kann?

mhulse
quelle

Antworten:

153

Die Anzahl der Farben, die für die Eingabe verfügbar sind, wird durch angegeben tput colors.

So zeigen Sie die grundlegenden 8 Farben an (wie sie setfim urxvt-Terminal und setafim xterm-Terminal verwendet werden):

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

Und normalerweise so benannt:

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

So zeigen Sie die erweiterten 256 Farben an (wie setafin urxvt verwendet):

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

Wenn Sie Zahlen und eine geordnete Ausgabe wünschen:

#!/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 Farbkarten hintereinander, beschriftet mit ihrem Index


Die 16 Millionen Farben benötigen eine Menge Code (einige Konsolen können dies nicht anzeigen).
Die Grundlagen sind:

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

fbist front/backoder 3/4.

Ein einfacher Test Ihrer Konsolenkapazität, um so viele Farben darzustellen, ist:

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

rote Linie, die von dunkler nach heller übergeht (von links nach rechts) Es wird eine rote Linie mit einer sehr kleinen Änderung des Tons von links nach rechts angezeigt. Wenn diese kleine Änderung sichtbar ist, unterstützt Ihre Konsole 16 Millionen Farben.

Jeder r, gund bist ein Wert von 0 bis 255 für RGB (Rot, Grün, Blau).

Wenn Ihr Konsolentyp dies unterstützt, erstellt dieser Code eine Farbtabelle:

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

Diagramm mit Beispielvordergrundfarben mit ihrem Index als Beschriftung

Diagramm mit Beispielhintergrundfarben mit ihrem Index als Beschriftungen

So konvertieren Sie einen hexadezimalen Farbwert in einen (nächsten) 0-255-Farbindex:

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

Verwenden Sie es als:

$ fromhex 00fc7b
048
$ fromhex #00fc7b
048

So ermitteln Sie die im HTML- Farbformat verwendete Farbnummer :

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

Verwenden Sie es als ("basic" sind die ersten 16 Farben, "color" ist die Hauptgruppe, "grey" ist die letzte graue Farbe):

$ tohex 125                  ### A number in range 0-255
dec= 125 color= #af005f
$ tohex 6
dec=   6 basic= #008080
$ tohex 235
dec= 235  gray= #262626
Jeff Schaller
quelle
Ihre fromhex-Funktion ist großartig! Vielen Dank!
mhulse
Lovin ' fromhex. Danke noch einmal! Außerdem habe ich einen Scheck für das hinzugefügt# . Feedback?
mhulse
1
Ja, das Entfernen eines führenden '#' ist ein angemessener Schutz. Ich finde es viel einfacher zu bedienen hex=${1#"#"}. Es wird nichts entfernen, wenn $1es kein a gibt #, und es entfernen, wenn es existiert. Siehe meinen aktualisierten Code.
Nett! Viel kompakter. Aktualisiere jetzt meinen Code. Danke!!!!
mhulse
Beachten Sie, dass mir zumindest in meiner xterm-Version \e[0;%s8;2;%s;%s;%smnicht 16 Millionen Farben zur Verfügung stehen, sondern nur die Farbe in der 240-Farben-Palette, die dem angeforderten RGB am nächsten kommt.
Stéphane Chazelas
14

Die kurze Antwort lautet, dass Sie in den Web-Tabellen Farbtabellen finden und diese mit der Farbnummer abgleichen können.

Die lange Antwort ist, dass die korrekte Zuordnung vom Terminal abhängt -

Dies 125ist ein Parameter für eine Escape-Sequenz, auf die setafin der Terminalbeschreibung verwiesen wird . tputmisst der Zahl keine besondere Bedeutung bei. Das hängt tatsächlich vom jeweiligen Terminalemulator ab.

Vor einiger Zeit definierte ANSI Codes für 8 Farben, und es gab zwei Schemata, um diese zu nummerieren. Die beiden sind in einigen Terminalbeschreibungen als die Paare setf/setboder zu sehen setaf/setab. Da letztere die Konnotation "ANSI-Farben" hat, werden Sie feststellen, dass diese häufiger verwendet werden. Ersteres (setf / setb) hat die Reihenfolge für Rot / Blau geändert, wie in den ncurses FAQ angegeben. Warum sind Rot / Blau vertauscht? In beiden Fällen wurde das Schema nur für die Nummerierung der Farben festgelegt. Es gibt keine vordefinierte Beziehung zwischen diesen Zahlen und dem RGB-Inhalt.

Für bestimmte Terminal-Emulatoren gibt es vordefinierte Farbpaletten, die sich leicht aufzählen lassen - und mit diesen Escape-Sequenzen programmieren lassen. Es gibt keine relevanten Standards, und Sie werden Unterschiede zwischen Terminalemulatoren feststellen, wie in den xterm-FAQ vermerkt. Ich mag diesen Blauton nicht .

Konventionen werden jedoch oft mit Standards verwechselt. Bei der Entwicklung von xterm in den letzten 20 Jahren wurden ANSI (8) aixterm-Farben verwendet, die Feature (16) -Farben angepasst und Erweiterungen für 88- und 256-Farben hinzugefügt. Ein Großteil davon wurde von anderen Entwicklern für verschiedene Terminalemulatoren übernommen. Das ist in den xterm FAQ zusammengefasst. Warum wird "xterm" nicht gleich "xterm-256color" gesetzt? .

Der xterm-Quellcode enthält Skripte zum Demonstrieren der Farben, z. B. unter Verwendung derselben Escape-Sequenzen, tputdie verwendet würden.

Diese Frage / Antwort ist möglicherweise auch hilfreich: RGB-Werte der Farben im erweiterten Ansi-Farbindex (17-255)

Thomas Dickey
quelle
Vielen Dank für Ihre Hilfe Thomas, ich weiß das sehr zu schätzen! Ich arbeite auf einem Mac / OS X mit iTerm. Ihre Erklärung hilft mir wirklich dabei, mehr über mein Setup zu verstehen (ich habe viel von den prompten Farben anderer Leute im Web kopiert / eingefügt). Ich freue mich sehr, dass Sie sich die Zeit genommen haben, mir eine detaillierte und informative Antwort zu schreiben. :)
mhulse
9

Das tputDienstprogramm verwendet eine 256-Farben-Lookup-Tabelle zum Drucken von 8-Bit-ANSI-Escape-Sequenzen (beginnend mit Escund [), wobei Terminalfunktionen verwendet werden , sodass diese Steuersequenzen als Farben interpretiert werden können. Hierbei handelt es sich um einen vordefinierten Satz von 256 Farben, die üblicherweise für Grafikkarten verwendet werden.

Verwenden Sie den folgenden Einzeiler, um alle 256 Farben im Terminal zu drucken:

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

Hinweis: An Spaltenliste | columnanhängen.

Diese 256-Farben-Nachschlagetabelle finden Sie auch auf der Wikipedia-Seite wie folgt:

Diagramm;  ANSI-Escape-Code;  8-Bit-Nachschlagetabelle mit 256 Farben bei Wikipedia;  256-Farben-Modus - Vordergrund: ESC [38; 5; #m Hintergrund: ESC [48; 5; #m

Kenorb
quelle
3

Mit zsh und in einem xterm-ähnlichen Terminal ( xtermund vte-basierten Endgeräten wie gnome-terminal, xfce4-terminal... zumindest), können Sie tun:

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

Das Bash-Äquivalent:

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

(Sie möchten, dass die Escape-Sequenz die Farbe abfragt, die gesendet werden soll, nachdem die Terminaldisziplin echodeaktiviert wurde (mit -s). Andernfalls wird die Antwort die Hälfte der Zeit von der Liniendisziplin angezeigt, daher wird sie als Teil der readEingabeaufforderung gesendet ( var?promptin zsh) wie in ksh, -p promptin bash)).

um die Definition von Farbe 125 zu erhalten (hier als RGB-Spezifikation, wobei jede Zahl die Intensität der Rot-, Grün- und Blau-Komponenten als Hex-Zahl zwischen 0 und FFFF darstellt).

Sie können dasselbe für die ersten 16 Farben mit dem xtermcontrolBefehl tun :

$ xtermcontrol --get-color1
rgb:cdcd/0000/0000
Stéphane Chazelas
quelle
Super, vielen Dank für die Hilfe! +1
mhulse
@ Gilles, Sie möchten, dass die Abfrage über die Eingabeaufforderung gesendet wird, nachdem das Echo der Terminaldisziplin deaktiviert wurde. Siehe Bearbeiten.
Stéphane Chazelas
@ StéphaneChazelas Mit einem anderen Terminalprogramm (gnome-terminal) (das ein xterm-Terminal ist) habe ich Ihren Code richtig funktionieren lassen (sowohl in bash als auch in zsh) Seltsamerweise: tput colorsBerichte nur 8, wenn das Terminal 256 Farben darstellen kann. Außerdem tput colorsmeldet die xterm-color (Konsole) nur, 8wenn dieses Terminal 16 Millionen Farben (und natürlich alle 256 Farben) vollständig darstellen kann. Und nein, kein tmux oder Bildschirm, der "färben" kann :-) (das ist ändern) die Ergebnisse (mir war dieses Detail bekannt). Kurz gesagt: Ihr Code kann in einigen Terminals / Konsolen fehlschlagen.
Ah, tohex fügte meiner Antwort hinzu: Ein bisschen länger als ich erwartet hatte, aber die 256 Farben haben einiges an kuriosen Wendungen.
0

ANSI-Farben auf Konsolenebene

Abhängig davon, welches Protokoll Ihre Konsole verwendet, könnte die Reihenfolge wie folgt lauten: \e[38;5;XXXmoder \e[3XXXmwo XXXentspricht die Ansi-Nummer?

Um sicherzustellen, dass Sie die richtige ANSI-Sequenz verwenden, müssen Sie verwenden tput.

In Bezug auf den ANSI-Escape-Code von Wikipedia habe ich Folgendes geschrieben:

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

Könnte so etwas rendern wie:

Bildbeschreibung hier eingeben

... Dann, weil ich es hasse, mehr als 200 Gabeln in einem kleinen Skript laufen zu lassen, schrieb ich Folgendes:

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

Mit nur 1 Gabel! Gleiches Ergebnis, aber viel schneller!

F. Hauri
quelle