如何使用shell管道从/复制到tmux“剪贴板”?

unt*_*ght 22 shell terminal-multiplexer terminal pipe tmux

在 shell 环境中工作时,我经常遇到需要复制“中间管道输出”的情况(例如,从/到已经运行的编辑器、其他 shell、其他机器等)。

在窗口环境中,解决此问题的简单(通用)方法通常是通过系统剪贴板,例如:

  • X11:... | xsel -i/xsel -o | ...
  • OS X:... | pbcopy/pbpaste | ...

如何使用 tmux 复制/粘贴工具获得类似的方便行为?

unt*_*ght 27

tl;博士

  • ... | tmux loadb -
  • tmux saveb - | ...

说明与背景

在 tmux 中,所有复制/粘贴活动都通过缓冲区堆栈,其中顶部(索引 0)是最近复制的文本,当没有明确提供缓冲区索引时将用于粘贴-b。您可以使用tmux list-buffers或默认快捷方式tmux-prefix+检查当前缓冲区#

有两种方法可以将管道传输到堆栈顶部的新 tmux 缓冲区,即set-buffer接受字符串参数和load-buffer文件参数。要通过管道传输到通常要load-buffer与 stdin一起使用的缓冲区,例如:

print -l **/* | tmux loadb -
Run Code Online (Sandbox Code Playgroud)

将其粘贴回编辑器等很明显(tmux-prefix+]或您绑定的任何内容paste-buffer),但是,从外壳内部访问粘贴不是,因为调用paste-buffer会将粘贴写入标准输出,最终在终端的编辑中缓冲区,粘贴中的任何换行符都会导致 shell 执行到目前为止粘贴的任何内容(可能是毁掉你一天的好方法)。

有几种方法可以解决这个问题:

  1. tmux pasteb -s ' ':-s用您提供的任何分隔符替换所有行尾(分隔符)。但是,您仍然会得到这样的行为,paste-buffer即粘贴最终会出现在您的终端编辑缓冲区中,这可能是您想要的,但通常不是。
  2. tmux showb | ...show-buffer将缓冲区打印到标准输出,几乎是必需的,但正如Chris Johnsen 在评论中提到的show-buffer对不可打印的 ASCII 字符和非 ASCII 字符执行八进制编码。不幸的是,这经常中断,很烦人,即使是简单的事情,如空终止字符串或重音拉丁字符(例如(在 zsh 中)print -N á | tmux loadb - ; tmux showbprints \303\241\000)。
  3. tmux saveb - | ...:save-buffer做简单的相反操作load-buffer并将未修改的原始字节写入标准输出,这是大多数情况下所需要的。然后您可以继续组装另一个管道,例如。通过| xargs -n1 -I{} ...以处理线明智等。

  • `tmux show-buffer` 将对 C0 控制字符和非 ASCII 字节(例如带重音的拉丁字符等)进行八进制编码。如果您想要原始字节(这通常是您想要的),您可以使用“tmux save-buffer -”。 (2认同)