DECTCEM ?25 — 显示/隐藏光标
显示或隐藏文本光标。
字节形式
涵盖所有常见的字符串字面量写法,方便正反查找。
\x1b[?25h (show) \x1b[?25l (hide)\033[?25h / \033[?25l\e[?25h / \e[?25lESC [ ? 2 5 h / l1b 5b 3f 32 35 68 / 6c说明
DEC 文本光标启用模式。\x1b[?25h 显示文本光标,\x1b[?25l 隐藏 —— ? 前缀表示这是 DEC 私有模式(非 ECMA-48 SGR 或 CSI 序列),末字节 h / l 是所有 DEC 私有模式共用的 SET / RESET 对(?7h/l DECAWM、?12h/l 光标闪烁、?1049h/l 备用屏,等等)。上面矩阵中的每个模拟器都支持。光标的*位置*不受影响 —— 仅切换渲染中的光标符 —— 因此「多行重绘前隐藏、重绘后显示」可以避免光标在重绘文本上跳动的视觉抖动,这也是进度条和全屏 TUI 的主要用途。
最大的坑(也许是最常见的终端状态 bug)是程序异常退出时 ?25l 还设着。panic、kill -9、信号处理器未注册时的 SIGINT、CLI 流程中的未捕获异常,都会让用户 shell 无可见的命令行光标。用户得跑 tput cnorm(?25h 的 terminfo cap)或 reset 来恢复。务必注册一个把光标重显的清理处理器:bash trap "printf '\\x1b[?25h'" EXIT INT TERM;Python signal.signal(signal.SIGINT, lambda *_: (sys.stdout.write('\\x1b[?25h'), sys.exit(130)));Go defer fmt.Print("\\x1b[?25h") 配合 os/signal 处理器在退出前重发。/pitfalls 的 stuck-cursor-hidden 条目详细记录了恢复路径。可见性与 dec-cursor-shape(DECSCUSR \x1b[N q)、dec-cursor-blink 互相正交 —— 你可以隐藏一个稳定块状光标、之后以闪烁竖线形状重新显示;三个设置独立组合。
重显光标用 \x1b[?25h —— ?25l 的精准对应物。在 alt-screen 模式(?1049h)下,多数模拟器把可见性设置按屏分离:在备用屏隐藏不会传播回退出时的主屏,所以备用屏内隐藏光标的 TUI 严格上不需要在 ?1049l 退出前重显(虽然稳妥代码会两条都发)。可移植的 terminfo cap 是 civis(隐藏,xterm-256color 上展开为 \x1b[?25l)与 cnorm(显示,展开为 \x1b[?25h);shell 脚本中写 tput civis / tput cnorm 是不假定 $TERM 的规范方式。相关:dec-cursor-shape 控形状、dec-cursor-blink 控闪烁、cursor-save-restore 与位置一起快照恢复。
规范出处: xterm-ctlseqs (DECTCEM)
示例
printf '\033[?25l'; sleep 2; printf '\033[?25h'import sys; sys.stdout.write('\x1b[?25l')fmt.Print("\x1b[?25l")process.stdout.write('\x1b[?25l')printf("\x1b[?25l");在哪里用到
实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。
- npm, pnpm install spinners旋转开始时隐藏,结束时恢复
- ora (Node), cli-spinners
- htop, btop full-screen TUIs
- less — hides cursor on page
- vim, neovim — depending on guicursor setting
常见问题
针对这条序列,开发者真正会去搜索的问题的简短回答。
- 光标消失了找不回来,运行什么命令能恢复?
- 运行
printf '\033[?25h'就能让光标重新显示。是某个 TUI 崩溃前没发出该序列,shell 继承了「隐藏」状态。若仍无效,reset(或stty sane)会清掉所有终端模式,包括光标可见性。预防方案见stuck-cursor-hidden误区条目(信号处理器在退出时重发\x1b[?25h)。 \x1b[?25h/\x1b[?25l跟\x1b[?12h/\x1b[?12l是一回事吗?- 不是。
?25切换光标可见性(显示 / 隐藏);?12切换光标闪烁(恒亮 / 闪烁,支持时)。两者独立——你可以隐藏一个闪烁的光标,或显示一个不闪的。要更精细控制光标形状(方块 / 下划线 / 竖线,闪 / 不闪),用 DECSCUSR(\x1b[N q)——参见dec-cursor-shape。
终端支持
- 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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |