tabel warna tput setaf? Bagaimana cara menentukan kode warna?

79

Saya sedang dalam proses pewarnaan terminal saya PS1.

Saya mengatur variabel warna menggunakan tput; misalnya, inilah ungu:

PURPLE=$(tput setaf 125)

Pertanyaan:

Bagaimana cara menemukan kode warna (mis. 125) Warna lain?

Apakah ada panduan tabel warna / cheat sheet di suatu tempat?

Saya hanya tidak yakin apa 125itu ... Apakah ada cara untuk mengambil warna hex dan mengubahnya menjadi angka yang setafdapat digunakan?

mhulse
sumber

Jawaban:

153

Hitungan warna yang tersedia untuk tput diberikan oleh tput colors.

Untuk melihat 8 warna dasar (seperti yang digunakan oleh setfdi terminal urxvt dan setafdi terminal xterm):

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

Dan biasanya dinamai seperti ini:

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

Untuk melihat 256 warna yang diperluas (seperti yang digunakan oleh setafdalam urxvt):

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

Jika Anda menginginkan angka dan output yang dipesan:

#!/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 bagan warna secara berurutan, berlabel dengan indeks mereka


16 juta warna memerlukan sedikit kode (beberapa konsol tidak dapat menampilkan ini).
Dasar-dasarnya adalah:

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

fbadalah front/backatau 3/4.

Tes sederhana dari kapasitas konsol Anda untuk menampilkan begitu banyak warna adalah:

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

garis merah, memudar dari gelap ke lebih terang (kiri ke kanan) Ini akan menghadirkan garis merah dengan perubahan nada yang sangat kecil dari kiri ke kanan. Jika perubahan kecil itu terlihat, konsol Anda mampu 16 juta warna.

Masing-masing r,, gdan bmerupakan nilai dari 0 hingga 255 untuk RGB (Merah, Hijau, Biru).

Jika jenis konsol Anda mendukung ini, kode ini akan membuat tabel warna:

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

bagan warna foreground sampel dengan indeks mereka sebagai label

bagan warna latar belakang sampel dengan indeks mereka sebagai label

Untuk mengonversi nilai warna hex ke indeks warna 0-255 (terdekat):

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

Gunakan sebagai:

$ fromhex 00fc7b
048
$ fromhex #00fc7b
048

Untuk menemukan nomor warna seperti yang digunakan dalam format warna 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

Gunakan sebagai ("dasar" adalah 16 warna pertama, "warna" adalah kelompok utama, "abu-abu" adalah warna abu-abu terakhir):

