跳到主要内容
ansicode

DECTCEM ?25 — 显示/隐藏光标

显示或隐藏文本光标。

字节形式

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

\\x1b[\x1b[?25h (show) \x1b[?25l (hide)
\\033[\033[?25h / \033[?25l
\\e[\e[?25h / \e[?25l
ESC [ESC [ ? 2 5 h / l
hex1b 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 处理器在退出前重发。/pitfallsstuck-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)

示例

bash
printf '\033[?25l'; sleep 2; printf '\033[?25h'
python
import sys; sys.stdout.write('\x1b[?25l')
go
fmt.Print("\x1b[?25l")
javascript
process.stdout.write('\x1b[?25l')
c
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
支持

相关序列

在家族食谱中

DEC 食谱 · 1. `?` 前缀 —— DECSET 与 SM 的分水岭