使tmux将缓冲区复制到剪贴板


118

我试图找出一种不错的方法将tmux缓冲区中的内容复制到剪贴板中。我已经尝试了几种不同的方法,例如

bind-key p select-pane -t 2 \; split-window 'xsel -i -b' \; paste-buffer

这使我非常接近,我要做的就是在我做前缀-p之后按control-d。

我试图通过做来解决

bind-key p select-pane -t 2 \; split-window 'xsel -i -b << HERE\; tmux paste-buffer\; echo HERE'

但这是行不通的。实际上,如果我将其配对为

bind-key p select-pane -t 2 \; split-window 'xsel -i -b << HERE'

它什么也没做,所以我假设在shell命令中,分割窗口不喜欢<<。

有任何想法吗?

编辑:select-pane -t 2如果需要,可以跳过,这并不是很重要。我只使用一种特定的布局,而窗格2是我在进行其他操作时希望拆分的布局,因此默认情况下会进入涉及拆分的绑定。


2
确保查看下面的2014年答案,该答案比其他一些答案要新。它建议使用tmux yank插件,效果很好。
dmonopoly

有关Tmux 2.4(2017年4月发布)和2.6的最新答案
Jason Axelson

Answers:


26

这里的文档需要换行符。例如,在Shell脚本中,您可以编写

cat <<EOF >somefile; echo  done
file contents
EOF

我不认为tmux允许您在其中放置换行符,即使这样做,也不是一个好方法。如果数据本身HERE仅包含一行(例如,因为您要复制.tmux.conf),该怎么办?

我建议将缓冲区内容写入一个临时文件。未经测试:

bind-key p save-buffer ~/.tmux-buffer \; run-shell "xsel -i -b <~/.tmux-buffer && rm ~/.tmux-buffer"

如果在两个单独的tmux实例中使用此命令,则存在争用条件。我不知道该怎么解决。


谢谢,效果非常好,比赛条件对我来说并不重要,我只使用1次。
Digital Powers

为了避免比赛条件,我建议使用mktemp广泛使用的方法
悲伤

@Grief好主意。在这种情况下,使用tmux进程的PID也会很好,并且可能会更容易安排($PPID在tmux启动的shell中)。但是如何将变量文件名(无论它是如何构造的)放入参数的中save-buffer呢?我猜save-buffer - | …就像在Grauwolf的答案中那样,它完全消除了一个临时文件?
吉尔斯

你是对的,我的错,这是不可能的。
悲伤

93

这应该工作:

# move x clipboard into tmux paste buffer
bind C-p run "tmux set-buffer \"$(xclip -o)\"; tmux paste-buffer"
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i"

1
确实如此。谢谢,这比使用临时文件好得多。由于TMUX环境变量,它甚至可以自动处理多个并发会话。
吉尔斯

22
C-p对此的更好说明是:bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"-没有引用问题或命令行限制问题。
docwhat 2012年

8
在打开时,tmux是否具有钩子将选择内容复制到剪贴板copy-mode
Ehtesh Choudhury

1
xclip -o选项对我没有用,所以我改成了bind C-c run "tmux save-buffer - | xclip -selection c"\; display-message "Buffer copied to clipboard"
Pawka

6
每次我以这种方式进行复制时,tmux都会停止响应任何键盘快捷键。有什么解决办法吗?
skrat 2015年

41

适用于Mac OS-X的更简单的解决方案

这是基于Alex的答案,并使用了当时不存在的东西。

如果您使用自制软件(如果不是,为什么不这样做?),则可以这样做:

brew install reattach-to-user-namespace

然后在您的~/.tmux.conf

set-option -g default-command "reattach-to-user-namespace -l zsh" # or bash...
bind C-c run "tmux save-buffer - | reattach-to-user-namespace pbcopy"
bind C-v run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"

要将缓冲区从tmux复制到Mac粘贴板中(您应该已经使用tmux复制了某些内容),请使用<tmux-key> Control-c。现在将可用于Command-vpbpaste

