SGR 30–37 — 前景色(8 种基础色)
将前景色设置为 黑/红/绿/黄/蓝/品红/青/白 中的一种。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\x1b[31m (red, similarly 30–37)\033[31m\e[31mESC [ 3 1 m1b 5b 33 31 6d实时预览
在浏览器中通过与解码器相同的分词器渲染 —— 无需打开终端。
说明
8 种基础前景色一一对应 SGR 参数:30 黑、31 红、32 绿、33 黄、34 蓝、35 品红、36 青、37 白。SGR 39 仅将前景色重置为终端默认值,而不影响背景色 —— 是整体 \x1b[0m 重置的精准补集。ECMA-48 §8.3.117 规定了参数范围;上面支持矩阵中的每个终端都完整支持 30–37 + 39,包括 Linux console(在 8 色模式下)和 conhost.exe / ConPTY。实际渲染的 RGB 由主题决定 —— 不存在标准的「ANSI 红」。xterm 默认主题将 31 渲染为 #cd0000;macOS Terminal.app 默认是 #c33720;Solarized 的红是 #dc322f;用户的 xresources / 配置文件可以任意重映射 16 个色槽。需要精确色值的应用必须用 256 色或真彩色,而非基础 31。
移植性陷阱都在环境层,不在解析器层。Linux console / fbcon 上只渲染基础 8 前景色 + 16 背景色 —— \x1b[38;5;Nm(256 色)与 \x1b[38;2;R;G;Bm(真彩色)会被静默量化到 16 色中最近的那个。Linux console 还实现 bold-as-bright(\x1b[1;31m 渲染为亮红,而非「31 红 + 加粗字重」),因此该终端上 SGR 90–97 与 1;3N 完全等价。两个跨环境陷阱常被踩中:(1)shell 脚本不检查 isatty(stdout) 就发 \x1b[31m,当用户管道到 less(不加 -R)或重定向到文件时会漏 ^[[31m 字节 —— 可移植脚本用 tput setaf 1,terminfo 会查 $TERM,在 dumb 或非 TTY 下返回空串;(2)每次换行前与程序退出前都要发 \x1b[0m(或至少 \x1b[39m),否则颜色会污染到用户的命令提示符。无论何时,输出到你不控制的终端都应尊重事实标准 NO_COLOR=1。
关闭前景色用 \x1b[39m —— 精准,不动背景与其他属性。不要为关闭一段彩色就用 \x1b[0m:那会同时抹掉你设置的加粗 / 斜体 / 背景。可访问性方面:颜色要与文本前缀搭配(✓ ok / ✗ failed),让色盲用户也能拿到同样的信号 —— 颜色应当强化信息,绝不能单独承载。需要不依赖主题的精确 RGB 控制,见 sgr-fg-truecolor;需要在大多数多路复用器中存活的 256 色调色板索引,见 sgr-fg-256;对应的背景一侧见 sgr-bg-basic。
规范出处: ECMA-48 §8.3.117 (SGR parameters 30–37, 39)
参数
| 30 | 黑 |
| 31 | 红 |
| 32 | 绿 |
| 33 | 黄 |
| 34 | 蓝 |
| 35 | 品红 |
| 36 | 青 |
| 37 | 白 |
| 39 | 默认前景色 |
示例
for c in 30 31 32 33 34 35 36 37; do printf "\033[${c}m■\033[0m"; done; echofor c in range(30, 38): print(f'\x1b[{c}m{c}\x1b[0m', end=' ')for c := 30; c <= 37; c++ { fmt.Printf("\x1b[%dm%d\x1b[0m ", c, c) }for (let c = 30; c <= 37; c++) process.stdout.write(`\x1b[${c}m${c}\x1b[0m `)for (int c = 30; c <= 37; c++) printf("\x1b[%dm%d\x1b[0m ", c, c);在哪里用到
实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。
- ls --color蓝色 = 目录,绿色 = 可执行,青色 = 符号链接(LSCOLORS 默认)
- grep --color, ripgrep匹配子串显示为红色
- git diff绿色 = 新增行,红色 = 删除行
- gcc, clang红色 = 错误,洋红 = 警告,青色 = 备注
- bash, zsh prompts (PS1)
常见问题
针对这条序列,开发者真正会去搜索的问题的简短回答。
\x1b[31m与\x1b[91m有什么区别?\x1b[31m选基本红(前景 30–37,标准 8 ANSI 色)。\x1b[91m选亮红(前景 90–97,由 aixterm 扩展的第二组 8 色)。许多终端也会把\x1b[1;31m(加粗 + 红)渲染成亮红——是「加粗即亮色」的历史 hack——但 90–97 是无歧义写法,不依赖加粗属性。- 为什么同一个
\x1b[31m在不同终端上一个橙红、一个深红? - 基本 8 色没有标准 RGB 定义——每个终端自带调色板。iTerm2 的 Solarized Dark、macOS Terminal 的 Basic、xterm 的默认、Windows Terminal 的 Campbell 把
31映射到明显不同的红。需要像素精确颜色就改用真彩色(\x1b[38;2;R;G;Bm)——基本 16 色天然受主题控制。 - 怎样尊重
$NO_COLOR并在管道输出到文件时禁用颜色? - 启动时检查两件事:
isatty(stdout)(输出不是终端就跳过着色)和process.env.NO_COLOR(按 [NO_COLOR 非正式标准](https://no-color.org/),任意非空值都表示「禁色」)。两者一起既处理管道(mytool | less)也处理显式关闭。参见no-color误区条目。
终端支持
- xterm
- 支持
- Linux console (fbcon)
- 支持
- macOS Terminal.app
- 支持
- iTerm2
- 支持
- Windows Terminal
- 支持
- cmd.exe / ConPTY
- 支持
- kitty
- 支持
- alacritty
- 支持
- WezTerm
- 支持
- Ghostty
- 支持
- GNOME Terminal
- 支持
- Konsole
- 支持
- tmux
- 支持
- GNU screen
- 支持
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |