I ssh into my VPS and run tmux. I can copy/paste from the remote to local, and local to remote - using the mouse and shift.

But I don't know how to copy large quantities of text.

If I were working locally, I could do this: cat somefile.txt | xsel -b or cat somefile | xclip -selection clipboard to copy into the clipboard. (I can't do that of course as the remote server doesn't run x, and even so the clipboard would not match the one used in tmux.)

So, how do I copy text in the tmux session, and for it to be duplicated over the wire to my local system's clipboard?

Actually, this is applicable even without tmux - how to copy-paste large buffers between a remote and local shell.

  • Same question here. On ubuntu using ssh to login to raspberry pi, and there running tmux, I'd like to be able to paste locally the selection that I put in the tmux buffer. Remarkable is that when I do the same on my chromebook linux terminal, the buffer is copied to the local clipboard. Really so! When I do the tmux copy mode on the remote machine and hit Enter, the terminal blinks the "copied" icon in the middle and I can paste the selected text locally! It's like magic, but I have no clue how to do the same on my ubuntu machine :( Feb 3, 2021 at 21:51

2 Answers 2


To have bidirectional clipboard (more here):

  1. Run ssh with -X to enable X11 forwarding.

  2. Install xsel (manipulate the X selection).

    sudo apt instal xsel

That's it. Now, to test remote → local run on the remote host:

time date +%Y-%m-%d_%T | xsel -b  # Or tee >(xsel -b) to get the output also on stdout

On local host:

echo "Time on server is $(xsel -b)"

time will show how long it took the command to copy the text to the clipboard.


  • You can also use primary buffer instead:

    Selection options

    -p, --primary: operate on the PRIMARY selection (default).
    -b, --clipboard: operate on the CLIPBOARD selection.

  • tmux buffer stack might be enough on some cases.

  • -X Might need xauth on server.

  • xsel depends on libx11-6 and libc6 (apt depends xsel).

  • If you get xsel: Can't open display: (null) check this answer.

  • Thank you. Strangely though this doesn't work for me. The command on the remote never returns (even without time), and the local doesn't reflect it. All dependencies installed. Maybe it's "just me". I'll try again later on another machine. Thanks once again!
    – lonix
    Oct 14, 2021 at 7:42
  • echo foo | xsel -b on the server return any output? Try with ssh -Y, or with ssh -vvv to debug what's going on. You are using Wayland? time only returns how long the process took to run.
    – Pablo A
    Oct 14, 2021 at 19:08
  • No wayland, I'm using ubuntu based server. Problem is maybe x11 forwarding which isn't setup properly as I've never needed it... I'll look into it again later. I upvoted as this if a good solution for those with x11 set up. There must be other options too, I hope that would work for me.
    – lonix
    Oct 15, 2021 at 2:50
  • I'm also using an ubuntu server (20.4). I didn't do any further tweaks. Maybe you need some packages installed on server, like x11-common. If you provide more info, like the output of echo foo | xsel -b while connecting with ssh -vvv -Y maybe we could help.
    – Pablo A
    Oct 15, 2021 at 20:26

In addition to Pablo's excellent answer above, if you are doing esoteric DISPLAY stuff, e.g. X11 forwarding for clipboard but using local display for OpenGL / CUDA machine learning stuff, then you may want to redirect your displays.

If you siphon an X11-forwarded display off into a separate env var, then you can have the "best" of both worlds.

It can look something like this:

# Bash function.
personal-ssh-session() {  # Call manually
    if [[ ! -v _SSH_DISPLAY && -v DISPLAY ]]; then
        export _SSH_DISPLAY=${DISPLAY}
        echo "Using redirect _SSH_DISPLAY=${_SSH_DISPLAY}"
    export DISPLAY=:1

# Bash script, `tmux-copy.sh`
set -e
if [[ -n "${_SSH_DISPLAY}" ]]; then
    export DISPLAY=${_SSH_DISPLAY}
mkdir -p ~/tmp
tee ~/tmp/tmux-clipboard.txt | xclip -in -selection clipboard

# tmux bind command - be sure ${_DOTFILES} is set, or use something else
bind -T copy-mode-vi Enter send-keys -X copy-pipe \

Example from https://github.com/eacousineau/dotfiles_template

  • Run inside X11-forward SSH session: bash_aliases func
    • This will set DISPLAY to use local gfx card vs. X11 forwarding (most likely software rendering)
  • Add script to handle redirect for clipboard; this also dumps current stuff in ~/tmp/tmux-clipboard.txt, just in case: bash script
  • Tell tmux to use this script: tmux bind command

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .