跳到主要内容
ansicode
DCS(设备控制字符串)

DCS 转义码 —— 设备控制字符串

Device Control String。`ESC P … ESC \` 信封 —— Sixel 图形、ReGIS、terminfo 查询协议(XTGETTCAP)、DECRQSS(请求选择 / 设置)。承载高带宽的带外数据:从内嵌图像,到查询终端当前光标样式,都走这里。

11 条序列

DCS 食谱 —— 五步读透设备控制串家族

DCS(Device Control String,设备控制串)是 ECMA-48 为「面向终端自身的高带宽不透明载荷」保留的 \x1bP …… \x1b\\ 信封 ——「面向对端应用」走的是 APC 那条道。下面五步覆盖这一家族 2026 年依旧承担的活:信封形状、嵌入像素图像(Sixel + Kitty 图形)、运行时自省查询、遗留 VT 重映射面(用户自定义键、动态下载字形、宏录制),以及保存 / 重放表现态对。

  1. 1. DCS 信封 —— \x1bP …… \x1b\\(8 位形 \x90 …… \x9c

    每条 DCS 都是 \x1bP(ESC P)起头,跟 Pp;Pn;… 头部参数,再跟 | 或终结字节选择子,然后是任意载荷,最后 \x1b\\(ST)。8 位 C1 形 \x90 …… \x9c 单字节版本相同但 UTF-8 不安全,除已知 Latin-1 通道外勿用。信封要求**不透明**穿越中间件:tmux 的 allow-passthrough on(≥ 3.3)把内层 DCS 再裹一层外层 DCS \x1bPtmux;<把内层 ESC 字节重复一遍>\x1b\\ 才能让字节跨过多路复用器(参 tmux-passthrough-dcs 痛点)。载荷长度上限各家不同:xterm 的 decGraphicsTermLevel 资源限制 Sixel 缓冲;kitty 无硬上限但解析器是状态机(每个 pane 同时只允许一条半成品 DCS);ConPTY 历史上把超大 DCS 在 4KB 处截断。**ST 必发**;漏写会让解析器一直挂起,直到下一个意外的 \x1b\\ 字节对出现 —— 在此之前的全部输出都被当成 DCS 载荷静默吞掉。

  2. 2. 流内画图 —— Sixel 与 Kitty 图形

    两套协议把像素塞进流。**Sixel** 是元祖 —— \x1bPq<sixel 数据>\x1b\\(DCS 终结字节 q)。每个「sixel」字符(?~)编码一条 6 像素纵向带,64 色调色板;早于 RGB 显示器。xterm(需 --enable-sixel-graphics)、foot、WezTerm、iTerm2、Konsole、mlterm、Ghostty 1.0+ 都能渲染;macOS Terminal、GNOME Terminal、alacritty、Linux console 不能。**Kitty 图形**是现代替代 —— slug 虽叫 dcs-kitty-graphics,真实字节形是 APC(\x1b_G<key>=<val>,…;<base64 像素>\x1b\\),不是 DCS;不过搜索终端图像协议的读者两条页面都会落,所以在 DCS 食谱里交叉链接合理。Kitty 图形按 4KB 块流式发 PNG / RGBA(m=1 续传,m=0 终止),支持放置 ID 做动画,Kitty、Konsole 22.04+、WezTerm 20240128+、Ghostty 都吃。truecolor-fallback-banding 提到的色带问题在像素信封里依然存在 —— 会降采样的模拟器仍按其规则降采样。

  3. 3. 向终端提问 —— DECRQSS、terminfo cap、DECRQTSR、DECRQUPSS、光标样式

    五道查询让 TUI 在运行时探明终端当前状态。\x1bP$q<P>\x1b\\(DECRQSS)是万能勺 —— <P> 处填 m(当前 SGR)、r(上下边距)、s(左右边距)、 q(光标样式)、"q(DECSCA 保护位)、"p(DECSCL 兼容级)。终端会在 stdin 上回送一条对应的 DCS,里面是当下的实际设置。\x1bP+q<十六进制名>;<十六进制名>…\x1b\\(XTGETTCAP,slug dcs-termcap-query)按十六进制名问 terminfo 能力 —— 运行时探测真彩色(RGB)、OSC 52 剪贴板(Ms)、样式下划线就靠它。\x1bP1$u\x1b\\(DECRQTSR / DECRQPSR)请求 Terminal State Report —— 把全部模式位向量打包;配合 \x1bP\$t…\x1b\\(DECRSTS)还原。\x1bP&u\x1b\\(DECRQUPSS)问当前装在「用户优选」槽位里的字符集。\x1bP$q q\x1b\\(DECRQSS 的光标子查询 —— slug decscusr-query)回报当下光标形状(闪烁块、固定竖条等)。所有回复都**异步**到达 stdin —— 用超时或 select(2) 会合读,别用阻塞读。

  4. 4. VT 重映射面 —— DECUDK(用户自定义键)与 DECDLD(下载字形)

    两条 VT500 时代的遗留能力,xterm + mlterm 在 2026 年仍然认得 —— 小众,但 CTF / 复古计算场景里照样出现。**DECUDK**(\x1bPPc;Pl|Ky/St;Ky/St;…\x1b\\)在运行时把 DEC 用户定义功能键(F6–F20)重映射到任意字节序列 —— 改不动用户 terminfo 时的「穷人版宏键映射」。Pc 控制扩展还是替换现有 UDK 表,Pl 是锁定模式,每个 Ky/St 对是键号 + 十六进制编码的输出串。**DECDLD**(\x1bP<参数>{ <模式>\x1b\\)把一个 Sixel 模式字形下载进字符集槽位 —— 当年终端字形 ROM 容量有限,每会话可以发一个自定义字符(一个对勾、一个 CJK 表意字、一个手画图标)。xterm 在 decTerminalID = 220 资源路径上渲染;今天对复古风 TUI 仍然有用 —— 要画 Unicode 制表区之外的自定义边框时。对不支持的终端这两条都可安全发 —— 现代模拟器会丢弃主体继续运行。

  5. 5. 有状态保存 / 重放 —— DECDMAC(定义宏)与 DECRSPS(恢复表现态)

    两条来自 VT500 系列的保存 / 重放原语。**DECDMAC**(\x1bPPid;Pdt;Pen!z<宏体>\x1b\\)以整数 Pid(1–63)命名一段字节;后续随时用 \x1b[Pid*z(DECINVM —— 调用宏)回放。Pdt 决定同 id 覆盖还是追加;Pen 在字面体与基础编码体(压缩重复字节)之间切换。TUI 要画几十次相同的框架 chrome 时正合用 —— 定义一次,每次重绘只发三字节。xterm + WezTerm 支持;alacritty、gnome-terminal、macOS Terminal 忽略(无作用即安全)。**DECRSPS**(\x1bP<Ps>$t<状态数据>\x1b\\)是第 3 节 DECRQTSR 的反操作 —— 把状态报告字节贴回去就还原整个模式向量。Ps=1 还原 DEC 私有模式、Ps=2 还原光标信息。这对往返(DECRQTSR → 保存 → DECRSPS)让 TUI 能在做危险操作前给终端状态打一个 checkpoint、失败时干净回滚 —— 终端模拟界的事务原语。

本家族的全部序列

浏览其他家族