在尝试开发一个控制台程序的时候,接触到了控制台转义字符(Escape Code),可以用于控制光标或达到一些特殊显示效果,比如lolcat
.
趁此机会,记录一下这些操作.
CSI序列
CSI(Control Sequence Introducer)是一系列控制控制台下特殊效果的代码序列, 它们以ESC[
开始,后接不同的控制参数.ESC
字符即ASCII
值27
,可以用如下方式得到:
\e
1
echo -e "hello, \e[31mworld\e[0m"
\033
1
echo -e "hello, \033[31mworld\033[0m"
\x1b
1
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)