在终端中设置、备份和恢复颜色

在终端中设置、备份和恢复颜色

我用这个程序显示终端中可用的所有颜色。我得到的是:

在此输入图像描述

  1. 该程序不显示低于 100 的颜色。为什么?有没有办法显示它们。
  2. 有没有办法改变某些 #rrggbb 值的第 n 个颜色?或者这个颜色是预定义的?
  3. 如果我可以改变颜色(参见问题 2),有没有办法导出和导入这个值?

答案1

支持多少种颜色以及如何更改前景色和背景色取决于终端。

数据库terminfo通常可以帮助您找到正确的顺序。

大多数彩色终端支持 ANSI 颜色转义序列来更改前景和背景颜色 0 到 7

那是:

  • 设置前景色$n:printf "\33[3${n}m"
  • 设置背景颜色$n:printf "\33[4${n}m"

一些(罕见的)终端(例如emu)对这些 ANSI 颜色使用不同的序列。

一些(罕见的)终端(例如 QNX 控制台)具有不同的转义序列和不同的颜色。

有些(罕见)使用颜色对。您定义背景和前景的颜色对,然后使用转义序列来选择要使用的颜色对。

现在,xterm 和大多数现代自由软件终端仿真器将基本的 8 种 ANSI 颜色扩展到最多 16 种(其中 8 到 15 是 ANSI 颜色 0 到 7 的更亮版本),有些甚至是 88 或 256 种颜色。

有些终端rxvt仅支持 8 种颜色,但如果需要,请使用更亮的颜色大胆的也打开(对于前台)或(作为背景)。\033[34;1m会产生比 更亮的蓝色\033[34m

使用颜色的最便携方法是使用 terminfo 数据库。

可以通过tput命令来实现。tcsh并且zsh还有一个echoti内置的。

假设 terminfo 数据库正确并且 的值$TERM正确反映了您正在使用的终端:

tput colors

将为您提供终端支持的颜色数量。

如今,除了上面提到的罕见例外之外,您可以假设您的终端将支持 ANSI 颜色。 ANSI 背景和前景色的 terminfo 功能为setabsetaf。如果终端支持超过 8 种颜色,您仍然可以使用该功能来查询它们。

tput setaf 233

如果终端支持 256 色,则应输出该颜色 233 的正确转义序列。

对于xtermsetaf输出\033[30m..\033[37m颜色 0 到 7、\033[90m..\033[97m颜色 8 到 15 以及\033[38;5;16m..\033[38;5;255m颜色 16 到 255。

\033[38;5;0m..\033[38;5;15m也可以工作,但比颜色 0 到 15 的更便携的等效项长 4 个字节。

因此,要测试终端支持的所有颜色。如果支持 ansi 颜色:

i=0; n=$(tput colors); while [ "$i" -lt "$n" ]; do
  tput setaf "$i"; printf %04d "$i"
  i=$((i + 1))
done

如果支持其他颜色:

i=0; n=$(tput colors); while [ "$i" -lt "$n" ]; do
  tput setf "$i"; printf %04d "$i"
  i=$((i + 1))
done

如果它适用于颜色对(如 hpterm-color):

i=0; n=$(tput pairs); while [ "$i" -lt "$n" ]; do
  tput scp "$i"; printf %04d "$i"
  i=$((i + 1))
done

现在,要重新定义颜色或颜色对,这在终端之间也有所不同。

有一个initcterminfo 功能可以为那些可以执行此操作的终端重新定义给定的颜色。并initp重新定义一对。

例如将颜色 1 重新定义为亮白色:

 tput initc 1 1000 1000 1000

使用xterm,发送序列:\033]4;1;rgb:FF/FF/FF\033\

在使用颜色对的终端上将颜色对 1 重新定义为黑底白字:

 tput initp 1 1000 1000 1000 0 0 0

答案2

由于您正在使用,gnome-terminal因此无需更改 RGB 值。最近gnome-terminal(自 v. 3.12 起)支持真正的 24 位颜色(1600 万)。您可以使用 来设置它们\e[38;2;R;G;B。例如

printf '\e[38;2;100;200;200mTest\e[0m\n'

如果您看到蓝色文本,则说明您的终端支持 24 位颜色。


但是,如果您想坚持使用 256 色,我建议使用以下脚本来显示所有可能性,该脚本以块的形式显示它们,以便轻松选取所需的颜色(带有更少或更多的 RGB 分量):

#!/bin/bash

trap 'echo "Bye"; exit 1' INT

echo "PALETTE OF 8 COLORS"
for i in {30..37}; do printf "\e[1;${i}mTest%-3u \e[0m" "$i"; done; echo
for i in {90..97}; do printf "\e[${i}mTest%-3u \e[0m" "$i"; done; echo
for i in {30..37}; do printf "\e[${i}mTest%-3u \e[0m" "$i"; done; echo
for i in {30..37}; do printf "\e[2;${i}mTest%-3u \e[0m" "$i"; done; echo -e "\n"

echo "PALETTE OF 256 COLORS"
j=8
for i in {0..255}; do
    [[ $i = 16 ]] && j=6
    [[ $i = 232 ]] && j=24
    printf "\e[38;5;${i}mTest%-3u \e[0m" "$i"
    [[ $(( $(( $i - 15 )) % $j )) = 0 ]] && echo
    [[ $(( $(( $i - 15 )) % $(( $j * 6 )) )) = 0 ]] && echo
done
exit 0

答案3

正如我发现的,我可以通过以下方式获得所有颜色

for i in {0..255} ; do printf "\x1b[38;5;${i}mcolour${i}\n"; done

可以~/.Xresources像这样更改 RGB 值:

xterm*color4: CornflowerBlue
URxvt*color1  : #ff0000
URxvt*color8  : #888888

但并非所有终端仿真器都遵循此值。URXVT是、gnome-terminal不是

答案4

该程序存在缺陷,因为它用空格将数字填充为 3 个字符。例如,打印“ [[48;5; 42m(带空格)不起作用,而不是打印^[[48;5;42m(不带空格)起作用。

相关内容