跳到主要内容
ansicode

C1 控制字符 —— ESC 序列的 8 位单字节等价形式(0x80–0x9F)

8 位 C1 控制字节(0x80..0x9F)—— CSI、OSC、ST、DCS、NEL、HTS、IND、RI —— 及其 7 位 ESC <letter> 等价形式。

字节形式

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

\\x1b[\x9b CSI \x9d OSC \x9c ST \x90 DCS \x85 NEL \x88 HTS \x84 IND \x8d RI
\\033[\233 / \235 / \234 / \220 / \205 / \210 / \204 / \215
\\e[(no \e form — these are single 8-bit bytes; use the 7-bit ESC equivalents below)
ESC [ESC [ ≡ CSI / ESC ] ≡ OSC / ESC \\ ≡ ST / ESC P ≡ DCS / ESC E ≡ NEL / ESC H ≡ HTS / ESC D ≡ IND / ESC M ≡ RI
hex9b / 9d / 9c / 90 / 85 / 88 / 84 / 8d

说明

C1 控制集占据 0x80..0x9F 字节范围,为最常用的 ESC <letter> 序列提供单字节替代形式。完整集合:IND(0x84,ESC D —— 不带 CR 的换行)、NEL(0x85,ESC E —— CR+LF)、HTS(0x88,ESC H —— 在当前列设置 tab 停位)、RI(0x8D,ESC M —— 反向换行,到顶时滚动)、SS2(0x8E,ESC N —— 对下一字符使用 G2 字符集单次切换)、SS3(0x8F,ESC O —— 单次切换 G3)、DCS(0x90,ESC P —— 设备控制串引导符)、CSI(0x9B,ESC [ —— 控制序列引导符,最常用)、ST(0x9C,ESC \\ —— 用于 DCS / OSC / APC / PM / SOS 的串终止符)、OSC(0x9D,ESC ] —— 操作系统命令引导符)、PM(0x9E,ESC ^ —— 隐私消息)、APC(0x9F,ESC _ —— 应用程序命令,Kitty 图形协议在用)。现代终端请避免使用 8 位形式0x80..0x9F 中的每个字节都是 UTF-8 的*续字节*(前导比特模式 10xxxxxx),UTF-8 流中出现一个孤立的 0x9B 要么被当作非法序列的一部分吸收,要么被静默丢弃。请始终使用 7 位 ESC <letter> 形式(\x1b[\x1b]\x1b\\ 等)—— 在 UTF-8、ASCII、Latin-1 下都是无歧义的,所有终端都识别。8 位 C1 集主要出现在遗留场景中(处于 S8C1T 模式的 DEC VT220、ISO 8859-1 字节流归档、老 VT100 固件测试向量)。

规范出处: ECMA-48 §5.2 (C1 set) / ISO 6429

参数

IND (0x84, ESC D)索引 —— 光标下移 1(无 CR 的 LF);位于区域底部时滚动
NEL (0x85, ESC E)下一行 —— CR + LF 合一
HTS (0x88, ESC H)水平制表设置 —— 在当前光标列设 tab 停位
RI (0x8D, ESC M)反向索引 —— 光标上移 1;位于区域顶部时滚动
SS2 (0x8E, ESC N)单次切换 G2 —— 仅对下一字符使用 G2 字符集
SS3 (0x8F, ESC O)单次切换 G3 —— 仅对下一字符使用 G3 字符集
DCS (0x90, ESC P)设备控制串引导符 —— 由 ST 终止
CSI (0x9B, ESC [)控制序列引导符 —— 最常用
ST (0x9C, ESC \\)串终止符 —— 关闭 DCS / OSC / APC / PM / SOS
OSC (0x9D, ESC ])操作系统命令 —— 由 ST 或 BEL 终止
PM (0x9E, ESC ^)隐私消息 —— 由 ST 终止
APC (0x9F, ESC _)应用程序命令 —— 由 ST 终止(Kitty 图形协议在用)

示例

bash
# 7-bit (preferred — UTF-8 safe):\nprintf '\033[31mred\033[0m'\nprintf '\033]0;new window title\033\\\\'\n# 8-bit C1 (legacy — breaks under UTF-8):\nprintf '\x9b31mred\x9b0m'   # only works if terminal is in 8-bit mode + Latin-1
python
# Prefer 7-bit ESC form:\nimport sys; sys.stdout.write('\x1b[31mred\x1b[0m')\n# 8-bit C1 — fails on UTF-8 stdouts:\n# sys.stdout.buffer.write(b'\x9b31mred\x9b0m')
go
// 7-bit ESC form (UTF-8 safe):\nfmt.Print("\x1b[31mred\x1b[0m")\n// 8-bit C1 — emits two UTF-8 continuation bytes interpreted as garbage:\n// os.Stdout.Write([]byte{0x9b, '3','1','m'})
javascript
process.stdout.write('\x1b[31mred\x1b[0m');\n// process.stdout.write(Buffer.from([0x9b, 0x33, 0x31, 0x6d]))  // breaks UTF-8
c
/* 7-bit ESC form: */\nprintf("\x1b[31mred\x1b[0m");\n/* 8-bit C1 — only safe on Latin-1 / explicit 8-bit terminals: */\n/* fputc(0x9b, stdout); fputs("31m", stdout); */

在哪里用到

实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。

  • telnet, tn5250, x3270 (mainframe / AS-400 emulation)8 位 IBM 5250 / 3270 数据流把 CSI 当作单字节 `\x9b` 发送,而非 `\x1b[`
  • minicom, picocom (8-bit serial sessions)8 位 VT220 时代的硬件终端直接发原始 C1 字节——CSI 用 `\x9b`、DCS 用 `\x90`、OSC 用 `\x9d`
  • luit (X11 locale filter)locale → UTF-8 包装器,在转发给模拟器前把进入的 C1 字节归一为 `ESC <Fe>` 的 7 位等价形态
  • GNU screen — accepts incoming C1 bytes and re-emits the 7-bit form on UTF-8 PTYs
  • kermit, lrzsz file-transfer protocols传统 8 位终端链路上,帧字节与 C1 范围重叠

常见问题

针对这条序列,开发者真正会去搜索的问题的简短回答。

什么时候该发 C1 CSI \x9b 而不是 \x1b[
现代 UTF-8 终端上几乎从不用。字节 0x9B 是合法的 UTF-8 续字节,与任何恰好含此字节的多字节字符灾难性冲突 —— 你的 CSI 引导字符被当作非法 UTF-8 序列的一部分吞掉,参数渲染成普通文字。7 比特形式 \x1b[(ESC [)全网通用,跨编码(UTF-8、Latin-1、ASCII)都能存活。仅在确定通道是 8 比特干净且非 UTF-8(如显式启用 S8C1T 的部分遗留串口 / DEC VT510 设置)时才发 8 比特 C1。
为什么 Linux 控制台对 C1 的处理和 xterm 不一致?
Linux fbcon 默认采用 S7C1T 模式(仅 7 比特 C1 传输),把 0x800x9F 的原始字节当作所载字体的图形字符,而非 C1 控制码。xterm 默认是 S8C1T-aware:把 0x9B 解析为 CSI,0x9D 为 OSC,0x90 为 DCS 等。可移植的选择是始终发 7 比特等价形式(ESC [ESC ]ESC P)—— 两边都能用。若确实想知道终端处于哪种模式,用 DECRQM 查询模式 66(S7C1T/S8C1T 选择)—— 但答案多半是个冷知识;直接发 7 比特就好。

终端支持

xterm
部分
Linux console (fbcon)
不支持
macOS Terminal.app
不支持
iTerm2
不支持
Windows Terminal
不支持
cmd.exe / ConPTY
不支持
kitty
不支持
alacritty
不支持
WezTerm
不支持
Ghostty
不支持
GNOME Terminal
不支持
Konsole
不支持
tmux
支持
GNU screen
支持

相关序列

在家族食谱中

ESC 食谱 · 5. 锁定切换与 8 位 C1 桥 —— `\x1bn` / `\x1bo` / `\x1b|` 与 `\x80-\x9F`