在 shell 环境中工作时,我经常遇到需要复制“中间管道输出”的情况(例如,从/到已经运行的编辑器、其他 shell、其他机器等)。
在窗口环境中,解决此问题的简单(通用)方法通常是通过系统剪贴板,例如:
- X11:
... | xsel -i
/xsel -o | ...
- 操作系统:
... | pbcopy
/pbpaste | ...
如何使用 tmux 复制/粘贴工具获得类似的便捷行为?
答案1
太长了;博士
... | tmux loadb -
tmux saveb - | ...
解释和背景
在 tmux 中,所有复制/粘贴活动都经过缓冲堆栈其中顶部(索引 0)是最近复制的文本,当没有明确提供缓冲区索引时将用于粘贴-b
。您可以使用tmux list-buffers
默认快捷键tmux-prefix+检查当前缓冲区#。
有两种方法可以通过管道传输到堆栈顶部的新 tmux 缓冲区:set-buffer
采用字符串参数和load-buffer
采用文件参数。要通过管道传输到缓冲区,您通常需要load-buffer
与 stdin 一起使用,例如:
print -l **/* | tmux loadb -
将其粘贴回编辑器中,这是非常明显的(tmux-prefix+]或您绑定的任何内容paste-buffer
),但是,从外壳内部访问粘贴则不然,因为调用paste-buffer
会将粘贴写入标准输出,最终出现在终端的编辑中缓冲区,并且粘贴中的任何换行符都会导致 shell 执行到目前为止已粘贴的任何内容(可能是毁掉你的一天的好方法)。
有几种方法可以解决这个问题:
tmux pasteb -s ' '
:-s
用您提供的任何分隔符替换所有行结尾(分隔符)。但是,您仍然会得到这样的行为,paste-buffer
这意味着粘贴最终会出现在终端编辑缓冲区中,这可能是您想要的,但通常不是。tmux showb | ...
:show-buffer
将缓冲区打印到标准输出,这几乎是所需要的,但是作为克里斯·约翰森在评论中提到,show-buffer
对不可打印的 ASCII 字符和非 ASCII 字符执行八进制编码。不幸的是,这经常会中断,甚至很烦人,甚至是简单的事情,例如空终止字符串或带重音的拉丁字符(例如(在 zsh 中)print -N á | tmux loadb - ; tmux showb
prints\303\241\000
)。tmux saveb - | ...
:save-buffer
只是执行相反的操作load-buffer
,并将未修改的原始字节写入标准输出,这在大多数情况下都是所需的。然后您可以继续组装另一个管道,例如。通过| xargs -n1 -I{} ...
以流程方式进行处理,等等。