跳到主要内容
ansicode

DECSTR 副作用 —— `\x1b[!p` 究竟重置哪些模式

DECSTR(软重置)会恢复到默认的每一个 DEC 模式 / 属性枚举参照 —— 哪些会被清、哪些保留、xterm / kitty / iTerm2 在哪里发生分歧。

字节形式

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

\\x1b[\x1b[!p
\\033[\033[!p
\\e[\e[!p
ESC [ESC [ ! p
hex1b 5b 21 70

说明

decstr-soft-reset 的伴生参照 —— 字节序列相同(\x1b[!p),扩展为 DEC VT510 RM §8.4.1 的完整副作用清单。问题是 「DECSTR 会不会把我的 X 弄丢?」 而非 「软重置怎么写?」 时看本页。

DECSTR 不会动: - 屏幕内容(主屏 / 备用屏 —— 保留) - 回滚缓冲(保留) - 备用屏快照(保留) - 窗口标题 / 图标名(OSC 0/2 设置的 —— 保留) - G0..G3 字符集定义(定义保留;活动 GL/GR 指针被重置 —— 见下) - 宏定义(DECDMAC 条目保留 —— 见 dcs-decdmac) - 用户键(DECUDK 条目保留 —— 见 dcs-decudk) - 光标位置(仍在原单元格)

DECSTR 会重置至以下默认值: - IRM(插入 / 替换,\x1b[4h/l)→ 替换 - DECOM(原点模式,?6h/l —— 见 dec-origin-mode)→ 关(绝对) - DECAWM(自动换行,?7h/l —— 见 dec-line-wrap)→ 开 - DECNRCM(国家替换字符集,?42h/l)→ 关 - DECNKM(数字 / 应用小键盘 —— 见 deckpam-deckpnm)→ 数字 - KAM(键盘动作,\x1b[2h/l)→ 解锁 - DECSCA(字符保护选择 —— 见 decsca)→ 全部无保护 - DECSCNM(反相屏幕,?5h/l —— 见 decscnm)→ 正常(关) - DECTCEM(光标可见,?25h/l —— 见 cursor-visibility)→ 开(光标可见) - DECCKM(光标键模式,?1h/l)→ 正常 - DECRLM(从右至左模式,?34h/l)→ 关 - DECSCUSR(光标形状 —— 见 dec-cursor-shape)→ 实现默认(通常为闪烁方块,\x1b[0 q) - DECSTBM(上下边距 —— 见 decstbm)→ 全屏(1 .. 高) - DECSLRM(左右边距 —— 见 decslrm)→ 全屏(1 .. 宽),仅 DECLRMM 开时 - SGR(所有字符属性:颜色、加粗、斜体等)→ 默认(\x1b[0m) - DECSC 保存的光标栈 → 清空 - GL / GR 映射 → GL → G0,GR → G2(规范默认) - 选择性擦除状态 → 关

厂商分歧: - xtermkittyalacrittyweztermghosttykonsole:与规范完全一致。 - iTerm2重置 DECSCUSR —— 光标形状跨 \x1b[!p 保留。如需顺带恢复形状,DECSTR 后显式发 \x1b[0 q。 - Windows Terminal:1.20 之前的构建不重置 DECSLRM。现代构建与规范一致。 - Linux console(内核 vt):旧内核把 DECSTR 当作 RIS-lite —— 屏幕和回滚也会清。别依赖回滚保留。 - macOS Terminal:静默忽略 DECSCA 重置(选择性擦除保护保留)。 - cmd.exe / ConPTY:部分实现;SGR + DECTCEM 会重置,其余多数忽略。

DECSTR vs RIS 何时选择:DECSTR 保留用户可见屏幕 + 回滚;RIS(见 ris-reset)一并清掉。「我刚退出一个状态不明的 TUI —— 优雅恢复又不丢上下文」用 DECSTR。「用户输 reset 因为终端卡死了」用 RIS(reset shell 命令通过 terminfo rs1 实际发的就是它)。

离场防御性模式: ``` 启动时: 通过 DECRQSS 快照在意的状态(SGR、光标形状、边距、鼠标模式) 退出(defer / 信号处理): 发 \x1b[!p # 软重置清除多数状态 发 \x1b[0 q # 强制光标形状(iTerm2 兜底) 发 \x1b[?1l\x1b> # 光标键 + 小键盘归位(额外保险) 发 \x1b[?25h # 光标可见(偏执 —— DECSTR 本来就会做) ```

规范出处: DEC VT510 RM §8.4.1 (DECSTR side-effect table) / xterm-ctlseqs

示例

bash
# Soft reset — preserves screen + scrollback. Side-effects as listed above.\nprintf '\\033[!p'
python
# Probe DECSCUSR after DECSTR to verify cursor-shape reset (catches iTerm2).\nimport sys\nsys.stdout.write('\\x1b[!p\\x1bP$q q\\x1b\\\\')\nsys.stdout.flush()
go
// Defensive exit: soft reset + explicit cursor shape + visible cursor.\nfunc restoreTerminal() {\n    fmt.Print(\"\\x1b[!p\")    // DECSTR\n    fmt.Print(\"\\x1b[0 q\")   // cursor shape -> default (iTerm2)\n    fmt.Print(\"\\x1b[?25h\")  // cursor visible (paranoia)\n}
javascript
// On Node TUI exit, leave terminal pristine for the user's shell.\nprocess.on('exit', () => {\n  process.stdout.write('\\x1b[!p\\x1b[0 q\\x1b[?25h');\n});
c
/* DECSTR keeps screen but you may want to also clear scroll-region\n * since DECSTBM resets to full-screen. */\nprintf(\"\\x1b[!p\");\nprintf(\"\\x1b[H\");  /* cursor home — DECSTR leaves it where it was */\nfflush(stdout);

终端支持

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

相关序列