> articles

How do I get a notification when a remote command finishes? OSC escape sequences explained

Desktop notifications from remote commands, copying from vim on a server to your local clipboard, clickable links in the terminal. OSC sequences do it all.

Published

On this page
  1. How programs give the terminal instructions
  2. What OSC can do
  3. Get notified when a command finishes
  4. Copy on the server, paste on your computer
  5. When you use tmux
  6. In ShellRS

You start a half-hour build on a server and want a desktop notification when it’s done. You copy a few lines in vim over SSH and want to paste them into your local browser. Your terminal’s window title keeps changing by itself. An option name in a compiler error opens its documentation when you click it. All of these rely on instructions that programs slip into their output for the terminal, and the most common kind is called OSC. Here’s what it is, what it can do and how to use it.

How programs give the terminal instructions

A program running in a terminal can only print text. To make the terminal do anything else, such as turn text red or change the window title, it mixes a short run of special characters into its output, starting with an invisible character called ESC. The terminal doesn’t show them but does what they say. These are called escape sequences; colors and cursor movement work this way.

OSC, short for Operating System Command, is one family of them. It covers things beyond the text on screen: the window title, the clipboard, desktop notifications, links. Each OSC carries a number that says what to do, followed by content such as the title or the message.

If you work over SSH, the useful part is that OSC is just output. A program on the server prints it with everything else, and it travels back over SSH to your local terminal unchanged. For keys going the other way, see the kitty keyboard protocol; for sending files over the same connection, see rz/sz and ZMODEM.

What OSC can do

The common ones:

Number What it does
0, 2 Sets the window or tab title
7 Tells the terminal the current folder, so it can open new tabs there
8 Turns a piece of text into a clickable link
9, 777 Shows a desktop notification
52 Puts text on your local clipboard

There’s no single standard behind them: 7, 8, 9 and 777 were added by various terminals, so support varies, and a terminal normally ignores ones it doesn’t know.

Why does the window title change by itself? Many shell setups use OSC to set it to something like “user@host:folder” each time the prompt appears, and some programs, Claude Code among them, set their own title while they run.

A link (OSC 8) works like one on a web page: you see some text, and behind it is an address. File names from ls --hyperlink and option names in error messages from GCC 10 and later are links of this kind. The spec asks terminals not to open them on a plain click, but on a modifier-click or from a context menu.

Get notified when a command finishes

There are two numbers for notifications. OSC 9 comes from iTerm2 and carries just a message; OSC 777 comes from rxvt-unicode (urxvt) and has a separate title as well. foot, WezTerm, Ghostty and ShellRS accept both, iTerm2 and kitty accept OSC 9, and rxvt-unicode accepts OSC 777.

Just add it after the command:

make; printf '\e]9;Build finished\a'

Replace make with your command; “Build finished” is the message. A ; rather than && means you hear about failures too. If your terminal only knows 777, use printf '\e]777;notify;Title;Message\a' instead. Don’t send both, or a terminal that knows both may notify you twice.

This works the same on a remote server: the notification travels back over SSH with the output and appears on your own desktop, with nothing to install on the server. Start the command and get on with something else.

Copy on the server, paste on your computer

Copy a few lines with y in vim over SSH, press ⌘V or Ctrl+V on your computer, and nothing comes out: the text lives in vim on the server, out of your clipboard’s reach.

OSC 52 is made for this. The program prints the text to copy inside an OSC 52 sequence, and the terminal puts it on your local clipboard. With an OSC 52 plugin in vim, or set-clipboard turned on in tmux (see the next section), what you copy goes straight to your computer.

OSC 52 can also work the other way round, asking the terminal to hand over what’s on the clipboard. That’s dangerous: any program that can print to your terminal, including one on a remote server, could quietly read a password you just copied. So terminals are careful about reads: some refuse them, others ask first. Writes are far less risky, since the worst case is a replaced clipboard, so many terminals allow them by default, though some want you to turn them on in their settings first. Still, cat on an untrusted file can change it, so glance at what you paste into a terminal.

When you use tmux

tmux is a terminal in its own right: a program’s output goes to tmux, which redraws the screen in the terminal outside, handling the OSC commands it knows and dropping the rest. So a notification sent inside tmux never reaches your terminal, and by default tmux doesn’t pass on what programs copy with OSC 52 either, only what you copy in its own copy mode.

Add two lines to ~/.tmux.conf:

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

Then run tmux source-file ~/.tmux.conf, or restart tmux. The first line lets what programs copy reach your computer. The second (tmux 3.3 and later) lets programs pass sequences tmux doesn’t know through to the outside, but the notification command needs a wrapper:

make; printf '\ePtmux;\e\e]9;Build finished\a\e\\'

on lets it through only while the pane is visible. If you’ll switch tmux windows while the command runs, use all (tmux 3.4 and later).

In ShellRS

ShellRS is a free, open-source SSH client for macOS, Windows and Linux. Here is how the things above work in it:

  • Notifications: both OSC 9 and OSC 777. When ShellRS isn’t in front you get a system notification that takes you to the terminal when clicked; when the terminal is in another tab, a notice appears at the top right of the window. The notification title is the tab name, so you can tell which host it came from. You can turn them off in Settings › Terminal › Notifications.
  • Clipboard: what remote programs copy with OSC 52 goes straight to your local clipboard. Remote programs can’t read it.
  • Links: links that programs mark, and http:// and https:// addresses in the output, are shown blue and underlined. ⌘-click (Ctrl-click on Windows and Linux) opens one in your browser; rest the pointer on it to see its real address.
  • Current folder: the Files sidebar follows the terminal’s current folder through OSC 7. If bash or zsh isn’t set up for it yet, ShellRS offers to do it for you.
  • Titles and colors: a local terminal’s tab shows the title its shell or program sets, and when vim or another program asks the terminal for its background color, it gets the current theme’s.

See the ShellRS manual, or get ShellRS from the download page.

Try ShellRS

A free, open-source SSH client: terminals, SFTP and port forwarding in one window, for macOS, Windows and Linux.