跳到主要内容
ansicode

OSC 8 — 内联超链接

在终端输出中渲染可点击超链接(gnome-terminal 3.26+、iTerm2、Windows Terminal、kitty 等)。

字节形式

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

\\x1b[\x1b]8;;URI\x07TEXT\x1b]8;;\x07
\\033[\033]8;;URI\007TEXT\033]8;;\007
\\e[\e]8;;URI\aTEXT\e]8;;\a
ESC [ESC ] 8 ; ; URI BEL TEXT ESC ] 8 ; ; BEL
hex1b 5d 38 3b 3b ... 07 ... 1b 5d 38 3b 3b 07

实时预览

在浏览器中通过与解码器相同的分词器渲染 —— 无需打开终端。

说明

OSC 8 —— 内联超链接。由 gnome-terminal 作者 Egmont Koblinger 在 2017 年制定,现已被 iTerm2 3.5+、Windows Terminal 1.21+、kitty、wezterm、ghostty、Konsole 18.08+、libvte 0.50+(之后的 gnome-terminal / xfce4-terminal / tilix 全继承)以及 VS Code 集成终端采纳。两段式序列:\x1b]8;params;URI BEL(或以 ST \x1b\\ 结束)开始链接区段;\x1b]8;;BEL(URI 为空)结束。中间 TEXT 可包含任意可打印字节及后续 SGR —— 所以可以把链接套在 \x1b[4;34m…\x1b[0m 里得到熟悉的「蓝色 + 下划线」外观(iTerm2 / ghostty / wezterm / 近版 gnome-terminal 会渲染为真正可点击的链接)。可选参数:id=anchor 提示终端「具有相同 id 的相邻或非相邻字段属于同一逻辑链接」(用于跨行回卷的 URL 不让每个单元格变成独立超链接)。URI 范围:HTTP / HTTPS 在所有支持 OSC 8 的模拟器上可用;file:// 在 iTerm2 / wezterm / kitty / vscode-terminal 可用;编辑器 URI(vscode://cursor:// 等)部分支持。

两类失败模式咬到 OSC 8 用户。(1)终止符卫生:OSC 序列必须显式以 BEL(\x07)或 ST(\x1b\\)结束;漏写终止符会让解析器把后续字节当作链接负载继续吞,直到字节流中下一处 BEL / ST 出现 —— 你之后的程序输出全被吞掉(见 osc-terminator)。为兼容 xterm 优先用 BEL,追求 ECMA-48 严谨用 ST —— 选一种并保持一致。(2)id= 语义分裂:Kitty 以 id + url 为去重键(同 id + 不同 url → 两个独立链接,这正是你要的);21.04 前 Konsole 和 3.36 前 gnome-terminal 仅按 id 去重(同 id + 第二个 url 静默继承最先出现的 url —— 数据损坏);iTerm2 完全忽略 id(每段各自独立);Windows Terminal 接受 id 但不跨行视觉聚合。同一会话内绝不要为两个不同 URL 重用同一 id= —— 从内容哈希或 uuid 生成 id(完整兼容性表见 osc8-id-rebind)。覆盖:Linux console / fbcon 与 Alacritty(有意省略)把整个 OSC 8 包络渲染为空 —— 链接文本会消失,不只是丢下划线。cmd.exe 与 Apple Terminal.app 渲染文本但不可点。这些栈上务必提供 URL 内联回退(或「链接文本(URL)」的形式)。

没有「关闭超链接」的精准 SGR —— 标准关闭就是空 URI 形式 \x1b]8;;\x07(或 \x1b]8;;\x1b\\)。组合 sgr-underline + sgr-fg-basic 给超链接包络内的可见文本上样式而不影响链接语义:\x1b]8;;https://example.com\x07\x1b[4;34mlink text\x1b[0m\x1b]8;;\x07。属于同一 OSC 家族、共用终止符规则的窗口标题与工作目录更新,见 osc-titleosc-cwd。OSC 52 剪贴板互操作见 osc-clipboard。发 OSC 8 时务必配合受众检查 —— 按保守行为假设(alacritty / Linux console 上文本会消失),并在 CLI 的 --help-l 长格式模式里为这些用户提供文本 URL 回退。

规范出处: Hyperlinks in terminal emulators (gnome-terminal proposal, 2017)

示例

bash
printf '\033]8;;https://example.com\033\\link text\033]8;;\033\\\n'
python
print('\x1b]8;;https://example.com\x07link text\x1b]8;;\x07')
go
fmt.Print("\x1b]8;;https://example.com\x07link text\x1b]8;;\x07\n")
javascript
console.log('\x1b]8;;https://example.com\x07link text\x1b]8;;\x07')
c
printf("\x1b]8;;https://example.com\x07link text\x1b]8;;\x07\n");

在哪里用到

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

  • gh (GitHub CLI)issue / PR / diff 输出链接到对应 github.com URL
  • git 2.40+启用 color.hyperlink 后,部分子命令的文件路径会变成超链接
  • eza在支持的终端中,文件名超链接到 file:// URI
  • pytest — traceback file paths
  • cargo build output — diagnostic URLs
  • deltagit 分页器——文件路径头链接到磁盘上的文件

常见问题

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

为什么 \x1b]8;;https://...\x1b\\ 在终端里显示成原始文本?
你的终端没实现 OSC 8,或者你身处复用器中而 OSC 被吞掉。现代终端(iTerm2、kitty、ghostty、wezterm、alacritty、较新的 Windows Terminal / gnome-terminal)会渲染为可点击链接;老终端会按字节原样打印。tmux 必须 set -g allow-passthrough on 才会转发——参见 tmux-passthrough-dcs 误区条目。
能用 BEL(\a)代替 ST(\x1b\\)作为终止符吗?
可以——两种终止符都符合规范,所有支持 OSC 8 的终端都接受。BEL 是 xterm 最早的写法,字节数更短;ST 是 ECMA-48 的标准形式。代码库里挑一种用并保持一致——在同一段 OSC 里混用是未定义行为。
为什么相邻的两条 OSC 8 链接被合并成了一条长链接?
你在两条链接之间漏写了关闭序列 \x1b]8;;\x1b\\(空 URL),或者两个不同 URL 复用了同一个 id=… 值,终端把它们当作一段。每条链接都要先关闭再开下一条,并且要么省略 id=,要么每个 URL 用新值——参见 osc8-id-rebind 误区条目。

终端支持

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

相关序列

在家族食谱中

OSC 食谱 · 3. OSC 8 超链接 —— `\x1b]8;;URI\x07TEXT\x1b]8;;\x07`