Answers:
可用的颜色计数由给出tput colors
。
要查看8种基本颜色(setf
在urxvt终端和setaf
xterm终端中使用):
$ printf '\e[%sm▒' {30..37} 0; echo ### foreground
$ printf '\e[%sm ' {40..47} 0; echo ### background
通常命名为:
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
要查看扩展的256种颜色(如setaf
urxvt中所使用的):
$ printf '\e[48;5;%dm ' {0..255}; printf '\e[0m \n'
如果需要数字和有序输出:
#!/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}
1600万种颜色需要大量代码(某些控制台无法显示此代码)。
基础是:
fb=3;r=255;g=1;b=1;printf '\e[0;%s8;2;%s;%s;%sm▒▒▒ ' "$fb" "$r" "$g" "$b"
fb
是front/back
或3/4
。
对控制台显示多种颜色的能力的简单测试是:
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
它将显示一条红线,从左到右的音调变化很小。如果可以看到很小的变化,则您的控制台可以支持1600万种颜色。
每个r
,g
以及 b
是从0到255为RGB(红,绿,蓝)的值。
如果您的控制台类型支持此功能,则此代码将创建一个颜色表:
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
要将十六进制颜色值转换为(最近的)0-255颜色索引,请执行以下操作:
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 ))"
}
用作:
$ fromhex 00fc7b
048
$ fromhex #00fc7b
048
要查找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
将其用作(“基本”是前16种颜色,“颜色”是主要组,“灰色”是最后的灰色):
$ tohex 125 ### A number in range 0-255
dec= 125 color= #af005f
$ tohex 6
dec= 6 basic= #008080
$ tohex 235
dec= 235 gray= #262626
\e[0;%s8;2;%s;%s;%sm
它不会给我提供1600万种颜色,只有240个调色板中最接近所请求rgb的颜色。
简短的答案是,您可以在网络表上找到颜色并将它们与颜色编号匹配。
长答案是正确的映射取决于终端-
的125
是被称作转义序列的参数setaf
在所述终端的说明。 tput
该数字没有特殊含义。这实际上取决于特定的终端仿真器。
不久前,ANSI为8种颜色定义了代码,并且有两种对这些颜色进行编号的方案。在某些终端说明中,这两个对称为setf/setb
或setaf/setab
。由于后者具有“ ANSI颜色”的含义,因此您会看到使用频率更高。前者(setf / setb)按照ncurses常见问题解答中的说明切换了红色/蓝色的顺序。为什么红色/蓝色互换?,但无论哪种情况,都建立了仅对颜色编号的方案。这些数字与RGB内容之间没有预定义的关系。
对于特定的终端仿真器,有预定义的调色板,可以很容易地枚举它们,并且可以使用这些转义序列进行编程。有没有相关的标准,你会看到终端仿真器之间的差异,如xterm的FAQ指出,我不喜欢的是蓝荫。
但是,惯例经常与标准混淆。在过去20年中xterm的开发中,它合并了ANSI(8)颜色,改编了aixterm
功能(16)颜色,并增加了88和256色的扩展名。其他开发人员已经为不同的终端仿真器采用了许多方法。在xterm常见问题中对此进行了总结,为什么不将“ xterm”等同于“ xterm-256color”?。
xterm源代码包括用于演示颜色的脚本,例如,使用将使用的相同转义序列tput
。
您可能还会发现此问题/答案也很有帮助:Ansi扩展颜色索引中的颜色RGB值(17-255)
该tput
实用程序正在使用256色查找表来打印使用终端功能的8位ANSI转义序列(以Esc和开头[
),因此这些控制序列可以解释为颜色。这些是图形卡中常用的256种预定义颜色集。
要在终端中打印所有256色,请尝试以下单线:
for c in {0..255}; do tput setaf $c; tput setaf $c | cat -v; echo =$c; done
提示:追加| column
到列列表。
此256色查找表也可以在Wikipedia页面上找到,如下所示:
随着zsh中,并在xterm
样终端(xterm
和vte
基于终端一样gnome-terminal
,xfce4-terminal
......至少),你可以这样做:
$ read -s -t1 -d $'\a' $'c?\e]4;125;?\a' && echo "${c##*;}"
rgb:afaf/0000/5f5f
相当于bash:
read -s -t1 -d $'\a' -p $'\e]4;125;?\a' c && echo "${c##*;}"
(您希望转义序列查询禁用终端规则后的发送颜色echo
(使用-s
),否则响应将在一半时间由行规则显示,因此作为read
提示的一部分发送(var?prompt
在zsh中就像在ksh,-p prompt
bash中一样))。
以获得颜色125的定义(此处为RGB规范,每个数字都是红色,绿色和蓝色分量的强度,为介于0和FFFF之间的十六进制数字)。
您可以使用以下xtermcontrol
命令对前16种颜色执行相同的操作:
$ xtermcontrol --get-color1
rgb:cdcd/0000/0000
tput colors
仅报告8
。同样,即使该终端完全能够显示1600万种颜色(当然,所有256种颜色),xterm-color(Konsole)也tput colors
仅报告8
。不,没有tmux或屏幕可能会“着色”:-)(即更改)结果(我知道该细节)。简而言之:您的代码可能在某些终端/控制台中失败。
根据至极长期协议控制台使用,顺序可能是:\e[38;5;XXXm
或\e[3XXXm
其中XXX
符合ANSI号。
为确保使用正确的ANSI序列,必须使用tput
。
关于Wikipedia的ANSI转义代码,我这样写:
#!/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
可以呈现如下内容:
...然后,因为我在一个小脚本中讨厌runnig超过200个fork,所以我这样写:
#!/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
只用1把叉子!结果相同,但速度更快!