Terminal
Terminal Escape Sequences
ANSI 转义序列与终端颜色输出,涵盖 16 色、256 色和 True Color 模式
概述
ANSI 转义序列(ANSI Escape Sequences)是控制终端文本输出的标准方法,用于设置颜色、样式和光标位置。
基础知识
ANSI 转义序列基础格式
- 转义序列以 ESC 字符开头,写作
\033(八进制)或\e(部分语言支持) - 控制序列引导符 CSI 格式为
\033[或\e[ - 完整格式:
\033[{code}m,其中{code}为 SGR(Select Graphic Rendition)参数 - 结束符
m表示这是一个 SGR 序列 - 示例:
\033[31m设置前景色为红色
16 色基础代码表
标准 8 色(正常亮度):
| 颜色 | 前景码 | 背景码 | 示例(bash) |
|---|---|---|---|
| 黑 | 30 | 40 | \033[30m |
| 红 | 31 | 41 | \033[31m |
| 绿 | 32 | 42 | \033[32m |
| 黄 | 33 | 43 | \033[33m |
| 蓝 | 34 | 44 | \033[34m |
| 品红 | 35 | 45 | \033[35m |
| 青 | 36 | 46 | \033[36m |
| 白 | 37 | 47 | \033[37m |
高亮 8 色(明亮模式):
| 颜色 | 前景码 | 背景码 |
|---|---|---|
| 亮黑 | 90 | 100 |
| 亮红 | 91 | 101 |
| 亮绿 | 92 | 102 |
| 亮黄 | 93 | 103 |
| 亮蓝 | 94 | 104 |
| 亮品红 | 95 | 105 |
| 亮青 | 96 | 106 |
| 亮白 | 97 | 107 |
文本修饰代码
| 代码 | 效果 | 说明 |
|---|---|---|
| 0 | 重置 | 清除所有样式 |
| 1 | 加粗 | 部分终端表现为高亮 |
| 2 | 淡化 | 降低亮度 |
| 3 | 斜体 | 部分终端不支持 |
| 4 | 下划线 | |
| 5 | 慢闪烁 | 多数现代终端不支持 |
| 7 | 反色 | 前景和背景互换 |
| 8 | 隐藏 | 文本不可见 |
| 9 | 删除线 |
进阶模式
ANSI 代码组合使用
- 多个 SGR 代码用分号
;分隔,一次性设置多个属性 - 格式:
\033[{style};{fg};{bg}m - 示例:
\033[1;31;43m表示加粗红色文字、黄色背景 - 顺序不影响最终效果,但习惯上按"样式;前景;背景"排列
- 使用后必须以
\033[0m重置,否则后续所有输出都继承样式
256 色编码逻辑
- 前景色格式:
\033[38;5;{N}m,背景色格式:\033[48;5;{N}m - N 的取值范围 0-255,共 256 个颜色
- 编码分布:
- 0-7:标准 8 色
- 8-15:高亮 8 色
- 16-231:6x6x6 RGB 立方体(共 216 色),计算公式
N = 16 + R*36 + G*6 + B,其中 R/G/B 各取 0-5 - 232-255:灰度渐变(24 级),从近乎黑到近乎白
True Color 模式
- 又称 24-bit Color,支持约 1677 万色
- 前景色格式:
\033[38;2;{R};{G};{B}m - 背景色格式:
\033[48;2;{R};{G};{B}m - R/G/B 各取 0-255,精确对应 RGB 色彩空间
- 与 256 色不同,不需要查表或计算索引
256 色与 True Color 的选择策略
- 256 色兼容性更好,几乎所有现代终端都支持
- True Color 在旧版终端(如 Windows CMD、旧版 iTerm2)可能降级为 16 色
- 生产环境脚本建议优先使用 256 色模式
- True Color 适合 UI 工具库、开发工具等对色彩精度有要求的场景
- 检测终端支持:检查
COLORTERM环境变量,truecolor表示支持 24-bit - 检测 256 色支持:检查
TERM是否包含256color
实践
多语言 ANSI 输出示例
Bash:
echo -e "\033[1;32mSuccess\033[0m"
printf "\e[38;5;208mOrange\e[0m\n"
Node.js:
console.log('\x1b[31mRed text\x1b[0m');
console.log('\x1b[38;5;208mOrange\x1b[0m');
console.log('\x1b[38;2;255;128;0mCustom RGB\x1b[0m');
Python:
print('\033[1;34mBold Blue\033[0m')
print('\033[38;5;196mRed from 256 palette\033[0m')
print('\033[38;2;100;200;150mCustom RGB green\033[0m')
Rust:
println!("\x1b[1;31mBold Red\x1b[0m");
println!("\x1b[38;5;220mYellow from 256\x1b[0m");
ANSI 使用注意事项与兼容性
- 使用
-e参数才能让 bashecho解析转义序列,或使用printf - Windows CMD 默认不支持 ANSI,需要调用
SetConsoleMode启用虚拟终端处理 - Windows Terminal 和 PowerShell 5.1+ 原生支持 ANSI 序列
- 永远以
\033[0m重置样式,避免"颜色泄漏"到后续输出 - 复杂场景建议使用成熟库(如 chalk、colorette、owo-colors)而非手写序列
- ANSI 序列在重定向到文件时会原样写入,可能不适合日志文件
- 使用
$CI环境变量检测 CI 环境,此时应禁用彩色输出