Note
您可能无法为 Windows 着色cmd prompt
,但它应该可以在许多 UNIX(或类 Unix)终端中工作。
另请注意,某些终端根本不支持某些(如果有)ANSI 转义序列,尤其是 24 位颜色。
Usage
请参阅 部分Curses在底部寻找最佳解决方案。对于个人或简单的解决方案(尽管not作为跨平台解决方案),请参阅ANSI 转义序列部分。
TL;DR
ANSI 转义序列
逃脱序列的背景
虽然这不是最好的方法,但在编程或脚本语言中执行此操作的最简单方法是使用转义序列。从该链接:
转义序列是用于更改计算机及其连接的外围设备状态的一系列字符。这些也称为控制序列,反映了它们在设备控制中的用途。
ANSI 转义序列的背景
然而,它比视频文本终端更容易,因为这些终端使用ANSI 转义序列。从该链接:
ANSI 转义序列是带内信令的标准,用于控制视频文本终端上的光标位置、颜色和其他选项。某些字节序列(大多数以 Esc 和“[”开头)嵌入到文本中,终端会查找这些字节并将其解释为命令,而不是字符代码。
如何使用 ANSI 转义序列
一般来说
- Escape sequences begin with an escape character; for ANSI escape sequences, the sequence always begins with ESC (ASCII:
27
/ hex: 0x1B
).
- 有关您可以执行的操作的列表,请参阅维基百科上的 ANSI 转义序列列表
在编程语言中
Some programming langauges (like Java) will not interpret \e
or \x1b
as the ESC character. However, we know that the ASCII character 27
is the ESC character, so we can simply typecast 27
to a char
and use that to begin the escape sequence.
以下是使用常见编程语言实现此目的的一些方法:
-
Java
System.out.println((char)27 + "[33mYELLOW");
-
Python 3
print(chr(27) + "[34mBLUE");
-
print("\x1b[35mMAGENTA");
-
Node JS
- 以下将NOTWeb 控制台中 JavaScript 的颜色输出
console.log(String.fromCharCode(27) + "[36mCYAN");
-
console.log("\x1b[30;47mBLACK_ON_WHITE");
在 Shell 提示符或脚本中
如果您正在与bash or zsh,对输出进行着色非常容易(在大多数终端中)。在 Linux、Os X 和某些 Window 终端中,您可以通过执行以下两项操作来检查终端是否支持颜色:
printf '\e[31mRED'
printf '\x1b[31mRED'
如果您看到两者的颜色,那就太好了!如果您只看到一种颜色,则使用该序列。如果您没有看到其中任何一个的颜色,请仔细检查以确保您输入的所有内容正确并且您使用的是 bash 或 zsh;如果您仍然看不到任何颜色,则您的终端可能不支持 ANSI 转义序列。
如果我没记错的话,linux 终端往往都支持\e
and \x1b
转义序列,而 os x 终端仅倾向于支持\e
,但我可能是错的。尽管如此,如果您看到类似下图的内容,那么您就已经准备好了! (请注意,我使用的是 shell,zsh,它正在为我的提示字符串着色;另外,我正在使用urxvt作为我在 Linux 中的终端。)
"How does this work?" you might ask. Bascially, printf
is interpretting the sequence of characters that follows (everything inside of the single-quotes). When printf
encounters \e
or \x1b
, it will convert these characters to the ESC character (ASCII: 27). That's just what we want. Now, printf
sends ESC31m
, and since there is an ESC followed by a valid ANSI escape sequence, we should get colored output (so long as it is supported by the terminal).
您还可以使用echo -e '\e[32mGREEN'
(例如),颜色输出。请注意,-e
标记为echo
“[启用]反斜杠转义的解释”如果你想要的话必须使用echo
正确解释转义序列。
有关 ANSI 转义序列的更多信息
ANSI 转义序列不仅仅可以做颜色输出,但让我们从它开始,看看颜色到底是如何工作的;然后,我们将看到如何操作光标;最后,我们将看看如何使用 8 位颜色和 24 位颜色(尽管它的支持很薄弱)。
On Wikipedia, they refer to ESC[ as CSI
, so I will do the same.
Color
要使用 ANSI 转义颜色输出,请使用以下命令:
-
CSI
n
m
-
CSI
: escape character—^[[
or ESC[
-
n
: a number—one of the following:
-
30
-37
, 39
:前景
-
40
-47
, 49
: 背景
-
m
: ASCII 文字m
—终止转义序列
我将使用 bash 或 zsh 来演示所有可能的颜色组合。将以下内容放入 bash 或 zsh 中亲自查看(您可能需要替换\e
with \x1b
):
for fg in {30..37} 39; do for bg in {40..47} 49; do printf "\e[${fg};${bg}m~TEST~"; done; printf "\n"; done;
Result:
快速参考(颜色)
+~~~~~~+~~~~~~+~~~~~~~~~~~+
| fg | bg | color |
+~~~~~~+~~~~~~+~~~~~~~~~~~+
| 30 | 40 | black |
| 31 | 41 | red |
| 32 | 42 | green |
| 33 | 43 | yellow |
| 34 | 44 | blue |
| 35 | 45 | magenta |
| 36 | 46 | cyan |
| 37 | 47 | white |
| 39 | 49 | default |
+~~~~~~+~~~~~~+~~~~~~~~~~~+
选择图形呈现 (SGR)
SGR 只允许您更改文本。其中许多在某些终端中不起作用,因此在生产级项目中谨慎使用它们。但是,它们对于使程序输出更具可读性或帮助您区分不同类型的输出非常有用。
颜色实际上属于 SGR,因此语法是相同的:
-
CSI
n
m
-
CSI
: escape character—^[[
or ESC[
-
n
: a number—one of the following:
-
0
: reset
-
1
-9
:开启各种文字效果
-
21
-29
:关闭各种文本效果(支持较少1
-9
)
-
30
-37
, 39
: 前景色
-
40
-47
, 49
: 背景颜色
-
38
:8 位或 24 位前景色(请参见8/24 位颜色 below)
-
48
:8 位或 24 位背景颜色(请参阅8/24 位颜色 below)
-
m
: ASCII 文字m
—终止转义序列
尽管对微弱 (2)、斜体 (3)、下划线 (4)、闪烁 (5,6)、反白 (7)、隐藏 (8) 和划线 (9) 的支持很微弱,但有些(但很少全部)倾向于在 Linux 和 os x 终端上工作。
还值得注意的是,您可以用分号分隔上述任何属性。例如printf '\e[34;47;1;3mCRAZY TEXT\n'
将会呈现CRAZY TEXT
with a blue foreground
on a white background
,这将是bold
and italic
.
Eg:
在 bash 或 zsh shell 中输入以下内容即可查看您可以执行的所有文本效果。 (您可能需要更换\e
with \x1b
.)
for i in {1..9}; do printf "\e[${i}m~TEST~\e[0m "; done
Result:
可以看到我的终端支持所有的文字效果except for faint (2), conceal(8) 和划掉 (9).
快速参考(SGR 属性 0-9)
+~~~~~+~~~~~~~~~~~~~~~~~~+
| n | effect |
+~~~~~+~~~~~~~~~~~~~~~~~~+
| 0 | reset |
| 1 | bold |
| 2 | faint* |
| 3 | italic** |
| 4 | underline |
| 5 | slow blink |
| 6 | rapid blink* |
| 7 | inverse |
| 8 | conceal* |
| 9 | strikethrough* |
+~~~~~+~~~~~~~~~~~~~~~~~~+
* not widely supported
** not widely supported and sometimes treated as inverse
8 位颜色
虽然大多数终端都支持这一点,但它的支持程度低于0-7
,9
colors.
Syntax:
-
CSI
38;5;
n
m
-
CSI
: escape character—^[[
or ESC[
-
38;5;
:表示使用 8 位颜色作为前景的文字字符串
-
n
: a number—one of the following:
如果您想以良好的方式预览终端中的所有颜色,我有gist.github.com 上有一个不错的脚本.
它看起来像这样:
如果您想使用 8 位颜色更改背景,只需替换38
with a 48
:
-
CSI
48;5;
n
m
-
CSI
: escape character—^[[
or ESC[
-
48;5;
:表示使用 8 位颜色作为背景的文字字符串
-
n
: a number—one of the following:
24 位颜色
24 位颜色也称为真彩色,它提供了一些非常酷的功能。对这一点的支持肯定在增长(据我所知,它适用于大多数现代终端,除了urxvt,我的终端[插入愤怒的表情符号])。
vim 实际上支持 24 位颜色(请参阅vim wiki查看如何启用 24 位颜色)。它真的很简洁,因为它取自为 gvim 定义的颜色方案;例如,它使用来自的 fg/bghighlight guibg=#______ guifg=#______
对于 24 位颜色!尼托,是吧?
以下是 24 位颜色的工作原理:
-
CSI
38;2;
r
;
g
;
b
m
-
CSI
: escape character—^[[
or ESC[
-
38;2;
:表示使用 24 位颜色作为前景的文字字符串
-
r
,g
,b
:数字——每个都应该是0
-255
To test 一些您可以拥有多种颜色((2^8)^3
or 2^24
or 16777216
我认为有可能),你可以在 bash 或 zsh 中使用它:
for r in 0 127 255; do for g in 0 127 255; do for b in 0 127 255; do printf "\e[38;2;${r};${g};${b}m($r,$g,$b)\e[0m "; done; printf "\n"; done; done;
结果(这是在gnome 终端 since urxvt不支持 24 位颜色...把它放在一起,urxvt 维护者...真正的):
如果您想要 24 位颜色的背景......您猜对了!你只需更换38
with 48
:
-
CSI
48;2;
r
;
g
;
b
m
-
CSI
: escape character—^[[
or ESC[
-
48;2;
:表示使用 24 位颜色作为背景的文字字符串
-
r
,g
,b
:数字——每个都应该是0
-255
插入原始转义序列
有时\e
and \x1b
不管用。例如,在shshell,有时两者都不起作用(尽管它在我的系统上起作用)now,我不认为以前是这样)。
To circumvent this, you can use CTRL+V,CTRL+[ or CTRLV,ESC
This will insert a "raw" ESC character (ASCII: 27). It will look like this ^[
, but do not fret; it is only one character—not two.
Eg:
Curses
请参阅Curses(编程库)页面有关诅咒的完整参考。需要注意的是,curses 仅适用于 unix 和类 unix 操作系统。
使用 Curses 启动并运行
我不会讨论太多细节,因为搜索引擎可以显示网站的链接,这些网站可以比我更好地解释这一点,但我将在这里简要讨论并举一个例子。
为什么使用 Curses 而不是 ANSI 转义?
If you read the above text, you might recall that \e
or \x1b
will sometimes work with printf
. Well, sometimes \e
and \x1b
will not work at all (this is not standard and I have never worked with a terminal like this, but it is possible). More importantly, more complex escape sequences (think Home and other multi-character keys) are difficult to support for every terminal (unless you are willing to spend a lot of time and effort parsing terminfo and termcap and and figuring out how to handle every terminal).
诅咒解决了这个问题。基本上,它能够使用这些方法了解终端具有哪些功能(如上面链接的维基百科文章所述):
Curses 的大多数实现都使用可以描述数千种不同终端功能的数据库。有一些实现,例如 PDCurses,它使用专门的设备驱动程序而不是终端数据库。大多数实现使用 terminfo;有些使用 termcap。 Curses 具有可向后移植到字符单元终端且简单的优点。对于不需要位图图形或多种字体的应用程序,使用curses 的界面实现通常比使用X 工具包的界面实现更简单、更快。
大多数时候,curses 会轮询 terminfo,然后能够了解如何操作光标和文本属性。然后,如果您需要所需的功能,您(程序员)可以使用 Curses 提供的 API 来操作光标或更改文本颜色或其他属性。
使用 Python 的示例
我发现 python 确实很容易使用,但如果你想在不同的编程语言中使用curses,那么只需在duckduckgo 或任何其他搜索引擎上搜索它即可。 :) 这是 python 3 中的一个简单示例:
import curses
def main(stdscr):
# allow curses to use default foreground/background (39/49)
curses.use_default_colors()
# Clear screen
stdscr.clear()
curses.init_pair(1, curses.COLOR_RED, -1)
curses.init_pair(2, curses.COLOR_GREEN, -1)
stdscr.addstr("ERROR: I like tacos, but I don't have any.\n", curses.color_pair(1))
stdscr.addstr("SUCCESS: I found some tacos.\n", curses.color_pair(2))
stdscr.refresh() # make sure screen is refreshed
stdscr.getkey() # wait for user to press key
if __name__ == '__main__':
curses.wrapper(main)
result:
You might think to yourself that this is a much more round-about way of doing things, but it really is much more cross-platform (really cross-terminal … at least in the unix- and unix-like-platform world). For colors, it is not quite as important, but when it comes to supporting other multi-sequence escape sequences (such as Home, End, Page Up, Page Down, etc), then curses becomes all the more important.
Tput 示例
-
tput
是一个用于操作光标和文本的命令行实用程序
-
tput
附带curses
包裹。如果您想在终端中使用跨终端 (ish) 应用程序,您应该使用 tput,因为它会解析 terminfo 或它需要的任何内容,并使用一组标准化命令(如curses)并返回正确的转义序列。
- example:
echo "$(tput setaf 1)$(tput bold)ERROR:$(tput sgr0)$(tput setaf 1) My tacos have gone missing"
echo "$(tput setaf 2)$(tput bold)SUCCESS:$(tput sgr0)$(tput setaf 2) Oh good\! I found my tacos\!"
Result:
有关 Tput 的更多信息
- see: http://linuxcommand.org/lc3_adv_tput.php看看 tput 是如何工作的
- see: http://invisible-island.net/ncurses/man/terminfo.5.html查看可以使用的命令列表