How a short escape sequence lets a program running inside any terminal — local, SSH, tmux — push text directly into your operating system's clipboard.
Terminals are just text streams. But over the decades, a set of escape sequences were standardised to let programs talk to the terminal emulator itself — not just print characters. These sequences are invisible; the terminal intercepts and acts on them.
OSC stands for Operating System Command. It's a family of escape sequences (all starting with ESC ]) that let a program make OS-level requests. There are many OSC codes: OSC 0 sets the window title, OSC 8 creates hyperlinks, and OSC 52 reads or writes the system clipboard.
Kitty, Alacritty, WezTerm, iTerm2, foot, and most modern VTE-based terminals. tmux and Zellij can forward OSC 52 sequences if configured. The classic xterm invented it; some older terminals silently ignore it.
The full OSC 52 write sequence looks like this:
\033] in bash. Bytes 0x1B 0x5D.c = clipboard. Others: p primary, q secondary, s select.\007 (bell char) or ESC \ (ST).So for the text hello, the full sequence sent to the terminal is:
Where aGVsbG8= is hello in base64. The terminal emulator sees this invisible sequence in its input stream, decodes the payload, and places hello into the OS clipboard — ready for Cmd+V anywhere.
| Part | Value | Description |
|---|---|---|
| \033] | ESC + ] — begins an OSC sequence. ESC is byte 0x1B. | |
| 52 | The OSC command number for clipboard access (XTerm standard). | |
| ; | Delimiter between command number and first parameter. | |
| c | clipboard | Which selection buffer to target. c = system clipboard. |
| ; | Delimiter between selection and payload. | |
| DATA | base64 | The actual text you want in the clipboard, base64-encoded. |
| \007 | BEL | Terminates the OSC sequence. Alternatively ESC \ (ST). |
Escape sequences are byte streams parsed by the terminal. If the clipboard payload contained raw bytes — especially control characters like newlines (0x0A), nulls (0x00), or another ESC (0x1B) — the terminal parser would misinterpret them as sequence terminators or new commands, corrupting or truncating the data.
Base64 encodes arbitrary binary as only printable ASCII characters (A–Z a–z 0–9 + / =), none of which are control characters. This guarantees the payload passes through the terminal parser intact, regardless of content — multi-line code, binary paths, Unicode, anything.
osc52copy through a pipe: echo "hello" | osc52copy, or a clipboard hook from an editor.
base64 -w 0 reads all of stdin and produces a single-line base64 string with no wrapping.
printf wraps the encoded string inside the escape sequence and writes it to stdout — which must be connected to the terminal.
osc52copy scriptThree lines. Click the i marker on any line to reveal its explanation.
/usr/bin/env bash finds bash via the PATH, making the script portable across systems where bash isn't at a fixed location like /bin/bash.
$(…) runs a subshell and captures its output into $buf. base64 reads all bytes from stdin and encodes them. The -w 0 flag disables line-wrapping — without it, base64 inserts newlines every 76 characters, which would break the OSC sequence by introducing a premature terminator.
printf is used instead of echo because it reliably interprets escape sequences. \033 is the ESC byte (octal 033 = hex 0x1B). %s is substituted with $buf. \007 is the BEL byte — the OSC sequence terminator. The whole sequence flows to stdout, which must be the terminal device for the terminal emulator to intercept it.
echo "hello world" | osc52copy or cat file.txt | osc52copy. As long as the script's stdout reaches the terminal emulator, the clipboard will be set.