$ 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
sumber
Fungsi fromhex Anda hebat! Terima kasih banyak!
mhulse
Sayang sekali fromhex. Terima kasih lagi! Juga, saya menambahkan cek untuk# . Umpan balik?
mhulse
1
Ya, menghapus awalan '#' adalah perlindungan yang masuk akal. Saya menemukan jauh lebih mudah digunakan hex=${1#"#"}. Ini tidak akan menghapus apa pun jika $1tidak memiliki #, dan menghapusnya jika ada. Lihat kode saya yang diperbarui.
Bagus! Jauh lebih kompak. Memperbarui kode saya sekarang. Terima kasih!!!!
mhulse
Perhatikan bahwa setidaknya dalam versi xterm \e[0;%s8;2;%s;%s;%smsaya tidak memberi saya 16 juta warna, hanya warna dalam palet 240 warna yang paling dekat dengan rgb yang diminta.
Stéphane Chazelas
14

Jawaban singkatnya adalah Anda dapat menemukan tabel warna di web dan mencocokkannya dengan nomor warna.

Jawaban panjangnya adalah bahwa pemetaan yang benar tergantung pada terminal -

Ini 125adalah parameter untuk urutan pelarian yang disebut setafdalam deskripsi terminal. tputtidak memiliki arti khusus pada nomor tersebut. Itu sebenarnya tergantung pada emulator terminal tertentu.

Beberapa waktu yang lalu, ANSI menetapkan kode untuk 8 warna, dan ada dua skema untuk penomoran itu. Keduanya terlihat dalam beberapa deskripsi terminal sebagai pasangan setf/setbatau setaf/setab. Karena yang terakhir memiliki konotasi "warna ANSI", Anda akan melihat yang digunakan lebih sering. Mantan (setf / setb) mengganti urutan untuk merah / biru seperti yang tercantum dalam FAQ ncurses. Mengapa merah / biru dipertukarkan? , tetapi dalam kedua kasus tersebut, skema dibuat hanya untuk penomoran warna. Tidak ada hubungan yang telah ditentukan antara angka-angka dan konten RGB.

Untuk emulator terminal tertentu, ada palet warna yang telah ditentukan yang dapat dihitung dengan cukup mudah - dan dapat diprogram menggunakan urutan pelarian ini. Tidak ada standar yang relevan, dan Anda akan melihat perbedaan antara emulator terminal, seperti yang tercantum dalam FAQ xterm. Saya tidak suka warna biru .

Namun, konvensi sering dikacaukan dengan standar. Dalam pengembangan xterm selama 20 tahun terakhir, ia menggabungkan warna ANSI (8), mengadaptasi aixtermfitur (16) warna, menambahkan ekstensi untuk 88 dan 256 warna. Banyak dari itu telah diadopsi oleh pengembang lain untuk emulator terminal yang berbeda. Itu dirangkum dalam FAQ xterm Mengapa tidak membuat "xterm" disamakan dengan "xterm-256color"? .

Kode sumber xterm menyertakan skrip untuk mendemonstrasikan warna, misalnya, menggunakan urutan pelarian yang sama yang tputakan digunakan.

Anda juga dapat menemukan pertanyaan / jawaban ini bermanfaat: Nilai RGB dari warna dalam indeks warna diperluas Ansi (17-255)

Thomas Dickey
sumber
Terima kasih banyak atas bantuan Anda Thomas, saya sangat menghargainya! Saya menggunakan Mac / OS X yang menjalankan iTerm. Penjelasan Anda benar-benar membantu saya memahami lebih banyak tentang pengaturan saya (saya telah melakukan banyak copy / paste dari berbagai warna prompt orang lain di web). Saya sangat menghargai Anda meluangkan waktu untuk menulis kepada saya jawaban yang terperinci dan informatif. :)
mhulse
9

The tpututilitas menggunakan tabel pencarian 256-warna untuk mencetak ANSI escape sequence 8-bit (dimulai dengan Escdan [) yang menggunakan kemampuan terminal , sehingga urutan kontrol ini dapat diartikan sebagai warna. Ini adalah kumpulan 256 warna yang telah ditentukan sebelumnya yang biasa digunakan pada kartu grafis.

Untuk mencetak semua 256 warna di terminal, coba one-liner berikut:

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

Petunjuk: Tambahkan | columnke daftar kolom.

Tabel pencarian 256-warna ini juga dapat ditemukan di halaman Wikipedia sebagai berikut:

Grafik;  Kode pelarian ANSI;  Tabel pencarian 256-warna 256-bit di Wikipedia;  Mode 256-warna - latar depan: ESC [38; 5; #m latar belakang: ESC [48; 5; #m

kenorb
sumber
3

Dengan zsh dan di terminal-like xterm( xtermdan vte-based terminal seperti gnome-terminal, xfce4-terminal... setidaknya), Anda dapat melakukan:

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

Setara bash:

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

(Anda ingin urutan escape untuk menanyakan warna yang akan dikirim setelah disiplin terminal echodinonaktifkan (dengan -s) jika tidak, responsnya akan ditampilkan oleh disiplin garis setengah dari waktu, maka pengirimannya sebagai bagian dari readprompt ( var?promptdalam zsh seperti di ksh, -p promptdi bash)).

untuk mendapatkan definisi warna 125 (di sini sebagai spesifikasi RGB, masing-masing bilangan menjadi intensitas komponen Merah, Hijau dan Biru sebagai bilangan heksa antara 0 dan FFFF).

Anda dapat melakukan hal yang sama untuk 16 warna pertama dengan xtermcontrolperintah:

$ xtermcontrol --get-color1
rgb:cdcd/0000/0000
Stéphane Chazelas
sumber
Luar biasa, terima kasih banyak atas bantuannya! +1
mhulse
@Gilles, Anda ingin kueri dikirim melalui prompt setelah gema disiplin terminal dinonaktifkan. Lihat edit.
Stéphane Chazelas
@ StéphaneChazelas Menggunakan program terminal lain (gnome-terminal) (yang merupakan terminal xterm) Saya mendapatkan kode Anda untuk bekerja dengan benar (baik dalam bash dan zsh) Anehnya: tput colorsmelaporkan hanya 8jika terminal mampu menyajikan 256 warna. Juga, xterm-color (Konsole) tput colorshanya melaporkan 8bahkan jika terminal itu sepenuhnya mampu menghadirkan 16 juta warna (dan tentu saja semua 256 warna). Dan tidak, tidak ada tmux atau layar yang dapat "mewarnai" :-) (ubahlah itu) hasilnya (saya tahu detail itu). Singkatnya: kode Anda mungkin gagal di beberapa terminal / konsol.
Ah, tohex ditambahkan ke jawaban saya, sedikit lebih lama dari yang saya harapkan, tetapi 256 warna memiliki sedikit putaran yang aneh.
0

ANSI Colors pada istilah konsol

Tergantung pada protokol istilah yang digunakan konsol Anda, urutannya bisa: \e[38;5;XXXmatau di \e[3XXXmmana XXXsesuai dengan nomor ansi.

Untuk memastikan Anda menggunakan urutan ANSI yang tepat, Anda harus menggunakan tput.

Mengenai kode pelarian ANSI Wikipedia , saya menulis ini:

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

Dapat membuat sesuatu seperti:

masukkan deskripsi gambar di sini

... Lalu, karena saya benci runnig lebih dari 200 garpu dalam naskah kecil, saya menulis ini:

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

Dengan hanya 1 garpu! Hasil yang sama, tetapi jauh lebih cepat!

F. Hauri
sumber