Reputation: 166066
Most Unix-like systems have a command that will let you pipe/redirect output to the local clipboard/pasteboard, and retrieve from same. On OS X, these commands are
pbcopy, pbpaste
Is there a way to replicate this functionality while SSHed into another server? That is,
And yes, I know I could just (shudder) use my mouse to select the text from the command, but I've gotten so used to the workflow of pipping output directly to the clipboard that I want the same for my remote sessions.
Code is useful, but general approaches are appreciated as well.
Upvotes: 242
Views: 139239
Reputation: 1
If you're using Windows Terminal and working in an SSH session, you can easily copy the entire content of a file to your clipboard without extra tools.
Add the following function to your .bashrc
or .bash_aliases
:
clip() { clear; printf "%s" "$(cat "$1")"; read; }
clear
: Clears the terminal for a clean view.
printf "%s" "$(cat "$1")"
: Displays the file content without adding a new line at the end.
read
: Keeps the terminal from returning to the prompt immediately, so you can select everything.
To use, source your file
source ~/.bash_rc
# OR
source ~/.bash_aliases
Press Ctrl + Shift + A to select all the content in the terminal.
Press Ctrl + C to copy the selected content to your clipboard.
Press Enter to come back to the prompt.
Paste it into any editor on your local machine with Ctrl + V.
This method ensures you can copy file content from a remote server without needing extra software or clipboard integration.
Upvotes: 0
Reputation: 9308
Similar to Sridhar's answer but uses a local forward. This is because remote forwards leave a port bound and open on the remote machine, which I think is bad practice. To me, their client & server is also backwards, it's more logical for the remote to serve the content, and the local to request it.
-L127.0.0.4:7777:127.0.0.8:7777
nc -l 127.0.0.8 7777 < some-file.ext
or you can write to it from an editor, e.g. in Vim:
:w !nc -l 127.0.0.8 7777
The "server" is now waiting for an incoming connection.xclip
or pbcopy
:
nc -N 127.0.0.4 7777 < /dev/null | xclip -sel c
or just redirect output to a file. -N
option closes the connection.The .4
& .8
addresses are not special and can be changed.
They help differentiate where each is used.
Upvotes: 0
Reputation: 25236
All the existing solutions either need:
xclip
on the server works great) orHere's another way to do it, though you'll need to modify how you ssh into your computer.
I've started using this and it's nowhere near as intimidating as it looks so give it a try.
ssh [email protected] -R 2000:localhost:2000
(hint: make this a keybinding so you don't have to type it)
nc -l 2000 | pbcopy
Note: if you don't have pbcopy
then just tee
it to a file.
cat some_useful_content.txt | nc localhost 2000
Actually even if you're in the middle of an ssh session there's a way to start a tunnel but i don’t want to scare people away from what really isn’t as bad as it looks. But I'll add the details later if I see any interest
Upvotes: 34
Reputation: 2528
This answer develops both upon the chosen answer by adding more security.
That answer discussed the general form,
<command that makes output> | \
ssh <user A>@<host A> <command that maps stdin to clipboard>
Where security may be lacking is in the ssh
permissions allowing <user B>
on host B>
to ssh
into host A
and execute any command.
Of course B
to A
access may already be gated by an ssh
key, and it may even have a password. But another layer of security can restrict the scope of allowable commands that B
can execute on A
, e.g. so that rm -rf /
cannot be called. (This is especially important when the ssh
key doesn't have a password.)
Fortunately, ssh
has a built-in feature called command restriction or forced command. See ssh.com, or
this Server Fault question.
The solution below shows the general form solution along with ssh
command restriction enforced.
This security enhanced solution follows the general form - the call from the ssh
session on host-B
is simply:
cat <file> | ssh <user-A>@<host A> to_clipboard
The rest of this shows the setup to get that to work.
Suppose the user account on B
is user-B
, and B has an ssh key id-clip
, that has been created in the usual way (ssh-keygen
).
Then in user-A
's ssh directory there is a file
/home/user-A/.ssh/authorized_keys
that recognizes the key id-clip
and allows ssh
connection.
Usually the contents of each line authorized_keys
is exactly the public key being authorized, e.g., the contents of id-clip.pub
.
However, to enforce command restriction that public key content is prepended (on the same line) by the command to be executed. In our case:
command="/home/user-A/.ssh/allowed-commands.sh id-clip",no-agent-forwarding,no-port-forwarding,no-user-rc,no-x11-forwarding,no-pty <content of file id-clip.pub>
The designated command "/home/user-A/.ssh/allowed-commands.sh id-clip"
, and only that designated command, is executed whenever key id-clip
is used initiate an ssh
connection to host-A
- no matter what command is written the ssh
command line.
The command indicates a script file allowed-commands.sh
, and the contents of that that script file is
#/bin/bash
#
# You can have only one forced command in ~/.ssh/authorized_keys. Use this
# wrapper to allow several commands.
Id=${1}
case "$SSH_ORIGINAL_COMMAND" in
"to-clipboard")
notify-send "ssh to-clipboard, from ${Id}"
cat | xsel --display :0 -i -b
;;
*)
echo "Access denied"
exit 1
;;
esac
The original call to ssh
on machine B
was
... | ssh <user-A>@<host A> to_clipboard
The string to-clipboard
is passed to allowed-commands.sh
by the environment variable SSH_ORIGINAL_COMMAND
.
Addition, we have passed the name of the key, id-clip
, from the line in authorized_keys
which is only accessed by id-clip
.
The line
notify-send "ssh to-clipboard, from ${Id}"
is just a popup messagebox to let you know the clipboard is being written - that's probably a good security feature too. (notify-send
works on Ubuntu 18.04, and maybe not others).
In the line
cat | xsel --display :0 -i -b
The parameter --display :0
is necessary, because the process doesn't have its own X display with a clipboard,
so it must be specified explicitly. This value :0
happens to work on Ubuntu 18.04 with the Wayland window server. On other setups it might not work. For a standard X server this answer might help.
host-A
/etc/ssh/sshd_config
parametersFinally a few parameters in /etc/ssh/sshd_config
on host A
that should be set to ensure permission to connect, and permission to use an ssh
-key only without a password:
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers user-A
To make the sshd
server reread the configuration
sudo systemctl restart sshd.service
or
sudo service sshd.service restart
It's some effort to set it up, but other functions besides to-clipboard
can be constructed in parallel with the same framework.
Upvotes: 4
Reputation: 17491
It is not a one-liner, but it doesn't require any extra SSH connection.
netcat
if necessarycat ~/some_file.txt | nc termbin.com 9999
. This will copy the output to the termbin
website and prints the URL to your output.Of course, do not use it for sensitive content.
Upvotes: 4
Reputation: 1389
This is my solution based on an SSH reverse tunnel, netcat, and xclip.
First create a script (for example, clipboard-daemon.sh) on your workstation:
#!/bin/bash
HOST=127.0.0.1
PORT=3333
NUM=`netstat -tlpn 2>/dev/null | grep -c " ${HOST}:${PORT} "`
if [ $NUM -gt 0 ]; then
exit
fi
while [ true ]; do
nc -l ${HOST} ${PORT} | xclip -selection clipboard
done
And start it in the background.
./clipboard-daemon.sh &
It will start nc
piping output to xclip and respawning the process after receiving a portion of data.
Then start the SSH connection to the remote host:
ssh user@host -R127.0.0.1:3333:127.0.0.1:3333
While logged in on the remote box, try this:
echo "this is test" >/dev/tcp/127.0.0.1/3333
Then try to paste on your workstation.
You can of course write a wrapper script that starts clipboard-daemon.sh first and then the SSH session. This is how it works for me.
Upvotes: 9
Reputation: 651
rhileighalmgren's solution is good, but pbcopy will annoyingly copy the last "\n" character. I use head to strip out the last character to prevent this:
#!/bin/bash
head -c -1 | ssh desktop pbcopy
My full solution is here: http://taylor.woodstitch.com/linux/copy-local-clipboard-remote-ssh-server/
Upvotes: 3
Reputation: 8125
My favorite way is ssh [remote-machine] "cat log.txt" | xclip -selection c
. This is most useful when you don't want to (or can't) ssh from remote to local.
On Cygwin, ssh [remote-machine] "cat log.txt" > /dev/clipboard
.
A helpful comment from nbren12:
It is almost always possible to setup a reverse ssh connection using SSH port forwarding. Just add
RemoteForward 127.0.0.1:2222 127.0.0.1:22
to the server's entry in your local.ssh/config
, and then executessh -p 2222 127.0.0.1
on the remote machine, which will then redirect the connection to the local machine. – nbren12
Upvotes: 175
Reputation: 5213
I found a great solution that doesn't require a reverse SSH connection!
You can use xclip on the remote host, along with SSH X11 forwarding and XQuartz on the OS X system.
To set this up:
,
)ssh -X remote-host "echo 'hello from remote-host' | xclip -selection clipboard"
Upvotes: 34
Reputation: 1206
I'm resurrecting this thread because I've been looking for the same kind of solution, and I've found one that works for me. It's a minor modification to a suggestion from OSXDaily.
In my case, I use Terminal on my local OS X machine to connect to a Linux server via SSH. Like the OP, I wanted to be able to transfer small bits of text from terminal to my local clipboard, using only the keyboard.
The essence of the solution:
commandThatMakesOutput | ssh desktop pbcopy
When run in an SSH session to a remote computer, this command takes the output of commandThatMakesOutput (e.g., ls, pwd) and pipes the output to the clipboard of the local computer (the name or IP of "desktop"). In other words, it uses nested SSH: you're connected to the remote computer via one SSH session, you execute the command there, and the remote computer connects to your desktop via a different SSH session and puts the text to your clipboard.
It requires your desktop to be configured as an SSH server (which I leave to you and Google). It's much easier if you've set up ssh keys to facilitate fast ssh usage, preferably using a per-session passphrase, or whatever your security needs require.
Other examples:
ls | ssh desktopIpAddress pbcopy
pwd | ssh desktopIpAddress pbcopy
For convenience, I've created a Bash file to shorten the text required after the pipe:
#!/bin/bash
ssh desktop pbcopy
In my case, I'm using a specially-named key.
I saved it with the file name cb (my mnemonic (ClipBoard). Put the script somewhere in your path, make it executable and voilà:
ls | cb
Upvotes: 107
Reputation: 691
If you use iTerm2 on the Mac, there is an easier way. This functionality is built into iTerm2's Shell Integration capabilities via the it2copy
command:
Usage: it2copy
Copies to clipboard from standard input
it2copy filename
Copies to clipboard from file
To make it work,
choose iTerm2-->Install Shell Integration menu item while logged into the remote host (so that it runs curl -L https://iterm2.com/shell_integration/install_shell_integration_and_utilities.sh | bash
), to install it to your own account.
Follow the instructions to refresh your environment (e.g. source ~/.iterm2_shell_integration.zsh
).
Once that is done, you'll have access to ~/.iterm2/it2copy
, as well as a bunch of other aliased commands that provide cool functionality.
The other solutions here are good workarounds but this one is so painless in comparison.
Upvotes: 14
Reputation: 111
Allow me to add a solution that if I'm not mistaken was not suggested before.
It does not require the client to be exposed to the internet (no reverse connections), nor does it use any xlibs on the server and is implemented completely using ssh's own capabilities (no 3rd party bins)
It involves:
The solution utilizes ssh's ControlMaster functionality to use just one TCP connection for everything so it will even support hosts that require a password to login and prompt you for it just once.
Edit: as requested, the code itself:
Paste the following into your bashrc and use sshx host
to connect.
On the remote machine echo SOMETHING > ~/clip
and hopefully, SOMETHING will end up in the local host's clipboard.
You will need the xclip
utility on your local host.
_dt_term_socket_ssh() {
ssh -oControlPath=$1 -O exit DUMMY_HOST
}
function sshx {
local t=$(mktemp -u --tmpdir ssh.sock.XXXXXXXXXX)
local f="~/clip"
ssh -f -oControlMaster=yes -oControlPath=$t $@ tail\ -f\ /dev/null || return 1
ssh -S$t DUMMY_HOST "bash -c 'if ! [ -p $f ]; then mkfifo $f; fi'" \
|| { _dt_term_socket_ssh $t; return 1; }
(
set -e
set -o pipefail
while [ 1 ]; do
ssh -S$t -tt DUMMY_HOST "cat $f" 2>/dev/null | xclip -selection clipboard
done &
)
ssh -S$t DUMMY_HOST \
|| { _dt_term_socket_ssh $t; return 1; }
ssh -S$t DUMMY_HOST "rm $f"
_dt_term_socket_ssh $t
}
More detailed explanation is on my website:
https://xicod.com/2021/02/09/clipboard-over-ssh.html
Upvotes: 8
Reputation: 1324
If you're working over e.g. a pod in a Kubernetes cluster and not direct SSH, so that there is no way for your to do a file transfer, you could use cat
and then save the terminal output as text. For example in macOS you can do Shell -> Export as text.
Upvotes: 1
Reputation: 303
For anyone googling their way to this: The best solution in this day and age seem to be lemonade
Various solutions is also mentioned in the neovim help text for clipboard-tool
Upvotes: 2
Reputation: 351
Far Manager Linux port supports synchronizing clipboard between local and remote host. You just open local far2l, do "ssh somehost" inside, run remote far2l in that ssh session and get remote far2l working with your local clipboard.
It supports Linux, *BSD and OS X; I made a special putty build to utilize this functionality from windows also.
Upvotes: 2
Reputation: 495
The simplest solution of all, if you're on OS X using Terminal and you've been ssh'ing around in a remote server and wish to grab the results of a text file or a log or a csv, simply:
1) Cmd-K
to clear the output of the terminal
2) cat <filename>
to display the contents of the file
3) Cmd-S
to save the Terminal Output
You'll have the manually remove the first line and last line of the file, but this method is a bit simpler than relying on other packages to be installed, "reverse tunnels" and trying to have a static IP, etc.
Upvotes: 5
Reputation: 204718
There are various tools to access X11 selections, including xclip and XSel. Note that X11 traditionally has multiple selections, and most programs have some understanding of both the clipboard and primary selection (which are not the same). Emacs can work with the secondary selection too, but that's rare, and nobody really knows what to do with cut buffers...
$ xclip -help Usage: xclip [OPTION] [FILE]... Access an X server selection for reading or writing. -i, -in read text into X selection from standard input or files (default) -o, -out prints the selection to standard out (generally for piping to a file or program) -l, -loops number of selection requests to wait for before exiting -d, -display X display to connect to (eg localhost:0") -h, -help usage information -selection selection to access ("primary", "secondary", "clipboard" or "buffer-cut") -noutf8 don't treat text as utf-8, use old unicode -version version information -silent errors only, run in background (default) -quiet run in foreground, show what's happening -verbose running commentary Report bugs to <[email protected]>
$ xsel -help Usage: xsel [options] Manipulate the X selection. By default the current selection is output and not modified if both standard input and standard output are terminals (ttys). Otherwise, the current selection is output if standard output is not a terminal (tty), and the selection is set from standard input if standard input is not a terminal (tty). If any input or output options are given then the program behaves only in the requested mode. If both input and output is required then the previous selection is output before being replaced by the contents of standard input. Input options -a, --append Append standard input to the selection -f, --follow Append to selection as standard input grows -i, --input Read standard input into the selection Output options -o, --output Write the selection to standard output Action options -c, --clear Clear the selection -d, --delete Request that the selection be cleared and that the application owning it delete its contents Selection options -p, --primary Operate on the PRIMARY selection (default) -s, --secondary Operate on the SECONDARY selection -b, --clipboard Operate on the CLIPBOARD selection -k, --keep Do not modify the selections, but make the PRIMARY and SECONDARY selections persist even after the programs they were selected in exit. -x, --exchange Exchange the PRIMARY and SECONDARY selections X options --display displayname Specify the connection to the X server -t ms, --selectionTimeout ms Specify the timeout in milliseconds within which the selection must be retrieved. A value of 0 (zero) specifies no timeout (default) Miscellaneous options -l, --logfile Specify file to log errors to when detached. -n, --nodetach Do not detach from the controlling terminal. Without this option, xsel will fork to become a background process in input, exchange and keep modes. -h, --help Display this help and exit -v, --verbose Print informative messages --version Output version information and exit Please report bugs to <[email protected]>.
In short, you should try xclip -i
/xclip -o
or xclip -i -sel clip
/xclip -o -sel clip
or xsel -i
/xsel -o
or xsel -i -b
/xsel -o -b
, depending on what you want.
Upvotes: 9