跳到主要内容
ansicode

DECRQTSR / DECRSTS —— 请求 / 还原终端状态报告

保存(`CSI Ps$u` → DCS 回)与还原(`DCS Ps$p…ST`)整套 DEC 终端状态 —— `dcs-decrsps` 只覆盖陈现状态时的终端全态补遗。

字节形式

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

\\x1b[\x1b[Ps$u request \x1bP<Ps>$p<body>\x1b\\ restore
\\033[\033[Ps$u request \033P<Ps>$p<body>\033\\ restore
\\e[\e[Ps$u request \eP<Ps>$p<body>\e\\ restore
ESC [ESC [ <Ps> $ u / ESC P <Ps> $ p <body> ESC \\
hex1b 5b … 24 75 / 1b 50 <Ps> 24 70 <body> 1b 5c

说明

**DECRQTSR**(*请求终端状态报告*,`\x1b[<Ps>$u`)与逆元 **DECRSTS**(*还原终端状态*,`\x1bP<Ps>$p<body>\x1b\\`)框出 DEC 把*整台终端*可变状态快照成不透明字节流,并稍后忠实回灌的机制。它们是 `dcs-decrsps` / `dcs-decrqss`(只覆盖*陈现*片段:光标、SGR、字符集、原点、制表位)的**终端全态**对偶。 **请求** —— `\x1b[<Ps>$u`。`Ps=1`(唯一通用值)选 DEC 终端状态。部分 VT 系列文档为 `Ps=2` 保留色表状态,但无实际模拟器把 `Ps=2` 与 `Ps=1` 区别实现 —— 视 `1` 为唯一可移植选择子。 **回复(DECTSR)** —— `\x1bP<Ps>$s<body>\x1b\\`。`$s` 中间-末字节把 DECTSR 与 DECRSTS *还原*形(`$p`)以及 DECRPSS(`$r`)区分开。`<body>` **对主机不透明** —— 是 DEC 私有的状态序列化,包含:制表位、字符集状态(G0/G1/G2/G3 指示符 + GL/GR + UPSS)、所有模式状态(DECCKM / DECANM / DECCOLM / DECSCLM / DECSCNM / DECOM / DECAWM / DECARM / DECTCEM / DECNRCM / DECSCA / DECNKM / DECSCUSR / DECSDM / DECSLRM)、打印机状态、键盘模式状态、当前 SGR 笔、光标位置 + 保存栈、保护区状态。主机**不得解析**主体 —— 语义保留给原发模拟器。 **还原** —— `\x1bP<Ps>$p<body>\x1b\\`。把同一 `<body>` 原样回送。终端校验 `<Ps>` 与保存时一致(不一致时回复模拟器静默回 `\x1bP0$r\x1b\\`,其他模拟器视为空操作)。**跨终端还原**(在 xterm 保存、到 Konsole 还原)**不可移植** —— 主体格式是 DEC 实现自定义,各家自有编码。 **往返模式**(TUI 接管 + 还原): ``` 启动: 发 '\x1b[1$u' # DECRQTSR Ps=1 读 DCS 直至 ST # 回 '\x1bP1$s<body>\x1b\\' 保存 body 退出: 发 '\x1bP1$p' + body + '\x1b\\' ``` 现代现实:多数 TUI 用 **alt-screen**(`\x1b[?1049h`/`l`)+ DECSC/DECRC 处理光标/SGR。DECRQTSR/DECRSTS 是 **终端全态**版本,仅在 alt-screen 不可用时(部分 BBS / 串口多路场景)或需要往返 DECSTR 不触碰的模式(NRCS、UPSS、DECSCA)时用。 **边界** - 回复默认以 `\x1b\\`(ST 表为 ESC + 反斜杠)结束;xterm 在 8 位 C1 模式(`decscl-compat-level`)下使用单字节 `\x9c` —— 解析器需对两种终止都就绪。 - 主体字节可包含 `\x1b` 后跟**除 `\\` 外任意字节**(DEC 把内嵌控制用 DECDLD 风格的十六进制转义编入);天真的「按 ESC 分割」解析器会错框 —— 读至包边界处见 ST,而非首个 ESC。 - 部分模拟器(Linux console)回空主体 —— 还原成空操作。 - DECSTR(软重置)不会清掉主机持有的快照,只重置在用终端状态。 **覆盖度** —— **xterm** = 完整(标准;主体长度通常 100–200 字节)。**mlterm** = 完整。**WezTerm** = 部分(回最小主体,还原接受但仅还原 SGR + 光标 + 制表位 —— DECSTR 会重置的模式会被重套,其余静默丢)。**Konsole** + **gnome-terminal** = 部分(回缺 UPSS / DECSCA 字段,还原同样截断)。**Kitty** + **iTerm2** + **Alacritty** + **Ghostty** + **Windows Terminal** + **cmd / ConPTY** + **macOS Terminal** + **Linux console** = 无作用(完全不回 —— 这些场景请改用 `alt-screen` + `cursor-save-restore` + `dcs-decrqss` 做往返)。

规范出处: DEC VT510 RM (DECRQTSR / DECTSR / DECRSTS) / xterm-ctlseqs (CSI Ps $ u)

参数

Ps = 1DEC 终端状态。唯一通用值。
Ps = 2保留(部分规范用于色表);无现役模拟器与 Ps=1 区别实现。
Reply $s vs Restore $pDCS 中间-末字节 `$s` = 报告(终端 → 主机);`$p` = 还原(主机 → 终端)。勿混。
<body>DEC 私有不透明序列化。原样往返。格式因模拟器而异 —— 不可跨终端搬运。

示例

bash
# Capture full terminal state, then restore on exit (xterm).\nprintf '\\033[1$u'\nIFS= read -rs -d '\\\\' -t 0.2 snapshot </dev/tty 2>/dev/null\n# ... session runs, mutates modes ...\n# Restore: re-emit the body in DECRSTS shape.\nbody=\"${snapshot#*\\\$s}\"\nbody=\"${body%\\\\}\"\nprintf '\\033P1$p%s\\033\\\\' \"$body\"
python
import sys, re\n# Save snapshot, then later push it back.\nsys.stdout.write('\\x1b[1$u'); sys.stdout.flush()\nreply = sys.stdin.buffer.read1(4096)\nm = re.search(rb'\\x1bP1\\$s(.*?)\\x1b\\\\', reply, re.DOTALL)\nbody = m.group(1) if m else b''\n# ... TUI session ...\nsys.stdout.flush()\nsys.stdout.buffer.write(b'\\x1bP1$p' + body + b'\\x1b\\\\')
go
// Skeleton: probe, read until ST, persist body for the duration of the run.\nfmt.Print(\"\\x1b[1$u\")\nvar buf [4096]byte\nn, _ := os.Stdin.Read(buf[:])\n// Match \\x1bP1$s<body>\\x1b\\\\.\nbody := extractDECTSR(buf[:n])\n// ...\nfmt.Printf(\"\\x1bP1$p%s\\x1b\\\\\", body)
javascript
// Snapshot at startup, restore on exit handler.\nprocess.stdout.write('\\x1b[1$u');\nlet snapshot = '';\nprocess.stdin.once('data', (buf) => {\n  const m = /\\x1bP1\\$s(.*?)\\x1b\\\\/s.exec(buf.toString('binary'));\n  if (m) snapshot = m[1];\n});\nprocess.on('exit', () => {\n  if (snapshot) process.stdout.write('\\x1bP1$p' + snapshot + '\\x1b\\\\');\n});
c
/* Skeleton: snapshot at TUI entry, restore at exit. */\nfputs(\"\\x1b[1$u\", stdout); fflush(stdout);\n/* read until ST seen at packet boundary, store body bytes opaquely. */\n/* on exit: fputs(\"\\x1bP1$p\", stdout); fwrite(body, 1, body_len, stdout); fputs(\"\\x1b\\\\\", stdout); */

终端支持

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

相关序列

在家族食谱中

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