Tmux run-shell xclip 不工作

Tmux run-shell xclip 不工作

我正在使用 tmux 2.3,想要定义一个命令将粘贴缓冲区发送到系统剪贴板。我尝试过使用下面的命令以及我能想到的每个变体,但是当我尝试运行它时,我收到一条消息,说它返回退出代码 1。当在 sh 中运行命令时,它工作正常,当我删除xclip 部分它不会引发错误。如何调试导致错误的原因?我相信我有正确的命令。

bind-key b run-shell "tmux show-buffer | xclip -sel clip -i > /dev/null"

答案1

注意:最初的问题提到了tmux版本 2.3,我确认所有这些都适用于该版本和 3.2a

对我来说,这通常是由于在tmux没有设置环境变量的情况下启动会话 引起的DISPLAY,这意味着xclip不知道如何与 X 服务器通信。这个 AskUbuntu 答案更关注 SSH,但它包含一个有用的段落

要检查 X11 转发是否启用,请查看 DISPLAY 环境变量的值:echo $DISPLAY。您应该看到类似localhost:10[...]的值 。请注意,如果DISPLAY未设置,则手动设置它是没有用的[...]

这是我的本地非 SSH 会话中的样子tmux

$ echo "${DISPLAY:?}"
:0

如果您得到类似以下内容,则意味着该DISPLAY变量未设置:

$ echo "${DISPLAY:?}"
sh: 1: DISPLAY: parameter null or not set

最好弄清楚如何tmux在 X Server 会话内启动会话,但如果您可以在 X Server 会话内启动终端,则找出变量DISPLAY是什么并在会话中临时设置它可能会很有用tmux,以便看看它是否有效:

export DISPLAY=':0'

Ubuntu 社区 Wiki 对 shell 变量进行了简短而详尽的介绍(它提到了bash,但大多数信息适用于大多数 shell,除了cshtcshfish,它们不符合 POSIX_compile);它描述了DISPLAY接近尾声。请注意,该export VARIABLE_NAME=value语法是 POSIX shell 编程语言的一部分,并且非常违反直觉,即使对于那些具有其他语言经验的人也是如此。这个 Stack Exchange 问题对如何设置环境变量有更多解释。

通常,您可以通过启动终端应用程序,然后使用终端中的 shell 运行命令行程序,在 X Server 会话中启动任何命令行程序。

在 GNOME 上,这看起来像:

  1. 登录到您的帐户
  2. 启动终端
  3. tmux new-session在终端中作为命令运行(有时它无论如何都会连接到已经运行的会话)

启动后,tmux将启动一个DISPLAY设置了环境变量的 shell,并且xclip应该可以工作:

$ xclip -verbose -out
Connecting to X server.
Using UTF8_STRING.

您可能会看到其他内容,如果您的剪贴板已经包含内容,它将回显到终端。在运行之前尝试复制、突出显示或选择一些文本。

如果相反它显示:

xclip: command not found

这意味着xclip尚未安装或找不到。

如果xclip有效,那么您可以尝试将命令设置为tmux键绑定(运行此命令可能仅在已经处于会话内部时才有效tmux ):

tmux bind-key -T prefix b run-shell "tmux show-buffer | xclip -se c -i > /dev/null"

运行tmux list-keys | less显示默认键绑定,以及在配置文件中设置它们的语法

我明确地将键绑定添加到prefix表中。tmux的表中的命令(或键盘快捷键)prefix是通过首先按前导键序列来运行的,默认情况下为Ctrl+ ,或在的语法中为 Cb 。按+然后(Cb b) 应运行该命令。我将用来指示应按下前缀组合键。btmuxCtrlbbprefix

我们确实得到了一个错误。tmux打开包含内容的复制模式'tmux show-buffer | xclip -se c -i > /dev/null' returned 1

如果运行的命令run-shell将任何输出打印到 stdout,则tmux在当前窗格中打开复制模式,显示该输出。如果 shell 命令失败,它还会显示一行,说明返回或退出代码。默认情况下, prefix然后q将退出复制模式。

许多程序将错误打印到 stderr 而不是 stdout,包括tmux's show-buffer,因此错误信息会丢失。要捕获它,我们可以放弃 shell 管道,并更改 shell 重定向:

$ tmux show-buffer
no buffers

$ echo $?  # prints 1 if the previous command failed
1

$ tmux run-shell "tmux show-buffer"
'tmux show-buffer' returned 1

$ tmux run-shell "tmux show-buffer 2>&1"
no buffers
'tmux show-buffer 2>&1' returned 1

返回此错误消息是因为tmux启动时默认没有缓冲区。

如果有任何缓冲区,以下命令将显示这些缓冲区及其内容(默认情况下,它绑定到prefixthen =):

tmux choose-buffer

如果没有缓冲区,则此命令立即返回且没有输出。如果有任何缓冲区,则choose-buffer显示包含所有缓冲区的列表,按上次使用时间排序。按将滚动列表,按Enter会将所选缓冲区的内容粘贴到当前窗格,然后q 退出。

要创建缓冲区,请使用以下set-buffer命令:

$ tmux set-buffer "test content"
$ tmux save-buffer - && echo
test content

