Skip to main content
ansicode
OSC (terminal control)

OSC escape codes — window title, hyperlinks, colour palette

Operating System Command. The ESC ] n ; payload BEL (or ESC \ terminated) family — window / icon title, the OSC 8 hyperlink protocol, dynamic colour queries, palette overrides, working-directory reporting. The protocol layer that lets terminals talk back to and configure the emulator itself.

20 sequences

When to use OSC

Reach for OSC when you need to drive the terminal's chrome rather than the glyph grid — window / tab title, clickable hyperlinks, the palette itself, shell prompt marks, the OS clipboard, inline images, taskbar progress. OSC sequences open with \x1b]<n>;<payload> and close on a BEL (\x07) or ST (\x1b\\) terminator — always emit the terminator or the parser eats your next output as title text. Each numeric <n> is a wholly different feature (0 = title, 7 = cwd, 8 = hyperlink, 52 = clipboard, 104 = palette reset, 133 = prompt marks, 1337 = inline image, 9;4 = progress). Use SGR for in-grid colour, CSI for cursor / erase, DEC for modes — OSC is the lane for everything outside the text grid.

Common OSC one-liners

Paste any of these into bash / zsh — printf interprets the \x1b byte.

  • Set window + tab title
    printf '\x1b]0;%s\x07' 'build: passing'
  • OSC 8 clickable hyperlink
    printf '\x1b]8;;https://ansicode.dev\x07link\x1b]8;;\x07\n'
  • Copy to OS clipboard (OSC 52)
    printf '\x1b]52;c;%s\x07' "$(printf hello | base64)"

OSC cookbook — driving the terminal chrome with six recipes

OSC sits one layer outside CSI — instead of painting glyphs in the grid, OSC drives the terminal's surrounding chrome: window title, hyperlinks, the colour palette itself, shell-integration markers, inline images, progress bars. Six stops cover the envelope syntax, window/tab titles as the canonical example, the OSC 8 hyperlink protocol, palette overrides, the FinalTerm OSC 133 prompt marks that turn a flat byte stream into structured blocks, and the OSC 1337 + OSC 9;4 codes that talk to the host OS's taskbar.

  1. 1. The envelope — \x1b]\x07 or \x1b\\

    Every OSC sequence is \x1b] (ESC ]), a numeric Ps (0, 8, 133, etc.), then ;-separated payload, then a terminator. Two terminators are both valid: \x07 (BEL — xterm's original de-facto choice, one byte) and \x1b\\ (ST — ECMA-48 standards-correct, two bytes spelt ESC \). Modern emulators accept both; reach for BEL on a one-shot shell printf, reach for ST when you're nesting OSC inside DCS or tmux pass-through where BEL would mean something else. There's also an 8-bit C1 form \x9d … \x9c you'll see in old VT manuals but never in the wild. Always emit the terminator — a missing BEL/ST hangs the parser until the next byte that happens to be one, so the next stray ^G in your output silently closes your OSC and treats everything past it as text.

  2. 2. Window & tab titles — OSC 0 / 1 / 2

    The canonical OSC sequence: \x1b]0;TITLE\x07 sets both the window title bar and the icon name (taskbar text on Windows, dock-icon hover text on macOS). Sub-codes split the two: OSC 1 icon name only, OSC 2 window title only — useful when your shell wants the window title to stay pinned to the project while the icon flashes an attention-state. The common shell idiom wires it into PROMPT_COMMAND / precmd: printf '\033]0;%s — %s\007' "$USER@$HOST" "$(basename "$PWD")" redraws the title every prompt with the current directory. Inside tmux / screen the inner OSC needs the \ePtmux;\e DCS wrapper or it won't reach the outer terminal — tmux's set-option -g set-titles on does the wrapping for you. Supported everywhere except the bare Linux console (no chrome to set).

  3. 4. Palette overrides — OSC 4 / 10 / 11 / 104

    Four codes let you repaint the palette itself rather than picking from it. \x1b]4;n;rgb:RR/GG/BB\x1b\\ overrides slot n (0–255) of the xterm 256-palette for this session — so \e]4;1;rgb:e0/3a/3a\e\\ retunes the red that \x1b[31m will use from then on. OSC 10 and OSC 11 change the default foreground and default background colours independent of the indexed palette — handy for a TUI to dim the chrome behind a modal without touching any text colour. The matching reset is \x1b]104;n\x1b\\ (revert one slot to compiled-in default) or bare \x1b]104\x1b\\ to revert every slot at once; OSC 110 / OSC 111 (no args) reset default fg / bg respectively. The colour string accepts the X11 rgb:RRRR/GGGG/BBBB long form too, plus #rrggbb on most emulators.

  4. 5. Shell prompt marks — OSC 133 (FinalTerm A / B / C / D)

    FinalTerm's OSC 133 turns a shell session from a flat byte stream into structured blocks the terminal can navigate. Four codes mark boundaries: \x1b]133;A\x07 before the prompt, \x1b]133;B\x07 between prompt and user input, \x1b]133;C\x07 between Enter and the command's stdout, \x1b]133;D;<exit>\x07 after the command exits (exit code optional). Kitty, iTerm2, WezTerm, Ghostty, Warp, and VS Code's terminal then expose UX you can't fake otherwise: jump to previous / next prompt with a keystroke, fold a single command's output, decorate the gutter with red-triangle / green-tick based on exit code, scroll one command at a time. Wire it into your PS1 + preexec + precmd hooks (atuin, starship, and the emulator-bundled scripts do it for you). Pair with \x1b]7;file://host/path\x1b\\ (OSC 7, cwd advertising) so the terminal also knows where each block ran — together they're the full shell-integration story.

  5. 6. Inline images & progress — OSC 1337 and OSC 9 ; 4

    Two out-of-band OSC codes drive the host OS's window chrome rather than painting glyphs. \x1b]1337;File=name=<b64>;inline=1:<b64-payload>\x07 is iTerm2's inline-image protocol — the same vocabulary covers PNG, JPEG, animated GIF, PDF — and is the path the imgcat shell script uses (iTerm2 ships it; WezTerm and Konsole 22.04+ implement the File= subset). The same OSC 1337 envelope also carries non-File subcodes (SetUserVar, SetMark, ReportCellSize) for status-bar variables, navigation marks, and pixel-accurate Sixel sizing. \x1b]9;4;<state>;<pct>\x07 is the ConEmu progress protocol Windows Terminal 1.18+ standardised — state=1 normal, 2 error, 3 indeterminate, 4 paused, 0 clear — and the terminal forwards it to the OS taskbar (WT) or tab indicator (Ghostty, WezTerm). Don't confuse it with iTerm2's OSC 9 ; <message> notification: the ;4 second token is the disambiguator, so always emit the full shape. Both are safe to emit unconditionally — unsupported emulators silently drop the bytes.

All sequences in this family

Browse other families