SGR 转义码 —— 颜色与文本属性
Select Graphic Rendition。`ESC [ … m` 这一族 —— 终端中所有上色、加粗、斜体、下划线、闪烁、反相、删除线等文本样式属性的编码。是 ANSI 字母表中最庞大、也最常被检索的角落。
24 条序列
颜色食谱 —— 六步把整族读透
SGR 是 ANSI 字母表里最庞大的一支 —— 凡是给字形上色或加修饰的转义码全在这里。下面六步从浅入深读一遍,就能把整族吃透:怎么收尾、原始 16 色、256 索引调色板、24-bit 真彩色、用 OSC 临时换色,以及标准党更爱的冒号子参数写法。
1. 一键归零 ——
\x1b[0m每一段彩色文本都用
\x1b[0m收尾。它会把上次 SGR 打开的 fg + bg + 全部修饰位(粗体、斜体、下划线之类)一次清零。漏写就会让颜色渗到下一行 prompt、shell 的PS1、甚至你 pipe 进去的文件里去。把它当作每段彩色输出的「闭括号」。\x1b[m(空参数)按 ECMA-48 是一样的意思,但实际工具几乎清一色写\x1b[0m。2. 基础 16 色 ——
\x1b[31m那一票ECMA-48 时代的原始调色板:30–37 选 8 个前景色(黑、红、绿、黄、蓝、品红、青、白),40–47 选对应背景色。再加
1;就是加粗 —— 很多终端在加粗的同时让颜色变亮,所以\x1b[1;31m比\x1b[31m更红。亮色也可以直接用 90–97(前景)和 100–107(背景)—— 多出来的 8 槽不必依赖加粗。39 / 49 是配套的「默认 fg」与「默认 bg」复位码,需要把颜色还原又想保留 bold / italic 时正好用得上。3. 256 索引色 ——
\x1b[38;5;n mxterm-256color 调色板:0–15 镜像 16 个基础/亮色;16–231 是 6×6×6 RGB 立方体(每档取 0、95、135、175、215、255,不是线性 0–255);232–255 是 24 级灰度,从近黑到近白。要橙色就
\x1b[38;5;208m,要中灰就\x1b[38;5;244m。38是前景、48是背景,其余写法完全一致。除非是 1995 年前的老 console,几乎所有终端都支持 —— 连 ssh 套screen或tmux也吃得动,只要里层$TERM是xterm-256color/screen-256color/tmux-256color之一。4. 真彩色 ——
\x1b[38;2;r;g;b m256 不够用时上 24-bit RGB。
\x1b[38;2;255;128;0m精确画出#FF8000橙色;\x1b[48;2;30;30;30m给一个近黑背景。现代终端(kitty、alacritty、wezterm、iTerm2、Windows Terminal、gnome-terminal ≥ 3.20、konsole、ghostty)全都支持。运行时探测最稳的是看$COLORTERM环境变量 —— 等于truecolor或24bit就放心发 RGB;为空就退化到最接近的 256 索引槽。光看$TERM不靠谱:xterm-256color并不意味着支持真彩色,反过来很多终端$TERM只是普通的xterm但仍然把$COLORTERM设了。5. OSC 调色板覆盖 —— 直接把槽位本身改了
严格来说这是 OSC,不是 SGR —— 但「我那个红能不能调好看一点」的读者大多落在这里。
OSC 4 ; n ; rgb:RR/GG/BB ST临时覆盖调色板第n槽(0–255)。所以\e]4;1;rgb:e0/3a/3a\e\\就重调了\x1b[31m用的红。配合OSC 10改默认前景、OSC 11改默认背景;再用OSC 104 ; n ST把第n槽恢复成出厂值,或者干脆OSC 104 ST(不带参数)一次恢复全部。给 TUI 做主题切换很好用,不用逼用户改终端配置。6. SGR 冒号子参数 —— 真正符合标准的写法
ECMA-48 规定子参数分隔符是冒号(
:)而不是分号 ——38:2::r:g:b才是标准里的 truecolor 写法(2与r之间空着的那一格是色彩空间 ID,通常省略)。多数终端两种都吃(xterm 历史遗留),但 wezterm、kitty、foot、Linux 内核 console 在新的 SGR 扩展里只认冒号形式 —— 比如下划线颜色。举一个 21 世纪的例子:要在默认色文字下画一条红色波浪下划线就是\x1b[4:3m\x1b[58:2::255:0:0m。4:3开启卷曲下划线,58:2::r:g:b把下划线颜色独立于前景色设定。看到 SGR 解析器行为「怪怪的」时,记得它可能就栽在分号/冒号这里。
本家族的全部序列
- SGR 0 — 重置 / 恢复默认
\x1b[0m清除所有文本属性和颜色,恢复终端默认状态。
- SGR 1 — 加粗 / 高亮
\x1b[1m将后续文本渲染为加粗(在某些终端上为高亮色)。
- SGR 2 — 暗淡 / 减弱
\x1b[2m以降低亮度(faint/暗淡)渲染后续文本。
- SGR 5 — 闪烁(慢速)
\x1b[5m使后续文本闪烁(≤ 150 次/分钟)。
- SGR 8 — 隐藏 / 不可见
\x1b[8m将后续文本渲染为不可见(光标仍前进)。
- SGR 9 — 删除线
\x1b[9m在后续文本中央绘制一条水平删除线。
- SGR 39 — 默认前景色
\x1b[39m仅重置前景色(保留其他属性与背景色)。
- SGR 49 — 默认背景色
\x1b[49m仅重置背景色(保留其他属性与前景色)。
- SGR 48;5;n — 256 色背景
\x1b[48;5;Nm从 xterm 256 色调色板中选择背景色。
- SGR 48;2;R;G;B — 24 位真彩色背景
\x1b[48;2;R;G;Bm直接指定 16,777,216 种 RGB 背景色之一。
- SGR 3 — 斜体
\x1b[3m将后续文本渲染为斜体;并非所有终端都支持。
- SGR 4 — 下划线
\x1b[4m为后续文本添加下划线。
- SGR 7 — 反相显示
\x1b[7m交换前景色与背景色。
- SGR 30–37 — 前景色(8 种基础色)
\x1b[31m (red, similarly 30–37)将前景色设置为 黑/红/绿/黄/蓝/品红/青/白 中的一种。
- SGR 40–47 — 背景色(8 种基础色)
\x1b[41m (red bg, 40–47)将背景色设置为 黑/红/绿/黄/蓝/品红/青/白 中的一种。
- SGR 90–97 — 高亮前景色
\x1b[91m (bright red, 90–97)8 种基础前景色的高亮变体(aixterm/xterm 扩展)。
- SGR 100–107 — 高亮背景色
\x1b[101m (bright red bg, 100–107)8 种基础背景色的高亮变体。
- SGR 38;5;n — 256 色前景
\x1b[38;5;Nm从 xterm 256 色调色板中选择前景色。
- SGR 38;2;R;G;B — 24 位真彩色前景
\x1b[38;2;R;G;Bm直接指定 16,777,216 种 RGB 前景色之一。
- SGR 21 — 双下划线
\x1b[21m为文本添加双下划线 —— 与单下划线(SGR 4)不同。
- SGR 53 — 上划线
\x1b[53m在字形上方绘制一条线 —— 与下划线相对。使用 SGR 55 关闭。
- SGR 26 — 比例间距(ECMA-48 定义;常见终端均忽略)
\x1b[26mECMA-48 把它定义为「启用比例间距」—— 但所有常见终端都不实现。记录这一陷阱。
- SGR 冒号子参数 — ITU-T T.416 替代写法(38:2:: / 48:2:: / 38:5:)
\x1b[38:2::255:128:64m (T.416) \x1b[38;2;255;128;64m (xterm-legacy)在扩展颜色子参数之间使用 `:`(0x3a)代替 `;`(0x3b)—— 规范认可的写法,可消除复合 SGR 与独立 SGR 的歧义。
- SGR 73 / 74 / 75 —— 上标 / 下标 / 取消
\x1b[73m superscript \x1b[74m subscript \x1b[75m neitherMintty 的上标 / 下标 SGR 对,现已被 Kitty 0.32+、WezTerm、foot 与 iTerm2 实现。是终端输出能不靠特殊字符排出数学、脚注与化学式的第一组 SGR。