Paul Calnan
Published August 2, 2013

I do a lot of work via SSH on a remote Linux server. It is often useful to transfer text from that server back to my local machine. Rather than save to a file and scp it down to my local machine, I adapted this process to allow me to copy to my local pasteboard from a remote machine.

Note, I use port 50730 for this. I can't remember why I picked that number. Regardless, it's arbitrary and you should be able to choose something else if you prefer.

Step 1: Create a pasteboard daemon

On Mac OS X, this is fairly easy using a Launch Agent.

Save the following XML property list file in ~/Library/LaunchAgents/com.paulcalnan.pbcopy.plist on your local machine:

Note that I use my domain name, com.paulcalnan, in the daemon and file name. You can call it whatever you like.

Step 2: Load the daemon

From the Terminal on your local machine, run:

launchctl load ~/Library/LaunchAgents/com.paulcalnan.pbcopy.plist

Step 3: Configure SSH port forwarding

Add the following to your local machine's ~/.ssh/config file:

RemoteForward 50730 127.0.0.1:50730

Step 4: Create a remote pbcopy script

Add the following file to the remote server as ~/bin/pbcopy and make it executable:

#!/usr/bin/env bash
cat | nc localhost 50730

This assumes ~/bin is on your PATH. If the remote host runs OS X, you should name it something else, like rpbcopy, to prevent confusion with the built-in pbcopy.

Step 5: Try it out

From the remote server, run a command and pipe the output through pbcopy:

uptime | pbcopy

Back on your local machine, paste into a text editor.

Bonus tmux Trick

Most of the time, I use tmux to manage multiple consoles in the same SSH session. When I split the window horizontally, it breaks my ability to select multiple lines of text with the mouse.

To copy from a tmux session, I do a Ctrl-A [, select text I want to copy, and press Enter (I use Ctrl-A instead of Ctrl-B for my prefix). That puts the selected text in the tmux buffer. To copy the tmux buffer contents, I run tmuxcp, defined as an alias in my .bashrc:

alias tmuxcp='tmux save-buffer - | pbcopy'

This works on Linux (where I have my pbcopy script on my path) and on OS X (which has the native pbcopy on the path).

Issues

I use this quite often and it's turned out to be a huge time saver. It's not perfect, though. There are two issues I have encountered.

First, it doesn't work if you open multiple SSH sessions to the same server. After one session is opened, subsequent sessions print a warning:

Warning: remote port forwarding failed for listen port 50730

This can cause other issues. For instance, I have a particular Linux host I connect to via SSH that also runs a MySQL instance. if I have an SSH session open to that host and then use MySQL Workbench (or some other MySQL graphical client) to open an SSH connection to that same host, the warning message is incorrectly interpreted as an error message and the connection fails. The workaround here is to open the MySQL connection first and then open the SSH connection. The port forwarding will fail in the SSH session, preventing the remote pbcopy from working, but the MySQL connection will work.

Second, it doesn't handle text encoding particularly well. When I pass UTF-8 text into the remote pbcopy script, it shows up on the local pasteboard garbled. This shouldn't be too hard to fix, but I don't run into it often enough to spend the time debugging it.