OSC 4 查询 — 读取 256 色调色板索引(`\x1b]4;<n>;?\x07`)
向终端查询调色板索引 `n`(0–255)当前绑定的 RGB 值 —— 主题检查器、截屏工具与调色板迁移脚本常用。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\x1b]4;<n>;?\x07\033]4;<n>;?\007\e]4;<n>;?\aESC ] 4 ; n ; ? BEL1b 5d 34 3b ... 3b 3f 07说明
OSC 4 的*查询*对偶(设置形式参见 `osc-set-palette`)。发送 `\x1b]4;<n>;?\x07`,其中 `<n>` 为 0–255 的调色板索引,终端在标准输入回复 `\x1b]4;<n>;rgb:RRRR/GGGG/BBBB\x07` —— 与 OSC 10 / 11 / 12 查询(见 `osc-color-query`)相同的 XParseColor 形状、每通道 16 位形式。一次请求可批量多个索引 —— `\x1b]4;0;?;1;?;2;?\x07` 会连续返回三条回复。 **用途**: - **主题检查器 / dotfile 生成器** —— 把当前 16 个 ANSI 色加上 6×6×6 立方导出为 YAML / JSON,方便在新机上做到截屏级一致复刻。 - **截屏 / asciinema 录制器** —— 捕获运行时调色板,使回放在不同主题下仍能重现原始视觉。 - **调色板迁移脚本** —— 在套用新主题前读出当前颜色,以便逐字回滚(防御性的 `osc-reset-palette` 只能恢复*内置*默认,无法恢复用户自定义)。 - **CI 测试运行器** —— 自定义 OSC 4 后立即查询同一索引,断言它确实生效。 **回复解析** —— 回复中的索引与请求中的索引相同,因此批量发送多对 `;<n>;?` 时需按 `<n>` 解复用(并非所有终端都保证按发送顺序回复,多数会,但不可依赖)。每索引读超时 ~100 ms,缺失视为「未自定义 —— 退到 ANSI / 256 默认」。 **注意** —— Linux console / Windows cmd 忽略查询无回复(超时回退是正确策略)。macOS Terminal 仅对索引 0–15 回复。现代模拟器(xterm / iTerm2 / Kitty / Alacritty / WezTerm / Ghostty / Konsole)覆盖整段 0–255。
规范出处: xterm-ctlseqs (OSC 4 query)
参数
| n | 调色板索引 0–255(0–7 = 基础 ANSI、8–15 = 亮 ANSI、16–231 = 6×6×6 立方、232–255 = 灰阶)。 |
| ? | 查询占位符 —— 替换颜色规范,请求当前绑定而非修改。 |
示例
# Read palette index 1 (red) and print it.\nold=$(stty -g); stty -echo raw min 0 time 1\nprintf '\033]4;1;?\007' > /dev/tty\nIFS= read -r -d $'\\a' reply < /dev/tty\nstty "$old"\necho "palette[1] = ${reply##*rgb:}"# Dump first 16 ANSI colors as a Python dict.\nimport sys, termios, tty, select, re\nfd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\ntry:\n palette = {}\n for i in range(16):\n sys.stdout.write(f'\x1b]4;{i};?\x07'); sys.stdout.flush()\n if select.select([fd], [], [], 0.1)[0]:\n buf = b''\n while not buf.endswith(b'\\x07'):\n buf += sys.stdin.buffer.read1(64)\n m = re.search(rb'rgb:([0-9a-f]+)/([0-9a-f]+)/([0-9a-f]+)', buf, re.I)\n palette[i] = '#' + ''.join(g.decode()[:2] for g in m.groups())\n print(palette)\nfinally:\n termios.tcsetattr(fd, termios.TCSADRAIN, old)// Query a single palette index. (raw stdin setup elided — see osc-color-query)\nfor _, idx := range []int{0, 1, 2, 3, 4, 5, 6, 7} {\n fmt.Printf(\"\\x1b]4;%d;?\\x07\", idx)\n // read reply with bufio.Reader.ReadString(0x07), parse rgb:RRRR/GGGG/BBBB\n}// Batch query indices 0..15 in one write.\nprocess.stdin.setRawMode(true); process.stdin.resume();\nconst req = Array.from({length: 16}, (_, i) => `4;${i};?`).join(';');\nprocess.stdout.write(`\\x1b]${req}\\x07`);\nlet buf = '';\nprocess.stdin.on('data', chunk => {\n buf += chunk.toString();\n const matches = [...buf.matchAll(/\\]4;(\\d+);rgb:([0-9a-f]+)\\/([0-9a-f]+)\\/([0-9a-f]+)\\x07/gi)];\n if (matches.length === 16) {\n process.stdin.setRawMode(false); process.stdin.pause();\n console.log(matches.map(m => [+m[1], `#${m[2].slice(0,2)}${m[3].slice(0,2)}${m[4].slice(0,2)}`]));\n }\n});/* Query a single palette index — read until BEL. */\nprintf(\"\\x1b]4;%d;?\\x07\", index); fflush(stdout);\nchar buf[128]; int n = read(0, buf, sizeof buf - 1);\nif (n > 0) { buf[n] = 0; /* parse rgb:RRRR/GGGG/BBBB out of buf */ }终端支持
- 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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 支持 | 不支持 | 部分 | 支持 | 支持 | 不支持 | 支持 | 支持 | 支持 | 支持 | 部分 | 支持 | 不支持 | 不支持 |