要从Mac粘贴板粘贴某些东西,请使用<tmux-key> Control-v


2
这个答案很棒。我正在使用tmux show-buffer引起换行问题tmux save-buffer -解决它的方法。
event_jr 2012年

什么是-在结束tmux save-buffer -呢?
hekevintran

发出save-buffer标准输出。您可以将替换-为文件名,然后将其保存在此处。这样可以防止您编写(和清理)文件。
docwhat 2012年

1
从OS X 10.10开始,不再需要重新附加到用户命名空间。关于tmux和OS X的几乎所有教程和文档都提到了它,因为几年前复制和粘贴并不容易。如今,它(通常)是开箱即用的。
拉斐尔·布加杰夫斯基

40

copy-pipe1.8版本开始添加了该命令。它将选择内容复制到tmux缓冲区,并将其通过管道传递给命令。现在,不需要前缀绑定。这是一个例子:

bind -t vi-copy y copy-pipe "xclip"

# For OS X users:
bind -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

现在,当您在中选择了一些文本时copy-modey会将其复制到tmux缓冲区以及OS剪贴板。但是,如果您想将文本从剪贴板发送到tmux缓冲区,则无济于事。


1
完美运行,是最简单的解决方案。
Naseer 2014年

2
在Linux下不适用于我,但此功能却可以:unix.stackexchange.com/a/131074/13601
Sebastian Blask 2014年

1
从OS X 10.10开始,似乎reattach-to-user-namespace没有必要。
克里斯

工作在埃尔卡皮坦
2009东海生日贺

2
这不再适用于2017年4月20日发布的Tmux 2.4。相反,您需要使用bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip"OS X:bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"
Jason Axelson

16

您可能想尝试tmux-yank plugin。它可以直接复制到系统剪贴板(OS X和Linux)以及其他一些类似的东西,例如取消当前的shell行。


7
这是一个很棒的清洁解决方案,应该考虑更多,因为它是比其他方法更新的答案。感谢分享!
dmonopoly

9

在尝试了不同的解决方案之后,这是我的最终设置:

# move x clipboard into tmux paste buffer
bind C-p run "xclip -o | tmux load-buffer -
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i -selection clipboard"

当您拆分时,使用保存缓冲区而不是显示缓冲区将提供真实数据,而没有换行符所示的数据。

我还使用它在tmux复制模式下开始选择/复制:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy 'y' copy-selection

我猜有可能将复制选择与y键合并,然后将其移动到x剪贴板。


我试图像您提到的那样合并两个命令,但均未成功。关于如何做的任何想法?
拉斐尔·维加

9

这是一个全面的答案。

首先一点历史

首次提出此问题时(2011年6月),将文本从Tmux复制到剪贴板必须经过两个步骤,首先将所选文本复制到Tmux的缓冲区,然后将文本从Tmux的缓冲区复制到系统剪贴板。

在1.8(2013年3月)copy-pipe中添加了命令,该命令使您可以将所选文本直接复制到系统剪贴板(或其他目标)中。

然后在2.4(2017年4月)中,关键表发生了显着变化,导致此页面上的许多答案已过时。

回答原始问题

Linux

bind-key C-y run-shell "tmux save-buffer - | xclip -i -r > /dev/null" \; display-message "Copied tmux buffer to selection"
bind-key C-Y run-shell "tmux save-buffer - | xclip -i -r -selection clipboard > /dev/null" \; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"

Mac

如果您使用自制软件,则应reattach-to-user-namespace通过在终端中运行以下命令进行安装:

brew install reattach-to-user-namespace

然后在您的〜/ .tmux.conf中:

bind-key C-y run-shell "tmux save-buffer - | reattach-to-user-namespace pbcopy" \; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "reattach-to-user-namespace pbpaste | tmux load-buffer - ; tmux paste-buffer"

