Using iTerm2, I start an interactive SSH session to a remote Linux machine (where pbcopy
is not available). On the remote Linux machine I would like to capture the output of some arbitrary command (e.g. ls *.foo
), and have it magically appear in my OSX clipboard, so that when I hit ⌘+v it appears in whatever OSX application I've just pasted into. Is this possible? I've tried the escape codes mentioned on the iTerm2 doc page and can't make them work.
MacOS – How to copy to the OSX clipboard from a remote shell using iTerm2
copy/pasteitermmacos
Related Question
- How to prevent iTerm2 from creating overlaps and broken lines after pasting multiline chunks of text
- MacOS – Display contents of file and also copy it to the clipboard
- Make Ctrl-k in Terminal copy to the system clipboard
- IOS – Fast note app for quick lookup & copy to clipboard for osx & ios
- How to switch tabs when using iTerm2 with Z shell
- MacOS: saving images from the clipboard using `pngpaste` is faded and white
Best Answer
Solution
Piecing together lots of information from several different sources, here's what I came up with.
Local Daemon
From the local computer (OSX), setup a daemon to listen on a specific port, via
launchd
(see links below). The daemon process will simply callpbcopy
, which will take anything passed in viaSTDIN
and put it on the clipboard. To do this you need to setup alaunchd
plist file. Mine looked like this:By convention, the plist file name should be the label name with
.plist
appended, so for the above example, it would belocal.pbcopy.9999.plist
. If you wish to use a port other than 9999, just change it everywhere (keeping in mind that it should be something above 1024 and should not be a well-known port that you might already be using). Once you have things working, you can remove theStandardOutPath
andStandardErrorPath
keys and strings, as they're only needed for debugging.In order to load the daemon, run the following command:
You can see that it's loaded or remove it with the following commands:
If you would like this to load every time you login, place the plist file into the
~/Library/LaunchAgents
directory.Note: you will need to set this up on each local host you want this to work on.
SSH Port-Forwarding
Because I could be accessing the remote machine from several different local computers, I can't hard-code the sending of the data on the remote machine to a specific host. To make this as painless and dynamic as possible, I've used SSH port-forwarding to create a dynamic link from the remote machine back to the local computer (the how's and why's of this are beyond this answer; see below for more information). Specifically, I create a link from the remote machines's port 9997 to the local computer's port 9999, which now has a daemon listening on it, thanks to the
launchd
stuff above. I could use port 9999 on both the remote machine and the local computer, but I don't need to.To setup this tunnel, execute the following command:
You can remote into multiple different remote machines with the same command and all will function as expected. You can remote into the same remote machine multiple times with the same command, and it will sort of work as expected; see note below.
If you don't feel like typing the
-R 9997:localhost:9999
on every SSH invocation you make, you can put the remote forwarding definition in the SSH config file to do it automatically. Here's an example from my~/.ssh/config
file:With that, any time that I SSH to a host whose name starts with 'ufo', the remote forwarding from 9997 to localhost:9999 will automatically be set up. See the config file man page link below for more options.
Sending Data
On the remote end I use
netcat
to send the desired content back to the listening daemon.You can get as complicated as you'd like:
You can even dynamically decide whether or not to send any data, based on whether or not anyone is listening (there's probably a more efficient way to do this, but it works):
Observations & Caveats
Things I noted:
pbcopy
plays nicely with Copy'em PasteReference Links