When working in a shell environment I run fairly often into the need to copy 'intermediate pipe output' around (eg. from/to already running editors, to other shells, other machines, etc.).
When in a windowing environment, an easy (and generic) method to solve this is often via the system clipboard, eg.:
- X11:
... | xsel -i
/xsel -o | ...
- OS X:
... | pbcopy
/pbpaste | ...
How can I get similarly convenient behavior using the tmux copy/paste facility?
Best Answer
tl;dr
... | tmux loadb -
tmux saveb - | ...
Explanation & Background
In tmux, all copy/paste activity goes through the buffer stack where the top (index 0) is the most recently copied text and will be used for pasting when no buffer index is explicitly provided with
-b
. You can inspect the current buffers withtmux list-buffers
or the default shortcut tmux-prefix+#.There are two ways for piping into a new tmux buffer at the top of the stack,
set-buffer
taking a string argument, andload-buffer
taking a file argument. To pipe into a buffer you usually want to useload-buffer
with stdin, eg.:Pasting this back into editors and such is pretty obvious (tmux-prefix+] or whatever you've bound
paste-buffer
to), however, accessing the paste from inside the shell isn't, because invokingpaste-buffer
will write the paste into stdout, which ends up in your terminal's edit buffer, and any newline in the paste will cause the shell to execute whatever has been pasted so far (potentially a great way to ruin your day).There are a couple of ways to approach this:
tmux pasteb -s ' '
:-s
replaces all line endings (separators) with whatever separator you provide. However you still get the behavior ofpaste-buffer
which means that the paste ends up in your terminal edit buffer, which may be what you want, but usually isn't.tmux showb | ...
:show-buffer
prints the buffer to stdout, and is almost what's required, but as Chris Johnsen mentions in the comments,show-buffer
performs octal encoding of non-printable ASCII characters and non-ASCII characters. This unfortunately breaks often enough to be annoying, with even simple things like null terminated strings or accented latin characters (eg. (in zsh)print -N รก | tmux loadb - ; tmux showb
prints\303\241\000
).tmux saveb - | ...
:save-buffer
does simply the reverse ofload-buffer
and writes the raw bytes unmodified into stdout, which is what's desired in most cases. You could then continue to assemble another pipe, and eg. pass through| xargs -n1 -I{} ...
to process line wise, etc..