Pipe to/from the clipboard in a Bash script

Viewed 717548

Is it possible to pipe to/from the clipboard in Bash?

Whether it is piping to/from a device handle or using an auxiliary application, I can't find anything.

For example, if /dev/clip was a device linking to the clipboard we could do:

cat /dev/clip        # Dump the contents of the clipboard
cat foo > /dev/clip  # Dump the contents of "foo" into the clipboard
32 Answers

There are a wealth of clipboards you could be dealing with. I expect you're probably a Linux user who wants to put stuff in the X Windows primary clipboard. Usually, the clipboard you want to talk to has a utility that lets you talk to it.

In the case of X, there's xclip (and others). xclip -selection c will send data to the clipboard that works with Ctrl + C, Ctrl + V in most applications.

If you're on Mac OS X, there's pbcopy. E.g., cat example.txt | pbcopy

If you're in Linux terminal mode (no X) then look into gpm or Screen which has a clipboard. Try the Screen command readreg.

Under Windows 10+ or Cygwin, use /dev/clipboard or clip.

Try

xclip

xclip - command line interface to X selections (clipboard) 

man

I have found a good reference: How to target multiple selections with xclip

In my case, I would like to paste content on the clipboard and also to see what is been pasted there, so I used also the tee command with a file descriptor:

echo "just a test" | tee >(xclip -i -selection clipboard)

>() is a form of process substitution. Bash replaces each with the path to a file descriptor which is connected to the standard input of the program within the parentheses.

The teecommand forks your command allowing you to "pipe its content" and see the result on standard output "stdout".

You can also create aliases to get and write on the clipboard, allowing you to use "pbcopy" and "pbpaste" as if you where on Mac. In my case, as I use Z shell (zsh), I have this in my aliases file:

(( $+commands[xclip] )) && {
    alias pbpaste='xclip -i -selection clipboard -o'
    alias pbcopy='xclip -selection clipboard'
}

The (( $+command[name] )) in Z shell tests if the command "name" is installed on your system, and then both aliases are grouped with {}. The && is a binary AND; if a then b, hence if you have xclip then the aliases will be set.

echo "another test" | tee >(pbcopy)

To get your clipboard content, just type:

pbpaste | "any-command-you-need-here"

pbcopy is built into OS X:

Copying the content of file .bash_profile:

cat ~/.bash_profile | pbcopy

I just searched the same stuff in my KDE environment.

Feel free to use clipcopy and clippaste.

KDE:

> echo "TEST CLIP FROM TERMINAL" | clipcopy
> clippaste
TEST CLIP FROM TERMINAL

In Linux this works:

cat filename | xclip

The Ruby oneliner inspired me to try with Python.

Say we want a command that indents whatever is in the clipboard with four spaces. It is perfect for sharing snippets on Stack Overflow.

$ pbpaste | python -c "import sys
 for line in sys.stdin:
   print(f'    {line}')" | pbcopy

That's not a typo. Python needs newlines to do a for loop. We want to alter the lines in one pass to avoid building up an extra array in memory.

If you don't mind building the extra array try:

$ pbpaste | python -c "import sys; print(''.join([f'    {l}' for l in sys.stdin]))" | pbcopy

but honestly awk is better for this than python. I defined this alias in my ~/.bashrc file

alias indent="pbpaste | awk '{print \"    \"\$0}' | pbcopy"

Now when I run indent, whatever is in my clipboard is indented.

From this thread, there is an option which does not require installing any gclip/xclip/xsel third-party software.

A Perl script (since Perl is usually always installed)

use Win32::Clipboard;
print Win32::Clipboard::GetText();

On Wayland, xcopy doesn't seem to work. Use wl-clipboard instead.

E.g., on Fedora:

sudo dnf install wl-clipboard

tree | wl-copy

wl-paste > file

Yesterday I found myself with the question: "How can I share the clipboard between different user sessions?". When switching between sessions with Ctrl + Alt + F7 - Ctrl + Alt + F8, in fact, you can't paste what you copied.

I came up with the following quick & dirty solution, based on a named pipe. It is surely quite bare and raw, but I found it functional:

user1@host:~$ mkfifo /tmp/sharedClip

then in the sending terminal

user1@host:~$ cat > /tmp/sharedClip

last, in the receiving terminal:

user2@host:~$ cat /tmp/sharedClip

Now, you type or paste anything in the first terminal, and (after hitting Return), it will appear immediately in the receiving terminal, from where you can copy and paste again anywhere you like.

Of course this doesn't just strictly take the content from user1's clipboard to make it available in user2's clipboard, but rather it requires an additional pair of Paste & Copy clicks.

In macOS, use pbpaste.

For example:

Update the clipboard

pbpaste  | ruby -ne ' puts "\|" + $_.split( )[1..4].join("\|") ' | pbcopy

A way to paste from the clipboard to a file without any tools except echo.

  1. Escape single quotes in the text you want to paste: replace all occurrences of ' with '\'' and copy the result to clipboard.
  2. Type echo -n '
  3. Press Shift + Insert
  4. Type ' > filename.txt
  5. Press Enter

Basically you're doing this:

echo -n 'copied "text" with '\''single quotes'\'' escaped' > filename.txt

It works even if the copied text has new lines.

For mac you can use this function which uses pbcopy and pbpaste, but a little easier:

Add this to your .bashrc or .zshrc:

clp() {
  if [[ -z "$1" ]]
  then
    # No input - act as paste
    pbpaste;
  else
    # Input exists - act as copy
    echo "$1" | pbcopy;
  fi
}

To copy use clp "Content" and to paste use clp

This function will test what clipboard exists and use it.

To verify copy paste into your shell, and then call the function clippaste:

clippaste () {
    if [[ $OSTYPE == darwin* ]]
    then
            pbpaste
    elif [[ $OSTYPE == cygwin* ]]
    then
            cat /dev/clipboard
    else
            if command -v xclip &> /dev/null
            then
                    xclip -out -selection clipboard
            elif command -v xsel
            then
                    xsel --clipboard --output
            else
                    print "clipcopy: Platform $OSTYPE not supported or xclip/xsel not installed" >&2
                    return 1
            fi
    fi
}
Related