更短的方法(将选择内容直接从剪贴板复制并粘贴到剪贴板,以便tmux> 2.4)

注意:Linux有两个版本,因为Linux具有主要和辅助剪贴板(也称为选择)。

Linux

bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip -r" \; display-message "Copied to selection"
bind-key -T copy-mode-vi Y send-keys -X copy-pipe "xclip -r -selection clipboard" \; display-message "Copied to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - && tmux paste-buffer"

Mac

bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy" \; display-message "Copied to clipboard"

自定义这些命令

  • 如果您不希望该命令在状态行中告诉您它做了什么,则只需删除display-message(及其\;之前的)。

  • 如果您使用的是Emacs的风格复制模式,而不是六然后替换的任何实例copy-mode-vicopy-mode

  • 如果您运行的是Linux,并要使用xsel,而不是xclip替代xclip -rxsel -i -pxclip -oxsel -o -p

  • -rxclip -r是可选的,它消除了最后的换行符。这对于复制命令很有用,然后将其粘贴时将不会立即执行。

  • 如果您通过SSH进行隧道传输,则应查阅https://unix.stackexchange.com/a/354581/14252

参考文献:


这个命令bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"仍然有效吗?为tmux>2.4
alpha_989,18年

7

我不喜欢额外的按键操作,所以我想要更雄心勃勃的东西。使用[进入复制模式,突出显示正确的文本,然后按]将文本复制到剪贴板。

而且,tmux喜欢在换行的表达式中包含换行符(奇怪的是,这些换行符放在错误的位置!它们不在表达式在屏幕上换行的位置)。因此,我希望C-]复制删除换行符的表达式。

在tmux 1.6上,我尝试了以下操作:

bind [ copy-mode
bind -t vi-copy ] run "tmux send-keys Enter; tmux show-buffer | xclip -i -selection clipboard;"
bind -t vi-copy C-] run "tmux send-keys Enter; tmux show-buffer | perl -pe 's/\n//' | xclip -i -selection clipboard;"

但这没有用,因为tmux似乎不乐意将复杂的东西绑定到vi-copy表。所以我最终改为这样做:

bind [ copy-mode \;                                                        \
    bind -n ] run                                                          \
    "tmux send-keys Enter;                                                 \
     tmux show-buffer | xclip -i -selection clipboard;                     \
     tmux unbind -n C-];                                                   \
     tmux unbind -n ]" \;                                                  \
    bind -n C-] run                                                        \
    "tmux send-keys Enter;                                                 \
     tmux show-buffer | perl -pe 's/\n//' | xclip -i -selection clipboard; \
     tmux unbind -n C-];                                                   \
     tmux unbind -n ]"

如果您以[]或C-]以外的其他方式退出复制模式,则这将导致奇怪的事物([]或C-]在您下次使用时会变得有趣,但只有一次)。我可以想象用更多的绑定来解决此问题,但这确实是我大多数时候想要的。



4

在Arch Wiki上有一个使用xclip以下解决方案:

# move tmux copy buffer into x clipboard
bind-key C-y save-buffer /tmp/tmux-buffer \; run-shell "cat /tmp/tmux-buffer | xclip"

https://wiki.archlinux.org/index.php/Tmux


2
tmux是否save-buffer在共享目录中安全地创建文件?否则将其放入/tmp安全孔中。的无用用法cat,缺少了删除临时文件的功能。然后是xselvs的问题xclip,这在这里是等效的,并且您有我的(独立编写的)解决方案。
Gilles

1
谢谢吉尔。我将更新Wiki以反映您的观点。
jasonwryan 2011年

4

Mac OS X的解决方案。请按照以下两个步骤操作:

  1. 使用Chris Johnsen的变通方法:https : //github.com/ChrisJohnsen/tmux-MacOSX-pasteboard

  2. 将此代码添加到您的tmux配置(〜/ .tmux.conf)

