跳到主要内容
ansicode

单次切换 / 锁定切换族 —— SS2 / SS3 / LS2 / LS3 / LS1R / LS2R / LS3R

ISO 2022 字符集切换:单次调用 G2 / G3(SS2 / SS3),或将 GL / GR 锁定到不同 G 集(LS2 / LS3 / LS1R / LS2R / LS3R)。与 `\x1b(` / `\x1b)` / `\x1b*` / `\x1b+` G 集指派配对。

字节形式

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

\\x1b[\x1bN SS2 \x1bO SS3 \x1bn LS2 \x1bo LS3 \x1b~ LS1R \x1b} LS2R \x1b| LS3R
\\033[\033N / \033O / \033n / \033o / \033~ / \033} / \033|
\\e[\eN / \eO / \en / \eo / \e~ / \e} / \e|
ESC [ESC N / ESC O / ESC n / ESC o / ESC ~ / ESC } / ESC |
hex1b 4e / 1b 4f / 1b 6e / 1b 6f / 1b 7e / 1b 7d / 1b 7c

说明

ISO 2022 / ECMA-35 字符集机制使用四个寄存器(G0、G1、G2、G3),每个指向一个被指派的字符集;再用两个「指针」(GL 调用 0x20–0x7F、GR 调用 0xA0–0xFF)选定当前生效的 G 集。单次切换与锁定切换族切换这个活跃映射。 **指派**(设定各 G 寄存器指向哪 —— 单独成项,此处仅引:) - `\x1b(<末字节>` —— 指派 G0(如 `\x1b(0` = G0 → DEC Special Graphics 制表线集) - `\x1b)<末字节>` —— 指派 G1 - `\x1b*<末字节>` —— 指派 G2 - `\x1b+<末字节>` —— 指派 G3 **调用**(把 GL / GR 切到指向不同 G 寄存器 —— 本条目): - **SS2** `\x1bN`(`ESC N`)—— *Single Shift 2* —— **紧接的下一个 7 位字节**按 G2 解释,之后 GL 复原。用于无需锁定地插一个字符。 - **SS3** `\x1bO`(`ESC O`)—— *Single Shift 3* —— 同 SS2,但用 G3。注:许多小键盘 / 功能键码(应用模式下的 `\x1bOA` = 上箭头 —— 见 `keymap`)也以 `ESC O` 起始,本质上同样是 SS3。 - **LS2** `\x1bn`(`ESC n`)—— *Locking Shift 2* —— 把 GL 指向 G2,直到下一次切换。后续 7 位字节都过 G2。 - **LS3** `\x1bo`(`ESC o`)—— *Locking Shift 3* —— 把 GL 指向 G3。 - **LS1R** `\x1b~`(`ESC ~`)—— *Locking Shift 1 Right* —— 把 GR 指向 G1(8 位 0xA0–0xFF 流经 G1)。 - **LS2R** `\x1b}`(`ESC }`)—— *Locking Shift 2 Right* —— GR 指向 G2。 - **LS3R** `\x1b|`(`ESC |`)—— *Locking Shift 3 Right* —— GR 指向 G3。 - (LS0 = `\x0F` SI、LS1 = `\x0E` SO 是 C0 单字节控制 —— 见 `c0-controls`。) **实际场合**: 1. DEC 线图 —— `\x1b(0` 指派 G0 → DEC Special Graphics,码 0x6C(`l`)渲染为 `┌`。`ncurses` 在非 UTF-8 终端上常用。 2. 旧主机 / 串线程序,把 7 位「二进制路径」通过 GR 绑定的 G 集穿过会剥 MSB 的中间件。 3. NRCS(国家替换字符集)—— 如 `\x1b)A` 指派 G1 → 英式 NRCS(用 `£` 替 `#`)。 4. Telnet / SSH 的 7 位数据通道选项。 **UTF-8 时代的现实**:ISO 2022 大体上是残留。声明 UTF-8(`\x1b%G` / `\x1b%@` 是 UTF-8 进 / 出对)后的终端通常把输入按 UTF-8 解释、**忽略** SS2/SS3/LS2/LS3。例外是 DEC Special Graphics —— 因 `ncurses` 仍对无完整 Unicode 制表线的终端发 `\x1b(0` 而保活。 **覆盖度**:**xterm** = 完整(标准)。**kitty** / **WezTerm** / **iTerm2** / **Ghostty** / **Konsole**:支持 `\x1b(0` 制表线路径;SS2/SS3/LS2/LS3/LS{1,2,3}R 实现程度参差不齐,但实际用例就是制表线。**gnome-terminal** = 完整。**Alacritty** = 部分(仅 DEC Special Graphics + UTF-8)。**Linux console** = 部分(`\x1b(0` 可用,更冷门的调用器无效)。**Windows Terminal / cmd / ConPTY**:`\x1b(0` 制表线部分支持;右侧锁定切换(`\x1b~`/`\x1b}`/`\x1b|`)无效。**macOS Terminal** = 部分。除非已专门探测,否则别依赖 DEC Special Graphics + 指派以外的任何东西。

规范出处: ISO 2022 / ECMA-35 / xterm-ctlseqs (Single Shift + Locking Shift family)

示例

bash
# DEC line-drawing top-left corner: designate G0 -> SpecGraphics, emit 'l', restore.\nprintf '\\033(0l\\033(B'   # 'l' renders as ┌; \\033(B restores G0 -> US-ASCII
python
# Box from DEC special graphics: ┌──┐ / │  │ / └──┘\nimport sys\nsys.stdout.write('\\x1b(0lqqk\\nx  x\\nmqqj\\x1b(B\\n')\nsys.stdout.flush()
go
// Single-shift: print one G2 char without locking.\n// (G2 designated to DEC special graphics first.)\nfmt.Print(\"\\x1b*0\")   // designate G2 -> SpecGraphics\nfmt.Print(\"\\x1bNl\")    // SS2 then 'l' -> single ┌\nfmt.Print(\"X\")          // back to GL=G0 (US-ASCII) -> literal 'X'
javascript
// Lock GR to G2 for an 8-bit data path. Reset with LS0 (SI = \\x0f).\nprocess.stdout.write('\\x1b*A\\x1b}');  // G2 -> UK NRCS, LS2R\n// ... write 8-bit bytes; £ now lives at 0xA3 via G2\nprocess.stdout.write('\\x1b~');           // LS1R back to G1 default
c
/* ncurses-style box-drawing entry; designate G0 to SpecGraphics. */\nprintf(\"\\x1b(0\");\nputs(\"lqqk\");  /* ┌──┐ */\nputs(\"x  x\");  /* │  │ */\nputs(\"mqqj\");  /* └──┘ */\nprintf(\"\\x1b(B\");                /* restore G0 to US-ASCII */

终端支持

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`