跳到主要内容
ansicode

DSR — 设备状态报告(CSI 5n / CSI 6n)

查询终端状态(5n)或当前光标位置(6n)—— TUI 用以测量终端大小的反向通道。

字节形式

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

\\x1b[\x1b[5n (status request) \x1b[6n (cursor pos request)
\\033[\033[5n / \033[6n
\\e[\e[5n / \e[6n
ESC [ESC [ Ps n
hex1b 5b <Ps> 6e

说明

Device Status Report。程序发出请求,终端在 stdin 上回复。\x1b[5n —— 「你还好吗?」。回复:\x1b[0n(就绪)或 \x1b[3n(异常)。常作为启用奇特模式后的存活检查。\x1b[6n(又名 CPR,Cursor Position Report)—— 「光标在哪?」。回复:\x1b[<row>;<col>R。在没有 TIOCGWINSZ 的情况下测算终端大小的经典套路:把光标推到屏幕末端(\x1b[9999;9999H),DSR-6n,解析回复,再还原。现代程序首选 ioctl(TIOCGWINSZ) + SIGWINCH 监听 resize,但缺少该 ioctl 的场景(原始串口、某些 CI 环境)下,DSR-6n 仍是唯一可移植方案。xterm 扩展:\x1b[?6n 返回受 DECOM(origin mode)约束的光标位置。

规范出处: ECMA-48 §8.3.35 (DSR) / xterm-ctlseqs

示例

bash
# Discover terminal size without TIOCGWINSZ:\nstty -echo raw min 0 time 5\nprintf '\033[s\033[9999;9999H\033[6n\033[u'\nIFS=';' read -r -d R esc_row col; stty sane\necho "rows=${esc_row#*[} cols=$col"
python
import sys; sys.stdout.write('\x1b[6n')   # reply arrives on stdin in raw mode
go
fmt.Print("\x1b[6n")
javascript
process.stdout.write('\x1b[6n')
c
printf("\x1b[6n"); fflush(stdout); /* parse <row>;<col>R from stdin */

在哪里用到

实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。

  • vim, neovim startup probes`:checkhealth` 在启用块光标 / 鼠标功能前发 `\x1b[6n` 确认光标位置上报可用
  • resize(1) (xterm utility)「不用 ioctl 测算终端大小」的经典实现 —— 把光标推到 `\x1b[9999;9999H` 后发 DSR-6n、解析回复并导出 `COLUMNS` 与 `LINES`
  • stty -a fallback probes对于无 `TIOCGWINSZ` 的场景(CI runner、串口控制台),裸 `printf '\033[6n'` + 带上限 `read` 是可移植回退方案
  • powerlevel10k, starship right-prompts复杂多行提示符用 DSR-6n 校准自身的 wcwidth 估计与终端实际光标推进的偏差
  • asciinema, ttyrec — capture DSR replies in the recorded session so playback is dimension-accurate

常见问题

针对这条序列,开发者真正会去搜索的问题的简短回答。

我发了 \x1b[6n 却收不到回复,哪里出了问题?
三种常见原因。(1)tty 处于 cooked 模式 —— 回复(\x1b[<row>;<col>R)抵达 stdin 后被行规程缓存,直到你按 Enter 才送出。切换到 raw 模式或用 stty -icanon min 0 time N 做带超时的非阻塞读。(2)读取发生在回复抵达 *之前* —— 终端可能要几十毫秒才应答,因此请求务必配上带上限的 read(或带超时的 select())与回退路径。(3)你在 tmux/screen 内且未开 passthrough —— 复用器代答内部 pane,可能报告自身大小而非宿主终端;要拿宿主信息得开 passthrough 或在复用器接管前直接查询。务必实现 200 ms 超时 + ioctl(TIOCGWINSZ) 回退,让缺失的回复不至于挂死程序。
检测终端能力时该用 DSR \x1b[6n 还是 DA \x1b[c
都不直接答你想要的 —— 它们回答的不是同一个问题。DSR-6n 返回光标位置,可借 \x1b[9999;9999H 小技巧测算屏幕大小,但完全不涉及特性支持。DA(\x1b[c 返回设备属性串以识别模拟器类别(?1;2c?64;... 等)——只是粗粒度能力提示,与具体特性无关。要回答「这个终端支持同步输出 / 焦点事件 / SGR 鼠标吗?」该用 DECRQM\x1b[?<mode>$p,见 decrqm 条目),它询问具体 DEC 私有模式并给出 0/1/2/3/4 的明确回答。指纹识别时三者合用:DA 看类别,DECRQM 做每特性门控,没有 TIOCGWINSZ 的场景下用 DSR-6n 测大小。

终端支持

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

相关序列

在家族食谱中

CSI 食谱 · 4. 查询 —— DA、DA2、DSR、DECRQM