在尝试开发一个控制台程序的时候,接触到了控制台转义字符(Escape Code),可以用于控制光标或达到一些特殊显示效果,比如lolcat.
趁此机会,记录一下这些操作.
CSI序列
CSI(Control Sequence Introducer)是一系列控制控制台下特殊效果的代码序列, 它们以ESC[开始,后接不同的控制参数.ESC字符即ASCII值27,可以用如下方式得到:
\e1
echo -e "hello, \e[31mworld\e[0m"
\0331
echo -e "hello, \033[31mworld\033[0m"
\x1b1
echo -e "hello, \x1b[31mworld\x1b[0m"
以上三种方式完全一致,都是输出普通颜色的hello和红色的world.
顺带一提, 我测试过的语言中,只有C/C++支持\e转义方式.其他语言可以使用八进制或16进制的转义方式实现.一些语言默认使用了16位宽字符,可以用\u实现.
如Go语言:
1 | fmt.Println("hello, \033[31mworld\033[0m") |
Java的字符串转义没有\x:
1 | System.out.println("\033[31mhello, \033[0m world!"); |
CSI有很多有趣的控制命令, 如echo -e "\e[?25l"可以隐藏光标, echo -e "\e[H\e[0J"会将光标移动至屏幕左上角并清空屏幕,也就是相当于一次clear.
CSI用于控制显示效果的序列被称为SGR(Select Graphic Rendition),主要包括字体样式和颜色的设置,代码为CSI n m.其中,n为不同的数字代码,例如上面例子中的\e[31m就是设置颜色为红色.n可以同时有多个,以;隔开.
终端以状态机的形式设置这些效果,所以\e[31m设置了红色以后,整个终端的输出会一直编是红色,直到另一个效果覆盖了它,或者这个效果被取消.
字体样式
这里的字体样式是指诸如粗体,斜体,下划线这些显示效果,而不是设置如宋体,Consolas这些字体.
效果如下:
| Code | Desc | Preview |
|---|---|---|
| 1 | 粗体(Bold/Bright) | ![]() |
| 2 | 黯淡(Dim/Faint) | ![]() |
| 3 | 斜体(Italicized) | ![]() |
| 4 | 下划线(Underline) | ![]() |
| 5 | 闪烁(Blink) | ![]() |
| 7 | 反转前景和背景颜色(Inverse) | ![]() |
| 8 | 隐藏(Invisible/Hidden) | ![]() |
| 9 | 删除线(Strikethrough/Cross-out) | ![]() |
Tips:
如上所说,可以同时设置多种效果
例如
\e[1;3;4;9m可以同时设置粗体,斜体,下划线和删除线粗体和黯淡,下划线和双重下划线分别是同一类样式,会互相覆盖
隐藏不是不显示内容
隐藏效果其实只是让文字的前景色和背景色一样,这段文字还是可以被复制的.
所以千万不要用来用这个效果处理真正敏感的信息,顶多可以用来做一些’反白’的小彩蛋
代码
6在标准和终端实现文档里都没有记录,不过测试后,发现它的效果也是闪烁.这些效果在不同的终端也会有不同的显示效果
例如,
vte下这些效果显示如下:
取消字体样式
如上所说,终端是一个状态机,上面的显示的效果可以由对应的指定取消掉.
| Code | Desc |
|---|---|
| 0 | 恢复默认,即取消所有特殊效果,包括之后会提到的设置颜色 |
| 22 | 取消粗体或黯淡效果 |
| 23 | 取消斜体 |
| 24 | 取消下划线 |
| 25 | 取消闪烁 |
| 27 | 取消发转 |
| 28 | 取消隐藏 |
| 29 | 取消删除线 |
Tips:
基本上,字体样式中的效果代码加上20就是取消这个效果的代码
粗体(
1)和黯淡(2)都使用代码22来取消,下划线(4)和双重下划线(21)都使用代码24来取消虽然,代码
25可以取消代码6的闪烁效果,但是26没有实际效果
颜色设置
8色和16色
| 颜色 | 前景代码 | 背景代码 |
|---|---|---|
| 黑色 | 30 | 40 |
| 红色 | 31 | 41 |
| 绿色 | 32 | 42 |
| 黄色 | 33 | 43 |
| 蓝色 | 34 | 44 |
| 品红(magenta) | 35 | 45 |
| 青色(Cyan) | 36 | 46 |
| 灰色 | 37 | 47 |
| 默认 | 39 | 49 |
16色在8色的基础上,增加了对应的高亮度的颜色
| 颜色 | 前景代码 | 背景代码 |
|---|---|---|
| 灰色 | 90 | 100 |
| 亮红色 | 91 | 101 |
| 亮绿色 | 92 | 102 |
| 亮黄色 | 93 | 103 |
| 亮蓝色 | 94 | 104 |
| 亮品红(magenta) | 95 | 105 |
| 亮青色(Cyan) | 96 | 106 |
| 白色 | 97 | 107 |
这16种颜色在xterm中显示效果如下:
在vte下效果如下:
Tips:
代码
39和49分别用来重置前景和背景色,具体颜色取决于当前终端vscode的颜色取决于当前主题,所以最终效果是不可预期的.例如,这是在
Lichen Light主题下的显示效果:
256色(8-bit)和24位色
256色使用序列38;5;n和48;5;n来设置前景和背景色.n取值为[0,255].
xterm中效果如下:
24位色使用序列38;2;r;g;b和48;2;r;g;b设置前景色和背景色.
1 |
|
xterm中效果如下:
试着在终端下显示图片:
参考资料
Bash tips: Colors and formatting (ANSI/VT100 Control sequences)







