命令行使用ANSI实现彩色样式输出—CLI程序美化教程(二)
0x00 引言
虽然命令行程序使用文字来展示,但在使用得当的情况下也可以有着独特且不输于图形界面程序的交互与使用体验。
而实现这种效果就需要用到ANSI转义代码。本文章从自定义样式输出开始介绍ANSI转义代码的用法与应用。
0x01 什么是ANSI
ANSI转义代码(ANSI Escape Code,也被称为 VT100。以下为了方便简称为 ANSI)
是一种在文本终端中控制格式、颜色和其他输出选项的代码。这些代码允许开发者在终端中创建丰富多彩的文本界面,提高用户体验。
通过使用ANSI,可以摆脱传统CLI程序的逐行输出纯文本的交互模式,构建动态与彩色的命令行界面。
设置文本颜色和样式是ANSI标准中定义的一个功能,本篇文章中我们先来了解这一部分的功能。
0x02 认识ANSI控制序列
要使用ANSI,我们只需要向输出正常文字一样像控制台额外输出,或在原来的文字前追加一串特殊字符即可。
比如说这样:
1 | \033[4;34mHello,\033[0;3;32mWorld! |
输出以上的文字,在控制台的效果为带下划线蓝色的 Hello, 和斜体绿色的 World!。
看不懂是正常的,我当时初见这玩意的时候也是很懵逼。但实际上,这个控制序列实际上并不难理解。
以上的示例中,去除实际输出的文字,还剩下两个部分,这就是两个控制序列。
它们分别是 \033[4;34m 和 \033[0;3;32m 。我们先来看第一个,它可以分为以下的三个部分:
前缀:\033[
这是ANSI转义序列的开始标识。任何一个ANSI转义序列都由 \033[ 开头。
\033 是ASCII码为27的字符 ESC 的转义。你也可以使用 \x1b 和 \e 代替 \033。
中间:4;34
这是使用分号分割的参数列表,它决定了这个转义序列具体的功能的参数。
在这个例子中,4 代表了下划线,34 代表了蓝色,且是按照从左到右的顺序依次生效的。
后缀:m
这是转义序列的功能标识,使用一个字符表示。它决定了这个转义序列的具体功能。
m 字符代表的功能是 Select Graphic Rendition (SGR),即设定渲染样式,可以设置文字的颜色和各种样式。
所以说,这整个转义序列的作用即为 使用设定样式功能,设置样式4,再设置样式34,
这相当于在告诉终端:为后面的文字添加下划线,再设置为蓝色。
0x03 样式的叠加和重置
值得注意的是,使用ANSI设置的样式默认是对其后面所有文字生效的。如果要重新设置样式,就需要重置样式。
重置样式非常简单,只需要使用 0 作为参数即可。你可以理解为 0 代表了 重置所有样式 的样式。
在上面的例子的第二部分中,我们使用了 \033[0;3;32m 转义序列,
可以看到在样式参数列表开头有 0 参数,用来重置前面设置的下划线和蓝色样式。
所以,这个转义序列的作用即为 使用设定样式功能,设置样式0,再设置样式3,再设置样式32,
这相当于在告诉终端:先重置前面设置的所有参数,再设置为斜体,最后设置为绿色。
实际上,单独使用
\033[m实际上和\033[0m在大多数终端中是完全等效的,
不过明确写上 0 会让代码的语义更为严谨。
0x04 构建ANSI控制序列
知道了上面的知识,我们就可以开始使用ANSI实现自己想要的样式输出了。
只需要查表获取想要的样式对应的参数,再按照顺序使用 ; 拼接,最后在前面加 \033[,在后面加 m 即可。
以下是常用的样式和颜色表,完整列表可以在维基百科
查询。
0x05 常用样式表
| 参数 | 作用 | 注释 |
|---|---|---|
| 0 | 重置所有样式 | |
| 1 | 设置为粗体或深色 | 具体样式取决于具体环境 |
| 2 | 设置为细体或浅色 | 具体样式取决于具体环境 |
| 3 | 设置为斜体 | 某些环境下可能不支持 |
| 4 | 添加下划线 | |
| 5 | 设置为慢速闪烁 | |
| 6 | 设置为快速闪烁 | 某些环境下可能不支持 |
| 7 | 调换文字前后景颜色 | |
| 8 | 隐藏文字 |
0x06 常用颜色表
| 参数 | 作用 | 注释 |
|---|---|---|
| 30-37 | 设置文字颜色为基础颜色的某一个 | 从30-37分别为:黑,红,绿,黄,蓝,品红,青,白 |
| 40-47 | 设置文字背景颜色为基础颜色的某一个 | 从40-47分别如上 |
| 38;5;n | 设置文字颜色为256色表的第n个 | 色表见下 |
| 48;5;n | 设置文字背景颜色为256色表的第n个 | 色表见下 |
| 38;2;r;g;b | 设置文字颜色为rgb | |
| 48;2;r;g;b | 设置文字背景颜色为rgb |
256色表
0x07 示例
以下是一个使用ANSI实现彩色输出的示例:
1 | void main() { |
实际上,在部分语言中,可能对于样式输出有更为友好的封装库(例如Java中的Jansi,Python中的Colorama等),
这些库在底层也是使用ANSI转义序列实现的,但提供了更为简洁和易用的接口来设置样式和颜色。
0x08 总结
通过在输出字符串中嵌入这些简单的转义序列,我们就可以打破传统黑白终端的限制,
为命令行程序赋予更直观的信息层级(例如用红色高亮错误日志,用绿色高亮成功提示)和丰富的美感。
在使用ANSI的时候,有几点需要特别注意:
- 首先要始终记得重置样式。在每段彩色文本输出完毕后,务必养成加上
\033[0m的好习惯。如果不重置,设置的颜色和样式可能会污染后续输出。 - 其次是兼容性考量。绝大多数现代终端都已完美支持 ANSI 和 RGB 真彩色。
但在较老的 Windows 系统中可能无法正常解析,会输出乱码字符。 这种情况下直接调用成熟的库(如 Jansi)会是更好的选择。
虽然这篇文章主要介绍ANSI的样式输出功能,但ANSI的功能远不止于此。
它还可以实现光标控制、屏幕清除、输入控制等功能,这些功能可以帮助我们构建更为复杂和动态的命令行界面。
在(有可能的)后续文章中,我们将继续介绍这些功能,并给出一些实用的示例。
END.