# paste clipboard into tmux buffer
bind v run-shell "reattach-to-user-namespace -l zsh -c 'tmux set-buffer \\"$(pbpaste)\\"; tmux paste-buffer'"
# put tmux buffer into x clipboard
bind y run-shell "reattach-to-user-namespace -l zsh -c 'tmux show-buffer | pbcopy'"


4

我做了一个稍作修改的可接受答案。

除了xclip的primary默认剪贴板(使用鼠标选择和鼠标中键单击获得的剪贴板)之外,我还更喜欢使用系统剪贴板(Ctrl-C,Ctrl-V )。要选择系统剪贴板,您需要将-selection clipboard参数传递给xclip

同样,在将缓冲区复制到剪贴板时,我喜欢选择要复制的缓冲区的功能。使用完成choose-buffer,然后将参数传递给save-bufferusing -b %%

# Copy into clipboard
bind C-c choose-buffer "run \"tmux save-buffer -b %% - | xclip -i -selection clipboard\""
# Paste from clipboard
bind C-v run "xclip -o -selection clipboard | tmux load-buffer - ; tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run \"tmux save-buffer -b %% - | xclip -i \""
# Paste from primary
bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"

更新:以 某种方式在tmux 1.8和两个openSUSE 12.2安装中,通过管道从stdin读取tmux run-shell调用时,我看到挂起xclip。相反,我决定xsel尝试一下,这似乎可行。这些是使用的等效键绑定xsel。我还习惯于&&将命令链接到粘贴中,以提高鲁棒性。

# Copy into clipboard
bind C-c choose-buffer "run \"tmux save-buffer -b '%%' - | xsel -i -b\""
# Paste from clipboard
bind C-v run "xsel -o -b | tmux load-buffer - && tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run \"tmux save-buffer -b '%%' - | xsel -i\""
# Paste from primary
bind C-p run "xsel -o | tmux load-buffer - && tmux paste-buffer"

4

这是我相当冗长的答案,应该解决使用xclip从远程(ssh)tmux会话复制缓冲区的两个主要问题:

1.无反应的xclip

对我来说,@ Grauwolf的回答xclip没有工作(呈现TMUX窗格完全irresponsive)。我在Arch WikiTmux页面中找到了原因:

xclip也可以用于此目的,这与xsel不同,它在打印不适合当前语言环境的原始位流时效果更好。但是,使用xsel而不是xclip更加巧妙,因为xclip从tmux的缓冲区读取后不会关闭STDOUT。因此,tmux不知道复制任务已经完成,并继续等待xclip终止,从而使tmux无响应。一种解决方法是将xclip的STDOUT重定向到/ dev / null

因此绑定应为:

bind-key C-y run "tmux save-buffer - | xclip -i -sel clip > /dev/null"

现在,如果您的tmux会话是本地的,则可以使用。

2. xclip无法连接到X

如果您在ssh -X上使用tmux,则很有可能无法直接使用。

这是因为shell变量$DISPLAY需要正确设置。

完整的解决方案

因此,对我来说,完整的可行解决方案是在我的代码中添加以下几行~/.tmux.conf

set-option -g update-environment "DISPLAY"
bind-key C-y run "export DISPLAY=`tmux show-env | sed -n 's/^DISPLAY=//p'`; tmux save-buffer - | xclip -i -selection clipboard >/dev/null"
# Or more concise:
bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's/^DISPLAY=//p'` >/dev/null

对于主要的粘贴:

bind-key C-p run "xclip -d `tmux show-env | sed -n s/^DISPLAY=//p` -o | tmux load-buffer - && tmux paste-buffer"

我不完全理解为什么$DISPLAY在采购时设置不正确 .tmux.conf,所以这就是为什么我必须使用tmux show-envand 提取它的原因sed

如果您的tmux> = 1.8,则可以使用以下命令修改该命令copy-pipe

bind-key -t vi-copy y copy-pipe 'xclip -in -selection clipboard -d `tmux show-env | sed -n s/^DISPLAY=//p` >/dev/null'

