---
title: Copy to Clipboard From the Terminal: xclip, pbcopy | Relic
description: xclip, pbcopy, wl-copy and clip.exe all pipe command output to the clipboard. The newline, encoding and WSL traps we hit on Windows, and OSC 52 for SSH.
canonical: https://relic.space/blog/copy-to-clipboard-from-the-command-line
source: https://relic.space/llms.txt
---
[Developer cheat sheets](https://relic.space/blog/topics/dev-reference)

# How to copy to the clipboard from the command line

Pipe the output into the clipboard tool your system already has: pbcopy on a Mac, xclip or wl-copy on Linux, clip or Set-Clipboard on Windows. Copying is the easy part. The problems are an extra newline at the end, accented letters turning into junk, and Linux having more than one clipboard.

[JGJordan Gibbs](https://relic.space/authors/jordan-gibbs) October 20, 2026 8 min read

## How do you copy to the clipboard from the command line?

* **Mac:** `command | pbcopy`, and `pbpaste` to read it back.
* **Linux on X11:** `command | xclip -selection clipboard`, and add `-o` to paste.
* **Linux on Wayland:** `command | wl-copy`, and `wl-paste` to paste.
* **Windows:** `command | clip` in Command Prompt, or `Set-Clipboard` and `Get-Clipboard` in PowerShell.
* **WSL:** `command | clip.exe`, and `powershell.exe Get-Clipboard` to paste.
* **Over SSH:** an OSC 52 escape code that your local terminal turns into a copy.

This page is about moving text between commands and the clipboard. For the keys that copy and paste inside a terminal window, see [copy and paste in the terminal](https://relic.space/blog/copy-and-paste-in-the-terminal).

|                   | Copy          | Paste               | No trailing newline    |
| ----------------- | ------------- | ------------------- | ---------------------- |
| macOS             | pbcopy        | pbpaste             | printf '%s' "$(cmd)"   |
| Linux, X11        | xclip -sel c  | xclip -sel c -o     | xclip -r               |
| Linux, X11 (xsel) | xsel -bi      | xsel -bo            | tr -d '\\n' (one line) |
| Linux, Wayland    | wl-copy       | wl-paste -n         | wl-copy -n             |
| Command Prompt    | clip          | none built in       | echo adds CRLF         |
| PowerShell        | Set-Clipboard | Get-Clipboard -Raw  | adds none              |
| WSL               | clip.exe      | powershell.exe      | tr -d '\\r'            |
| SSH               | OSC 52        | depends on terminal | strip it first         |

## pbcopy and pbpaste on a Mac

Both come with macOS. `pbcopy` reads standard input and puts it on the clipboard. `pbpaste` writes the clipboard to standard output. Because they are plain pipes, you can chain them.

macOS terminal

pwd | pbcopy                       # the current folder's path
pbcopy < ~/.ssh/id_ed25519.pub     # a whole file
pbpaste > snippet.txt              # clipboard into a file
pbpaste | sort -u | pbcopy         # tidy what you just copied
printf '%s' "$(git rev-parse HEAD)" | pbcopy   # no newline at the end

The last line handles the newline. Most commands end their output with one, and pbcopy copies it as is. Paste a commit hash into a terminal and that newline acts like Enter. Wrapping the command in `"$(...)"` strips it, because command substitution drops trailing newlines. The same trick matters when you [copy a file path](https://relic.space/blog/how-to-copy-a-file-path) with `pwd`.

The [pbcopy man page](https://keith.github.io/xcode-man-pages/pbcopy.1.html) says both tools pick their encoding from your locale variables, such as `LANG=en_US.UTF-8`. Terminal sets a UTF-8 locale by default, so accented letters come through. A cron job or a bare SSH session may have no locale set, and then non-ASCII text can get mangled. Export a UTF-8 locale in the script if you see that. Two lesser-known flags: `-pboard find` uses the separate Find pasteboard, and `pbpaste -Prefer rtf`asks for rich text when it’s there.

## How do you use xclip on Linux?

X11 has more than one clipboard. The [Arch Wiki](https://wiki.archlinux.org/title/Clipboard) lays it out. PRIMARY holds whatever you last highlighted, and a middle click pastes it. CLIPBOARD is the one Ctrl+C and Ctrl+V use. The [xclip man page](https://manpages.debian.org/trixie/xclip/xclip.1.en.html) lists PRIMARY as the default. So `echo hi | xclip` runs without an error, and then Ctrl+V pastes something else. Add `-selection clipboard` every time.

X11 terminal

sudo apt install xclip

echo "hello" | xclip -selection clipboard
xclip -sel c < notes.txt                  # options can be shortened
xclip -sel c -o                           # print the clipboard
git rev-parse HEAD | xclip -sel c -r      # drop the last newline
xclip -sel c -t image/png -i shot.png     # copy an image
xclip -sel c -o -t TARGETS                # list the formats on offer

The man page allows shortened options as long as they stay unambiguous, so `-sel c` means `-selection clipboard`. The `-r` flag removes one newline at the very end and leaves the rest alone.

xclip doesn’t exit right away. It forks into the background and keeps serving the text until another program takes over the clipboard. That’s how X11 works: the program that copied holds the data. Close it and the copy can disappear. A [clipboard manager for Linux](https://relic.space/clipboard-manager-linux) grabs the text so it outlives the program.

### xsel and the pbcopy aliases

xsel does the same job with different flags. It also defaults to PRIMARY, says [its man page](https://manpages.debian.org/trixie/xsel/xsel.1x.en.html), so add `-b`.

xsel

echo "hello" | xsel --clipboard --input     # same as xsel -bi
xsel --clipboard --output                   # same as xsel -bo

If your fingers already type the Mac names, two aliases in `~/.bashrc` make them work on an X11 machine.

\~/.bashrc

alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'

## What replaces xclip on Wayland?

Ubuntu and Fedora both start a Wayland session by default. xclip and xsel speak X11, so on Wayland they only reach apps through the XWayland compatibility layer, when it’s running. The native tools are `wl-copy` and `wl-paste` from the [wl-clipboard](https://github.com/bugaevc/wl-clipboard)package. Check which session you’re in first.

Wayland terminal

echo $XDG_SESSION_TYPE             # prints wayland or x11
sudo apt install wl-clipboard

ls -la | wl-copy
wl-copy -n < token.txt             # leave off the trailing newline
wl-paste -n > out.txt              # paste without adding one
wl-copy < diagram.png              # images work too
wl-paste --list-types              # see what is on the clipboard
wl-copy --paste-once < secret.txt  # gone after the first paste

The newline rules run in opposite directions. The [wl-clipboard man page](https://man.archlinux.org/man/wl-clipboard.1.en) says `wl-copy -n` drops a trailing newline from the input. Separately, `wl-paste` adds a newline to text it prints, unless you pass `-n`. Like xclip, wl-copy forks into the background to serve pastes; `-f` keeps it in the foreground.

One oddity: on a compositor without the wlroots data-control protocol, wl-clipboard briefly opens a tiny invisible window to reach the clipboard. You may see a flicker. The man page warns it can hang if the compositor won’t focus that window.

## clip, Set-Clipboard and Get-Clipboard on Windows

Command Prompt has `clip`. [Microsoft’s page for it](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/clip) shows two forms and says nothing about encoding or line endings. Those are where it goes wrong, so we tested them. We ran everything in this section on 20 October 2026, on Windows 11 build 26200 with Windows PowerShell 5.1, Git Bash 5.2 and WSL 2.6.3 running Ubuntu 24.04.

Command Prompt

dir | clip
clip < readme.txt

rem clip reads UTF-8 correctly once the code page is 65001
chcp 65001 >nul
clip < notes-utf8.txt

* `echo hello| clip` put `hello` plus a carriage return and line feed on the clipboard. The newline from echo stays.
* Text piped in with Unix line feeds came out with Windows CRLF line endings.
* UTF-8 broke. clip read the bytes using the console code page (437 on our machine). The word `café` came out as `caf├⌐`. Running `chcp 65001` first fixed it.
* UTF-16LE input copied cleanly. If the text starts with a byte order mark, clip keeps it as an invisible character at the start of the clipboard. It can break a pasted password or token.

In PowerShell, use `Set-Clipboard`. Piping to `clip.exe` from Windows PowerShell 5.1 sends text in ASCII by default, so `café ✓` landed as `caf? ?`. Set-Clipboard copied the same string exactly, with no newline added.

PowerShell

Set-Clipboard -Value "café ✓"
Get-Content .\notes.txt -Raw | Set-Clipboard
Get-ChildItem | Out-String | Set-Clipboard    # the listing as text

Get-Clipboard              # one string per line
Get-Clipboard -Raw         # one string, line breaks kept
Get-Clipboard -Format FileDropList            # files copied in Explorer

Two more things to know. [Get-Clipboard](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-clipboard) returns an array with one string per line, and `-Raw` returns a single string. And piping file objects straight into Set-Clipboard in 5.1 copied the files themselves, so the text clipboard came back empty. Add `Out-String` when you want the listing as text. Git Bash users get one more option. `cat file > /dev/clipboard` copied UTF-8 text correctly in our test and kept the Unix line endings.

### WSL: clip.exe and powershell.exe

WSL can run Windows programs by name, with the `.exe` on the end, as [Microsoft’s WSL docs](https://learn.microsoft.com/en-us/windows/wsl/filesystems) describe. So `clip.exe` works from a Linux shell. It brings the same encoding bug with it: UTF-8 from Ubuntu came out garbled. Converting to UTF-16LE with iconv fixed it.

WSL shell

echo "build ok" | clip.exe                       # fine for plain ASCII
iconv -f UTF-8 -t UTF-16LE notes.txt | clip.exe   # keeps accents and symbols

powershell.exe -NoProfile -Command '[Console]::OutputEncoding = [Text.Encoding]::UTF8; Get-Clipboard -Raw' | tr -d '\r'

Pasting needs care too. A plain `powershell.exe Get-Clipboard` printed `é` as a single byte from code page 437, which Linux reads as junk. Setting the output encoding to UTF-8 inside the command fixed it. PowerShell ends its output with CRLF, so `tr -d '\r'` cleans up the carriage returns. One line feed is still left at the end.

WSLg sets `WAYLAND_DISPLAY` and `DISPLAY` inside WSL, and we saw both on our Ubuntu install. A script that checks for Wayland or X11 first will reach for wl-copy or xclip, which may not be installed. Check for WSL first.

## How do you copy to your local clipboard over SSH?

Running pbcopy or xclip on a server copies to the server, which is useless to you. The fix is an escape sequence called OSC 52\. The program prints it, and your local terminal sets your local clipboard from it. xterm’s [control sequence reference](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html) lists it as “Manipulate Selection Data”. The text inside travels as [Base64](https://relic.space/blog/what-is-base64-encoding), and your terminal has to allow it. Windows Terminal does, according to the [Set-Clipboard docs](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-clipboard), which also mention the `-AsOSC52` switch added in PowerShell 7.4\. tmux needs a setting before it passes the code through, and the [terminal copy and paste guide](https://relic.space/blog/copy-and-paste-in-the-terminal) covers that, plus iTerm2.

## One function for every machine

These two functions pick the right tool for wherever you are. SSH comes first, so a remote shell copies to your own machine. WSL comes next, for the reason in the note above. We tested the WSL and Git Bash branches, including accented text, on the setup listed earlier. The Mac and Linux desktop branches use the commands from their man pages, and we didn’t run them on those systems.

\~/.bashrc or \~/.zshrc

# Put these in ~/.bashrc or ~/.zshrc
copyclip() {
  if [ -n "$SSH_TTY" ]; then
    printf '\033]52;c;%s\a' "$(base64 | tr -d '\n')"
  elif [ -n "$WSL_DISTRO_NAME" ]; then
    iconv -f UTF-8 -t UTF-16LE | clip.exe
  elif command -v pbcopy >/dev/null 2>&1; then
    pbcopy
  elif [ -n "$WAYLAND_DISPLAY" ] && command -v wl-copy >/dev/null 2>&1; then
    wl-copy
  elif [ -n "$DISPLAY" ] && command -v xclip >/dev/null 2>&1; then
    xclip -selection clipboard
  elif [ -e /dev/clipboard ]; then
    cat > /dev/clipboard
  else
    echo "copyclip: no clipboard tool found" >&2
    return 1
  fi
}

pasteclip() {
  if [ -n "$WSL_DISTRO_NAME" ]; then
    powershell.exe -NoProfile -Command '[Console]::OutputEncoding = [Text.Encoding]::UTF8; Get-Clipboard -Raw' | tr -d '\r'
  elif command -v pbpaste >/dev/null 2>&1; then
    pbpaste
  elif [ -n "$WAYLAND_DISPLAY" ] && command -v wl-paste >/dev/null 2>&1; then
    wl-paste --no-newline
  elif [ -n "$DISPLAY" ] && command -v xclip >/dev/null 2>&1; then
    xclip -selection clipboard -o
  elif [ -e /dev/clipboard ]; then
    cat /dev/clipboard
  else
    echo "pasteclip: no clipboard tool found" >&2
    return 1
  fi
}

The names avoid `paste`, which is already a coreutils command. Once they load, a line like `curl -s $URL | jq -r '.token' | copyclip` should behave the same on each of your machines. The [jq cheat sheet](https://relic.space/blog/jq-cheat-sheet) has more filters for that middle step. If [Relic](https://relic.space/)runs on the desktop, everything you pipe to the clipboard also lands in its searchable history, so Monday’s output is still there on Friday.

## Sources

* [xclip(1) manual page](https://manpages.debian.org/trixie/xclip/xclip.1.en.html), Debian Manpages
* [wl-clipboard(1) manual page](https://man.archlinux.org/man/wl-clipboard.1.en), Arch manual pages
* [clip command reference](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/clip), Microsoft Learn
* [Set-Clipboard](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-clipboard), Microsoft Learn

JG

Written by

[Jordan Gibbs](https://relic.space/authors/jordan-gibbs)Founder, Relic

Jordan Gibbs is the founder of Relic, an end-to-end encrypted, permanent, searchable memory for everything you copy. He writes widely about AI, agents, and practical tooling on Medium, where he is read by tens of thousands, and builds privacy-first software. Here he covers how everyday tools like the clipboard actually work, and how to use them without handing your data to someone else.

[Medium](https://medium.com/@jordan%5Fgibbs)[GitHub](https://github.com/jordan-gibbs)[LinkedIn](https://www.linkedin.com/in/jordan--gibbs/)

Part of

[Developer cheat sheets](https://relic.space/blog/topics/dev-reference)
* [Regex cheat sheet· pillar](https://relic.space/blog/regex-cheat-sheet)
* [How to copy and paste in Vim](https://relic.space/blog/how-to-copy-and-paste-in-vim)
* [What AI crawlers fetch from a small open-source site: 31 days of logs](https://relic.space/blog/ai-crawlers-on-a-small-site)
* [JSONPath examples](https://relic.space/blog/jsonpath-examples)
* [jq cheat sheet](https://relic.space/blog/jq-cheat-sheet)
* [wget vs curl: what is the difference?](https://relic.space/blog/wget-vs-curl)
* [Subnet cheat sheet](https://relic.space/blog/subnet-cheat-sheet)
* [Port numbers list](https://relic.space/blog/port-numbers-list)
* [Ed25519 vs RSA](https://relic.space/blog/ed25519-vs-rsa)
* [TOML vs YAML](https://relic.space/blog/toml-vs-yaml)

Keep reading

[Pillar·10 minRegex cheat sheetThe regex pieces you actually reach for, character classes through lookarounds, with the flavor differences that bite you and a handful of patterns worth saving.Read ](https://relic.space/blog/regex-cheat-sheet)[9 minHow to copy and paste in Vimy copies and p pastes, but only inside Vim. How registers work, how to reach the system clipboard when your build says -clipboard, and how to copy out over SSH and in tmux.Read ](https://relic.space/blog/how-to-copy-and-paste-in-vim)[9 minWhat AI crawlers fetch from a small open-source site: 31 days of logsWe checked every request that claimed to be GPTBot, ClaudeBot, PerplexityBot and the rest against the operators' published IP lists. Then we looked at what the real ones read. The data is downloadable.Read ](https://relic.space/blog/ai-crawlers-on-a-small-site)

developerreferencehow-to
