跳到主要内容
ansicode

SGR 30–37 — 前景色(8 种基础色)

将前景色设置为 黑/红/绿/黄/蓝/品红/青/白 中的一种。

字节形式

涵盖所有常见的字符串字面量写法,方便正反查找。

\\x1b[\x1b[31m (red, similarly 30–37)
\\033[\033[31m
\\e[\e[31m
ESC [ESC [ 3 1 m
hex1b 5b 33 31 6d

实时预览

在浏览器中通过与解码器相同的分词器渲染 —— 无需打开终端。

30–37

说明

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默认前景色

示例

bash
for c in 30 31 32 33 34 35 36 37; do printf "\033[${c}m■\033[0m"; done; echo
python
for c in range(30, 38): print(f'\x1b[{c}m{c}\x1b[0m', end=' ')
go
for c := 30; c <= 37; c++ { fmt.Printf("\x1b[%dm%d\x1b[0m ", c, c) }
javascript
for (let c = 30; c <= 37; c++) process.stdout.write(`\x1b[${c}m${c}\x1b[0m `)
c
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
支持

相关序列

在家族食谱中

SGR 食谱 · 2. 基础 16 色 —— `\x1b[31m` 那一票