/home/linux/.tmux.conf:11: invalid or unknown command: bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's[0/0] PLAY=//p'` >/dev/null
用户

@user sed您显示的命令与我编写的命令不同...这是您在your中编写的命令.tmux.conf吗?
PlasmaBinturong

我只是复制并粘贴了您的代码。
用户

@user,很奇怪。可能有很多错误来源。首先检查您的报价是否正确。然后,您熟悉sed吗?该命令应为:sed -n s/^DISPLAY=//p。或者,您可以使用cuttmux show-env DISPLAY | cut -d'=' -f2。也可能值得检查您的tmux版本。
PlasmaBinturong

3

我试图找出一种不错的方法将tmux缓冲区中的内容复制到剪贴板中。我已经尝试了几种不同的方法,例如

对于emacs样式绑定,有几种不同的选择。(Vi风格应该类似吗?)在emacs中执行“复制选择”的典型绑定是Mw,因此在tmux中具有相同的绑定将非常方便。

1-会是理想的,但是不起作用(由于tmux的限制?)

unbind-key -t emacs-copy M-w
bind-key -t emacs-copy M-w copy-selection\; \
  run-shell "tmux save-buffer - | xsel --input --clipboard"

2- 对我而言妥协的妥协:接受对tmux中的emacs-copy使用不同的键绑定。例如使用CMw。(此绑定将“全局”定义-不仅在复制模式下,而且仅在复制模式下有用)

bind-key -n C-M-w send-keys M-w\; \
 run-shell "tmux save-buffer - | xsel --input --clipboard" 

3

这些答案中的许多对我在zsh上的Ubuntu 14.04都无效。不知道我的外壳程序是否与此有关,但是这是我使用此策略进行复制并使用此策略进行粘贴的工作版本。

    bind-key -t vi-copy 'v' begin-selection
    bind-key -t vi-copy 'y' copy-pipe "xclip -sel clip -i"
    bind-key ] run-shell "xclip -sel clip -o | tmux load-buffer - ; tmux paste-buffer" 

一些注意事项:

  • 对于复制管道,我需要使用来指定剪贴板-sel clip -i。该行将yank组合到tmux缓冲区,并将其发送到xclip。
  • 要实际粘贴它,我需要再次指定使用哪个剪贴板 -sel clip -o

现在,这对于我的vim / zsh / tmux设置非常有效。


谢谢!-sel clip -i解决了问题。虽然,我不明白为什么您需要再次指定剪贴板以将其粘贴(]对我而言标准有效)
melekes

1

@Leif答案的改进版本可能是:

tmux bind-key '[' run "tmux copy-mode;
tmux bind-key -n ']' run \"tmux send-keys Enter; tmux save-buffer - | xclip -i -selection clipboard;
tmux unbind-key -n ']'\";
tmux bind-key -n q run \"tmux unbind -n ']'; tmux send-keys q\";
tmux bind-key -n C-c run \"tmux unbind -n ']'; tmux send-keys C-c\""

这样,如果您以[]以外的其他方式退出复制模式,则没有任何后果,以上代码被包裹在tundle / tmux-yank一个tmux插件中,用于将tmux文本复制到系统剪贴板中,它的目标是在OS X上tmux> = 1.6和Linux。


1

在具有tmux 2.2或更高版本的OS-X上,可以使用以下功能:

bind-key -t emacs-copy MouseDragEnd1Pane copy-pipe "pbcopy"
bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "pbcopy"

1

我使用copyq多行剪贴板管理器。(它适用于Windows,OSX,Linux。)

  • 在中添加以下行~/.tmux.conf

    set-window-option -g mode-keys vi
    bind C-y run 'out=`tmux save-buffer - ` && copyq add "$out"'
    
  • cygwin要求copyq.exe位于~/.bashrc

    export PATH="$PATH:/cygdrive/c/Program Files (x86)/CopyQ"
    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.