> 文章

SSH 里命令跑完怎么弹桌面通知?终端 OSC 序列简介

远程命令跑完弹本机通知、在服务器的 vim 里复制到本机剪贴板、终端里能点的链接,靠的都是 OSC 序列。讲讲它是什么、怎么用。

发布于

本文目录
  1. 程序怎样指挥终端
  2. OSC 能做哪些事
  3. 命令跑完弹个通知
  4. 在服务器上复制,贴到本机
  5. 用了 tmux 时
  6. 在 ShellRS 里

在服务器上跑一个半小时的编译,想在跑完时收到本机的桌面通知;在远程的 vim 里复制一段文字,想直接贴进本机的浏览器;终端的窗口标题时不时自己就变了;报错信息里的选项名,点一下就能打开文档。这些事背后是同一样东西:程序夹在输出里、写给终端看的指令,其中最常用的一类叫 OSC。这篇讲讲它是什么、能做什么,以及怎么用上。

程序怎样指挥终端

终端里的程序只能往屏幕输出文字。要让终端做点别的,比如把字变红、改窗口标题,程序就在输出里夹一小段特殊字符,开头是一个看不见的 ESC 字符。终端认出这段字符后不把它显示出来,而是照着去做。这叫「转义序列」,屏幕上的颜色、光标的移动,都是这样来的。

OSC 是其中一类,全称 Operating System Command(操作系统命令),管的是屏幕上那些字以外的事:窗口标题、剪贴板、桌面通知、链接。每条 OSC 带一个编号,表示要做什么,后面跟着内容,比如标题文字、通知正文。

对 SSH 用户来说,它最有用的一点是:OSC 就是普通的输出。服务器上的程序把它和别的文字一起打印出来,经过 SSH 原样回到你本机的终端,不用另开通道。反方向,按键怎样告诉程序,是另一套约定,见《kitty 键盘协议》;在同一条连接里传文件,见《rz / sz 与 ZMODEM》。

OSC 能做哪些事

常见的几种:

编号 能做什么
0、2 改窗口或标签的标题
7 告诉终端当前在哪个目录,终端可以在同一目录开新标签
8 让一段文字变成可以点的链接
9、777 弹桌面通知
52 把内容放进本机的剪贴板

它们并非出自同一份标准:7、8、9、777 都是后来由各家终端加上的,所以支持情况不一样。终端遇到不认识的,一般直接忽略。

窗口标题为什么会自己变?很多 shell 配置会在每次显示提示符时,用 OSC 把标题设成「用户@主机:目录」这样的内容;有的程序运行时会换上自己的标题,比如 Claude Code。

链接(OSC 8)和网页上的链接一样:显示的是一段文字,背后是一个地址。ls --hyperlink 列出的文件名、gcc 10 起报错信息里的选项名,都是这样的链接。规范建议终端别在单击时就打开,要按住修饰键或用右键菜单。

命令跑完弹个通知

弹通知有两个编号。OSC 9 来自 iTerm2,只带一段正文;OSC 777 来自 rxvt-unicode(urxvt),多一个单独的标题。foot、WezTerm、Ghostty 和 ShellRS 两种都认,iTerm2 和 kitty 认 OSC 9,rxvt-unicode 认 OSC 777。

用法很简单,接在命令后面:

make; printf '\e]9;编译完成\a'

把 make 换成你要跑的命令,「编译完成」是通知的正文。用分号而不是 &&,命令失败了也会提醒。终端只认 777 的话,改成 printf '\e]777;notify;标题;正文\a'。两种不必同时发,两样都认的终端可能会弹两次。

这在远程服务器上一样管用:通知跟着输出经 SSH 回到本机,弹在你自己的桌面上,服务器上什么都不用装。命令跑起来就可以去忙别的,跑完自然会提醒你。

在服务器上复制,贴到本机

在 SSH 上的 vim 里按 y 复制一段,回到本机按 ⌘V 或 Ctrl+V,什么也贴不出来:内容只在服务器上的 vim 里,本机的剪贴板并不知道。

OSC 52 就是为这个准备的。程序把要复制的内容放进一条 OSC 52 里打印出来,终端收到后,写进本机的剪贴板。vim 装上 OSC 52 插件,或者 tmux 打开 set-clipboard(见下一节),复制的内容就能直接到本机。

OSC 52 也能反过来,让终端把剪贴板里的内容交给程序。这很危险:任何能往你终端输出的程序,包括远程服务器上的,都可能悄悄读走你刚复制的密码。所以终端对读取都很谨慎,有的直接不许,有的先问你。写入的风险小得多,最坏只是剪贴板被换掉,很多终端默认允许,也有的要先在设置里打开;不过 cat 一个来路不明的文件也可能改掉剪贴板,往终端里粘贴前最好看一眼。

用了 tmux 时

tmux 本身也是一个终端:程序的输出先到 tmux,tmux 再把画面重画到外面的终端上。它认识的 OSC 自己处理,不认识的就丢掉。所以在 tmux 里发通知,外面的终端收不到;程序用 OSC 52 复制的内容,tmux 默认也不往外传,只有在 tmux 自己的复制模式里复制的才会传出去。

在 ~/.tmux.conf 里加上两行:

set -g set-clipboard on
set -g allow-passthrough on

然后运行 tmux source-file ~/.tmux.conf,或者重开 tmux。第一行让程序复制的内容穿过 tmux 到达本机。第二行(tmux 3.3 起)允许程序把 tmux 不认识的序列「透传」出去,不过通知命令还要包上一层,写成:

make; printf '\ePtmux;\e\e]9;编译完成\a\e\\'

on 只在这个窗格显示着时放行。跑命令时如果会切到 tmux 的别的窗口,tmux 3.4 起可以把 on 改成 all。

在 ShellRS 里

ShellRS 是一个免费、开源的 SSH 客户端,支持 macOS、Windows 和 Linux。上面说的几件事,在 ShellRS 里是这样的:

  • 通知:OSC 9 和 OSC 777 都认。ShellRS 不在前台时发系统通知,点一下回到那个终端;在前台但终端在别的标签时,在窗口右上角提示。通知标题是标签名,看得出是哪台主机发的。不想要可以在「设置 › 终端 › 通知」里关掉。
  • 剪贴板:远程程序用 OSC 52 复制的内容直接进本机剪贴板;远程程序读不了本机剪贴板。
  • 链接:程序标出的链接,和输出里的 http://、https:// 地址,显示为带下划线的蓝色。按住 ⌘(Windows 和 Linux 上是 Ctrl)单击,用浏览器打开;鼠标在上面停一会儿,会显示它真正的地址。
  • 当前目录:右侧栏的「文件」靠 OSC 7 跟着终端的当前目录走。bash、zsh 还没配置时,ShellRS 会询问要不要自动配置。
  • 标题和配色:本地终端的标签显示 shell 和程序设的标题;vim 等程序询问终端的背景色时,得到的是当前主题的颜色。

详见 ShellRS 使用手册,ShellRS 可以在下载页获取。

试试 ShellRS

免费开源的 SSH 客户端:终端、SFTP 和端口转发都在一个窗口里,支持 macOS、Windows 和 Linux。