Every Mac ships with two command-line utilities that most developers underuse: pbcopy and pbpaste. They bridge the gap between your terminal and the system clipboard — the same NSPasteboard that every GUI app reads and writes.
If you've ever manually selected terminal output, pressed ⌘C, then switched to another app to paste — you're doing it wrong. pbcopy does this in a single pipe. And pbpaste lets you pull clipboard content into any command chain without touching the mouse.
These two commands are deceptively simple. Mastering them eliminates an entire class of friction in terminal-heavy workflows.
pbcopy — send to clipboard
pbcopy reads from standard input and places the content on the system clipboard. That's it. No flags you need to worry about (there's one for RTF vs plain text, but you'll almost never use it).
# Copy a string to clipboard
echo "hello" | pbcopy
# Copy file contents to clipboard
cat ~/.ssh/id_rsa.pub | pbcopy
# Copy command output to clipboard
pwd | pbcopy
# Copy a file path
ls -la /path/to/file | pbcopy
The critical thing to understand: pbcopy writes to the exact same clipboard you use with ⌘C. After running echo "test" | pbcopy, you can switch to any app and press ⌘V to paste "test". It's the same clipboard. Same NSPasteboard. Same data store.
This means anything copied via pbcopy also appears in your clipboard manager's history. QuietClip picks it up identically to a GUI copy.
# Copy your IP address
curl -s ifconfig.me | pbcopy
# Copy a git hash
git rev-parse HEAD | pbcopy
# Copy the contents of a file without opening it
pbcopy < README.md
That last form — pbcopy < file — is worth memorizing. It's the fastest way to get file contents onto your clipboard without cat.
pbpaste — read from clipboard
pbpaste outputs the current clipboard contents to stdout. Whatever was last copied — via ⌘C in any app or via pbcopy — comes out as standard output that you can redirect, pipe, or capture.
# Print clipboard contents
pbpaste
# Save clipboard to a file
pbpaste > snippet.txt
# Count words in clipboard
pbpaste | wc -w
# Count lines in clipboard
pbpaste | wc -l
This is enormously useful when you copy something in a GUI app and want to process it in the terminal. Copy a block of text from a webpage, then:
# Sort lines you copied
pbpaste | sort
# Remove duplicates from copied list
pbpaste | sort -u
# Search for a pattern in copied text
pbpaste | grep "TODO"
pbcopy and pbpaste turn your clipboard into a Unix pipe junction — everything flows through it, and any command can tap in or out.
Piping patterns — the real power
The magic of pbcopy and pbpaste is composability. They slot into any pipe chain, letting you move data between the GUI world and the terminal world seamlessly.
Filter and re-copy:
# Copy only lines containing "error" from clipboard
pbpaste | grep -i "error" | pbcopy
# Extract emails from copied text
pbpaste | grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | pbcopy
# Remove blank lines from clipboard
pbpaste | grep -v '^$' | pbcopy
Transform clipboard contents:
# Convert clipboard to uppercase
pbpaste | tr '[:lower:]' '[:upper:]' | pbcopy
# Replace tabs with spaces in clipboard
pbpaste | expand -t 4 | pbcopy
# Add line numbers to copied text
pbpaste | nl -ba | pbcopy
# URL-encode clipboard contents
pbpaste | python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))" | pbcopy
Extract and format:
# Get column 2 from copied TSV data
pbpaste | awk -F'\t' '{print $2}' | pbcopy
# JSON pretty-print clipboard
pbpaste | python3 -m json.tool | pbcopy
# Extract URLs from copied HTML
pbpaste | grep -oE 'https?://[^ "]+' | pbcopy
The clipboard transform loop
- Copy something in any app (⌘C)
- Transform it in terminal:
pbpaste | <transform> | pbcopy - Paste the result anywhere (⌘V)
This three-step pattern — copy, transform, paste — handles dozens of micro-tasks that would otherwise require a dedicated tool.
Shell scripting with the clipboard
pbcopy and pbpaste work in shell scripts exactly as you'd expect. Some patterns I use constantly:
Clipboard as variable:
# Capture clipboard to a variable
content=$(pbpaste)
echo "Clipboard has ${#content} characters"
# Use clipboard in a conditional
if pbpaste | grep -q "password"; then
echo "Warning: clipboard may contain a password"
fi
Batch processing:
# Process each line of clipboard separately
pbpaste | while IFS= read -r line; do
echo "Processing: $line"
done
Git shortcuts:
# Copy current branch name
git branch --show-current | pbcopy
# Copy last commit message
git log -1 --pretty=%B | pbcopy
# Copy diff for pasting into a PR comment
git diff --staged | pbcopy
Shell aliases worth adding to your .zshrc:
# Copy current directory path
alias cpwd='pwd | pbcopy'
# Copy last command
alias cplast='fc -ln -1 | pbcopy'
# Paste and execute (careful with this one)
alias pepaste='pbpaste | bash'
# Copy file contents
cpfile() { pbcopy < "$1"; }
Be careful with pbpaste | bash or pbpaste | sh in scripts. You're executing arbitrary clipboard content. If someone tricks you into copying a malicious command, this pattern will run it. Only use this with content you've deliberately placed on the clipboard yourself.
Beyond plain text — content types and AppleScript
pbcopy handles plain text by default. You can pass -Prefer rtf to handle RTF content, but it's rarely useful in practice. For anything beyond text — images, files, custom types — you need to go through AppleScript or Swift.
AppleScript clipboard access:
# Get clipboard as text via osascript
osascript -e 'the clipboard'
# Set clipboard via osascript
osascript -e 'set the clipboard to "hello from AppleScript"'
# Get clipboard info (shows available types)
osascript -e 'clipboard info'
The clipboard info command is fascinating — it shows you every data type currently on the clipboard. Copy a formatted paragraph from a webpage and run it to see the multiple representations (plain text, HTML, RTF, etc.) stored simultaneously.
The NSPasteboard connection:
Here's what's happening under the hood: pbcopy, pbpaste, ⌘C, and ⌘V all interact with the same NSPasteboard.general instance. There's one system clipboard. Every access method — GUI, terminal, AppleScript, Swift — reads from and writes to the same place.
This means a clipboard manager like QuietClip captures everything identically, regardless of source. Copy via pbcopy in a script, via ⌘C in VS Code, or via AppleScript automation — it all ends up in your history.
If you pipe output through pbcopy frequently, pair it with a clipboard manager. Every command output, git hash, and file path you copy stays in your searchable history. Instead of re-running a command to get its output, just search your clipboard history for it.
Every pbcopy stays in your history.
QuietClip captures everything you copy — terminal output included. Search your clipboard history for any command output, git hash, or file path you piped through pbcopy. Free to start, $8.99 once for Pro.