单次切换 / 锁定切换族 —— 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 集指派配对。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\x1bN SS2 \x1bO SS3 \x1bn LS2 \x1bo LS3 \x1b~ LS1R \x1b} LS2R \x1b| LS3R\033N / \033O / \033n / \033o / \033~ / \033} / \033|\eN / \eO / \en / \eo / \e~ / \e} / \e|ESC N / ESC O / ESC n / ESC o / ESC ~ / ESC } / ESC |1b 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)
示例
# 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# Box from DEC special graphics: ┌──┐ / │ │ / └──┘\nimport sys\nsys.stdout.write('\\x1b(0lqqk\\nx x\\nmqqj\\x1b(B\\n')\nsys.stdout.flush()// 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'// 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/* 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
- 支持
| 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`