起因
近来,翻看gin源码时,无意间看到了green = "\033[97;42m"这种不明所以的代码,遂充满疑惑和好奇,于是就搜索探究了一番,这才知道这叫ANSI转义序列。
ANSI转义序列
简单说,就是一种标准化的终端控制序列,用于设置文本样式、颜色和背景等。先放个代码吧,以免不知所云。
|
|
语法
整体的语法为:
|
|
-
ESC:ESC转义字符,固定为\033(八进制)或\x1b(十六进制),告诉终端后面的内容是控制序列 -
控制序列:有不同分类,一般为序列内容+命令字符的形式,具体语法后面再细说
支持情况
大多数终端都支持ANSI转义序列,但不包括windows平台默认配置的命令提示符和PowerShell(也许通过某些配置后是支持的,未深究)。
虽然大多数终端都支持,但支持的情况也是有差异的,即:
-
有些终端只支持某一部分的
ANSI转义序列,其它则不支持 -
对于同一
ANSI转义序列,不同终端的表现形式可能不同
分类
| 分类 | 语法 | 说明 |
|---|---|---|
| CSI序列 | ESC[+参数序列+命令字符 |
用于控制光标、颜色、屏幕等 |
| 直接控制 | ESC+命令字符 |
用于简单控制 |
| OSC命令 | ESC]+命令字符+参数+终止符 |
用于操作系统控制 |
| 私有模式控制 | ESC[?+参数序列+命令字符 |
用于配置终端的独有功能(通常由终端制造商或特定标准扩展) |
注意:
-
参数序列若有多个参数,用;进行分隔 -
命令字符区分大小写 -
终止符仅OSC命令有,固定为\007或\033\\
CSI序列
该分类应该是最常用的。
| 命令字符 | 功能 | 示例 |
|---|---|---|
| A | 光标上移 | \033[5A上移5行 |
| B | 光标下移 | \033[3B下移3行 |
| C | 光标右移 | \033[10C右移10列 |
| D | 光标左移 | \033[2D左移2列 |
| E | 光标下移并到行首 | \033[1E下移1行到行首 |
| F | 光标上移并到行首 | \033[1F上移1行到行首 |
| G | 光标水平绝对定位 | \033[10G移动到第10列 |
| H | 光标定位 | \033[2;10H第2行第10列 |
| J | 擦除屏幕 | \033[2J清屏 |
| K | 擦除行 | \033[K清除到行尾 |
| S | 向上滚动 | \033[5S上滚5行 |
| T | 向下滚动 | \033[3T下滚3行 |
| m | 图形样式 | \033[1;31m红色粗体 |
| n | 设备状态报告 | \033[6n查询光标位置 |
| s | 保存光标位置 | \033[s |
| u | 恢复光标位置 | \033[u |
| f | 同H(光标定位) |
\033[2;10f |
其中m即图形样式,应该是用得最多的。
图形样式
语法:\033[参数序列m
| 参数 | 效果 | 说明 |
|---|---|---|
| 0 | 重置所有属性 | 下面要介绍的文本属性和颜色的设置,在设置完之后将一直生效,通常需要在末尾加上\033[0m来恢复到默认设置 |
文本属性
- 语法:
\033[单一参数m
| 参数 | 效果 | 重置参数 |
|---|---|---|
| 1 | 加粗/高亮 | 22 |
| 2 | 弱化/暗淡 | 22 |
| 3 | 斜体 | 23 |
| 4 | 下划线 | 24 |
| 5 | 慢闪烁 | 25 |
| 6 | 快闪烁 | 26 |
| 7 | 反色 | 27 |
| 8 | 隐藏 | 28 |
| 9 | 删除线 | 29 |
| 21 | 双下划线 | |
| 53 | 单上划线 | |
| 73 | 上标 | |
| 74 | 下标 |
文本颜色
16色模式
- 语法:
\033[单一参数m
| 16色颜色 | 参数 | 效果 | 参数 | 效果 |
|---|---|---|---|---|
| 标准黑 | 30 | 前景色 | 40 | 背景色 |
| 标准红 | 31 | 前景色 | 41 | 背景色 |
| 标准绿 | 32 | 前景色 | 42 | 背景色 |
| 标准黄 | 33 | 前景色 | 43 | 背景色 |
| 标准蓝 | 34 | 前景色 | 44 | 背景色 |
| 标准品红 | 35 | 前景色 | 45 | 背景色 |
| 标准青 | 36 | 前景色 | 46 | 背景色 |
| 标准白 | 37 | 前景色 | 47 | 背景色 |
| 亮灰 | 90 | 前景色 | 100 | 背景色 |
| 亮红 | 91 | 前景色 | 101 | 背景色 |
| 亮绿 | 92 | 前景色 | 102 | 背景色 |
| 亮黄 | 93 | 前景色 | 103 | 背景色 |
| 亮蓝 | 94 | 前景色 | 104 | 背景色 |
| 亮品红 | 95 | 前景色 | 105 | 背景色 |
| 亮青 | 96 | 前景色 | 106 | 背景色 |
| 亮白 | 97 | 前景色 | 107 | 背景色 |
256色模式
-
前景色语法:
\033[38;5;颜色代码m -
背景色语法:
\033[48;5;颜色代码m
其中,颜色代码
-
0~15:标准16色 -
16~231:6 × 6 × 6的RGB立方(即36×R + 6×G + B + 16,R/G/B∈[0,5],最后的16为偏移) -
232~255:24级灰度(232=黑,255=白,即g + 232,g∈[0,23],最后的232为偏移)
24位RGB真彩色
前景色语法:\033[38;2;R;G;Bm(R/G/B∈[0,255])
背景色语法:\033[48;2;R;G;Bm(R/G/B∈[0,255])
直接控制
| 命令字符 | 功能 | 示例 |
|---|---|---|
| 7 | 保存光标位置 | \0337 |
| 8 | 恢复光标位置 | \0338 |
| D | 向下滚动一行 | \033D |
| M | 向上滚动一行 | \033M |
| E | 换行并回车 | \033E |
| c | 重置终端 | \033c完全重置终端 |
OSC命令
| 命令字符 | 功能 | 示例 | 说明 |
|---|---|---|---|
| 0 | 修改窗口标题 | \033]0;My Title\007 |
|
| 1 | 修改图标名称(少用) | \033]1;Icon Name\007 |
|
| 2 | 同 0(修改标题) | \033]2;New Title\007 |
|
| 4 | 修改调色板颜色 | \033]4;1;rgb:FF/00/00\007(红) |
使用\033]4;颜色索引;default\007恢复默认 |
| 8 | 创建超链接 | \033]8;;https://example.com\033\\点击\033]8;;\033\\ |
必须使用\033]8;;\033\\终止 |
| 10 | 修改默认前景色(文本) | \033]10;rgb:FF/00/00\007(红色) |
|
| 11 | 修改默认背景色 | \033]11;rgb:00/00/80\007(深蓝) |
|
| 12 | 修改光标颜色 | \033]12;rgb:FF/FF/00\007(黄色) |
|
| ? | 查询状态 | \033]10;?\007查询前景色 |
总结
ANSI转义序列可以让终端的输出变得更漂亮,更像GUI,而且只是针对终端的一个标准,任何可编写终端应用的语言都可以使用。
想当初刚学完c作为练手写的终端小游戏汉诺塔,若是当时掌握了这个知识点,展示效果绝对要上一个档次。
虽然ANSI转义序列很酷,但写起来还是太啰嗦了,而且代码看起来也更乱,但果然还是封装一下再用会比较舒服,比如:fatih/color就是一个跨平台兼容性更好的设置终端颜色的库,与ANSI转义序列的颜色部分类似。