跳到主要内容
ansicode

OSC 10 / 11 — 设置默认前景 / 背景色

设置终端的默认前景色(OSC 10)或背景色(OSC 11),或查询当前值。

字节形式

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

\\x1b[\x1b]10;#RRGGBB\x07 (set fg) \x1b]11;#RRGGBB\x07 (set bg)
\\033[\033]10;#RRGGBB\007 / \033]11;#RRGGBB\007
\\e[\e]10;#RRGGBB\a / \e]11;#RRGGBB\a
ESC [ESC ] 10 ; COLOR BEL / ESC ] 11 ; COLOR BEL
hex1b 5d 31 30 3b ... 07 / 1b 5d 31 31 3b ... 07

说明

xterm-ctlseqs 文档化 OSC 10(设置 / 查询终端默认前景色)与 OSC 11(设置 / 查询默认背景色)。字节形态 \x1b]<10|11>;<color>\x07(BEL 终止)或 \x1b]<10|11>;<color>\x1b\\(ST,即 ESC \ 终止)。颜色参数接受 xterm 全部多种写法:#RRGGBB(每通道 8 位十六进制)、#RGB(4 位简写)、rgb:RRRR/GGGG/BBBB(每通道 16 位)、或系统 rgb.txt 中的 X11 颜色名如 cornflowerblue。把值替换为 ?\x1b]10;?\x07),终端会在 stdin 上 *回报* \x1b]10;<当前色>\x07 —— 即查询形式,vim 的 'background' 自动检测、tmux 的颜色内省、想要渲染与主题协调 UI 的 TUI 均使用。恢复出厂默认用 OSC 110(前景)/ OSC 111(背景)。

可移植性 —— xterm、iTerm2、kitty、alacritty、wezterm、gnome-terminal、Konsole、Ghostty、Windows Terminal、ConPTY 1809+ 全部支持设置 + 查询。Linux console *不* 支持(内核 framebuffer 驱动不响应 OSC 颜色设置 —— 颜色仅来自内核调色板)。Apple Terminal.app *部分* 支持:接受设置形式,但 *从不* 回应查询形式 —— 这破坏了 macOS Terminal 上 vim 的自动检测,直到用户手动 set background=dark / light。终止符选择有讲究:BEL(\x07)通用;ST(ESC \\x1b\x5c 两字节)是 ECMA-48 的 C1 形式,但部分遗留解析器对两字节 ST 处理不洁 —— 拿不准时用 BEL。tmux 需要 set-option -g allow-passthrough on 加上恰当的 terminal-overrides 才能让查询应答穿透多路复用器;否则内部 pane 永远收不到回复。

查询形式才是关键用例。TUI 发出 \x1b]11;?\x07 并解析回复(例如 \x1b]11;rgb:1e1e/1e1e/2e2e\x07 表示近黑背景),就能挑选与用户终端真实对比的配色方案,而不是从 TERM$COLORFGBG 环境变量绞尽脑汁猜。设置形式应节制使用 —— 中途改变用户背景色非常突兀,许多用户花过时间调主题;OSC 10 / 11 设置适合自带主题的全屏应用(图像查看器、演示工具)在退出时通过 OSC 110 / 111 恢复原值(用 atexit / 信号处理实现可持久清理模式)。安全提示:未提示就接受 OSC 写入的终端允许日志输出篡改终端颜色,单独看只是稍烦,并无可利用性 —— 不同于 OSC 52(剪贴板,见 osc-clipboard),后者有真实攻击面,多数现代终端因此默认关闭。相关:osc-title(OSC 0 / 1 / 2 —— 同 OSC 框架用于窗口标题)、osc-hyperlink(OSC 8 —— 用同样的 OSC 框架做超链接)、sgr-fg-truecolor(SGR 38;2;R;G;B —— 单段文本前景色,OSC 10 的默认色位于其下层)。

规范出处: xterm-ctlseqs (OSC 10 / 11 / 110 / 111)

示例

bash
printf '\033]11;#1e1e2e\007'   # set bg to deep navy\nprintf '\033]11;?\007'        # query current bg
python
import sys; sys.stdout.write('\x1b]10;#cdd6f4\x07')
go
fmt.Print("\x1b]10;#cdd6f4\x07")
javascript
process.stdout.write('\x1b]10;#cdd6f4\x07')
c
printf("\x1b]10;#cdd6f4\x07");

在哪里用到

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

  • vim, neovim `background=` heuristic编辑器启动时用 OSC 11 `\x1b]11;?\x07` 查询终端的实际默认背景,然后自动切换 `:set background=light` 或 `dark` —— 解决了启发判断错时配色画成灰底灰字的经典问题
  • starship, oh-my-posh, powerlevel10k prompt rendering提示符通过 OSC 10 / 11 查询,挑出对比强烈的强调色 —— 不论用户用深色还是浅色配色,斜体灰段都保持可读;终端不应答时才回退到静态调色板
  • alacritty, WezTerm, kitty live colour reload三款终端都接受运行时 OSC 10 / 11 写入 —— 编辑配置里的 `colors.primary.foreground` 并 SIGUSR1 重载会广播 OSC 10,所有已开 shell、vim、tmux 窗格无需重启就拿到新默认前景
  • iTerm2, Windows Terminal scheme switcheriTerm2 的配置切换热键和 Windows Terminal 的 `Ctrl+,` 配色选择器都用 OSC 10 / 11 把新默认色推送到活动会话 —— 运行中程序在 FocusGained 时重新查询,立即看到变化
  • tmux OSC 10 / 11 passthroughtmux 把活动窗格的 OSC 10 / 11 查询转发给外层终端并把应答路由回来 —— 不转发,tmux 内的 vim 嗅探不到外层真实背景,`background=` 启发只会选 dark

常见问题

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

怎样读取终端当前的默认前景 / 背景色?
发送查询形式:前景 \x1b]10;?\x07,背景 \x1b]11;?\x07。支持的终端会从 stdin 回复 \x1b]10;rgb:RRRR/GGGG/BBBB\x07(每通道 16 比特)。读取必须非阻塞并设短超时,因为许多终端(旧版 urxvt、Linux 控制台、无 passthrough 的复用器)根本不回复。配 50–100ms 的 select() / poll() 后退回合理默认值;千万别死等回复。
为什么 \x1b]10;#ff0000\x07 在程序退出后失效了?
通常它确实会保留 —— 如果你本不想这样,那才是问题。OSC 10 / 11 修改的是 *终端* 自身的状态,不是进程状态。退出时还原,请在清理 / 信号处理器里发重置对:\x1b]110\x07(重置前景)+ \x1b]111\x07(重置背景)。如果终端真的「忘了」,那是你处在复用器(tmux / screen)里 —— 它截获 OSC 并转发会话作用域的副本,会话结束时内部的 OSC 状态也跟着消失。

终端支持

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

相关序列

在家族食谱中

SGR 食谱 · 5. OSC 调色板覆盖 —— 直接把槽位本身改了