注意:&& echo需要 ,因为缓冲区的内容不以换行符结尾

对于至少一个缓冲区,该show-buffer命令将使用最近设置的缓冲区的内容打开复制模式。

请注意,在上面的 shell 会话中,该save-buffer命令会将最近设置的缓冲区的内容打印到文件中,如果-给出文件名,那么它将打印到 stdout。

原来的配置应该是*

bind-key b run-shell "tmux save-buffer - | xclip -sel clip -i"

*我猜您正在尝试将某些内容复制tmux到系统剪贴板。

通常,tmux首先通过进入复制模式来选择文本。默认情况下, this 绑定到prefixthen [。使用默认配置,tmux在复制模式下使用 Emacs 样式的键绑定。在tmux 版本 2.3 中,这些键绑定可以用 来显示tmux list-keys -temacs-copy。在 2.3 以上的版本中,该list-keys命令默认显示所有表中的键绑定。

注意:vi-style 键绑定可以通过在所有命令和配置中替换emacs-copyvi-copycopy-mode-vi代替 来使用copy-mode

所选文本可以复制到系统剪贴板和缓冲区tmux 。在tmux2.3 版本中,可以通过以下方式实现:

bind-key -temacs-copy M-w copy-pipe "xclip -selection clipboard -in"

除了将选定的文本复制到缓冲区之外,这还将覆盖复制模式下Alt+的默认行为,以将选定的文本通过管道传输到。wxcliptmux

在 2.3 以上的版本中,等效配置为:

bind-key -T copy-mode M-w send-keys -X copy-pipe-and-cancel "xclip -selection clipboard -in"

在这两个版本中,以下内容将 用 X 服务器剪贴板的内容创建缓冲区,然后粘贴最新的缓冲区来prefix替换默认行为:]tmux

bind-key -T prefix ']' run-shell 'tmux set-buffer "$(xclip -selection clipboard -out)"' \; paste-buffer

注意xclip像这样使用时,在某些情况下可能会表现得很奇怪。

2016年发布2.3版本,所以大多数软件包存储库应该有更新的版本。

无论哪种方式,我都会建议使用tmux-yank,因为它很好地管理了复制任务tmux


至于调试导致tmux配置错误的原因,一般来说,我们可以采取一些措施来使其变得更容易:

  • 从会话内的终端运行命令tmux(如果可能)
  • 创建临时配置文件
  • 显示消息的时间更长

从会话内的终端运行命令tmux(如果可能)

tmux大多数可以放入配置文件中的命令也可以通过在会话内部、命令行中运行,只需在它们前面加上tmux.大多数 shell 会[ ] ; & " ' 专门解释某些字符,因此在运行tmux命令时,请注意引用这些字符,以便将它们传递给tmux.上面给出的所有命令在以 为前缀tmux且无需修改的情况下以及在配置文件中都将起作用。

可能无法运行这样的命令,例如在复制模式下且 shell 会话不可用时。

如果可能的话,这可以帮助诊断命令的每个部分到底发生了什么。

tmux有时,可以从 的命令提示符 运行该命令(默认情况prefix下是:)。就像在配置文件中一样输入命令,然后按Enter运行它。

例如,在复制模式下,按 然后prefix: 状态行更改为黄色,内容:为 ,后面跟着光标。键入类似命令display-message test,然后按Enter 会将状态行的内容设置为test。要退出,请按终端的中断组合键(大多数终端中的默认值为 Ctrl+ cstty -a可能会显示类似 的内容intr = ^C)。

注意:请参阅“显示更长时间的消息”部分以增加这些消息在状态行中显示的时间

注意:tmux2.4 及更高版本允许从命令提示符运行复制模式命令,例如send-keys -X begin-selection.我不知道在 2.4 之前的版本中如何执行此操作。

创建临时配置文件

为了帮助调试,我们可以在名为的文件中添加潜在的配置更改tmux_debug.conf

# -q: do not return an error if the file doesn't exist
source-file -q /etc/tmux.conf
source-file -q ~/.tmux.conf

# add any experimental configuration below here

并运行tmux

tmux -f ./tmux_debug.conf

tmux启动时,默认情况下它会读取两个配置文件: /etc/tmux.conf~/.tmux.conf.该-f选项指示它忽略这些,并加载自定义文件。由于我们可能依赖这两个配置,因此如果它们存在,我们会获取它们。这将使我们能够保留当前的配置,而无需对其进行永久更改。

我们还可以添加一个键绑定来快速重新加载临时配置文件:

bind-key -T prefix C-r source-file ./tmux_debug.conf \; display-message "sourced configuration"

这将设置键序列prefix然后 Ctrl+r以重新tmux加载启动tmux_debug.conf目录中的文件tmux,然后sourced configurationtmux状态行中显示文本。

显示消息的时间更长

上一个命令在状态行中显示一条消息。默认情况下,tmux 仅在状态行中显示消息 750 毫秒,这令人沮丧。

在配置文件中,添加以下行将导致文本显示,直到按下按键:

set -g display-time 0

注意:按键被发送到刚刚获得焦点的窗格或窗口中正在运行的任何内容

相关内容