tmux 将密钥绑定到 bash 命令拒绝工作

tmux 将密钥绑定到 bash 命令拒绝工作

我希望能够重新生成当前窗口中不处于树模式的所有窗格。我制作了这个脚本并且它有效:

for i in $(tmux list-panes -F "#{line} #{pane_id} #{pane_mode} #{pane_active}" | sort -k3 | grep -v tree-mode | awk '{print$2}'); do tmux respawn-pane -k -t $i; done

我想将其绑定到 tmux-action + Rkey。但这是行不通的。

我尝试了以下方法:

bind-key R send-keys "for i in $(tmux list-panes -F "#{line} #{pane_id} #{pane_mode} #{pane_active}" | sort -k3 | grep -v tree-mode | awk '{print$2}'); do tmux respawn-pane -k -t $i; done"
bind-key R run-shell "for i in $(tmux list-panes -F "#{line} #{pane_id} #{pane_mode} #{pane_active}" | sort -k3 | grep -v tree-mode | awk '{print$2}'); do tmux respawn-pane -k -t $i; done" Enter

我还尝试将脚本放入文件中并将以下内容添加到.tmux.conf

bind-key R run-shell "./tmux_respawn.sh"

但我收到 127 错误,但不知道为什么。如果我从当前窗格运行脚本,我不会收到错误,并且它可以工作。

我也尝试在 ~/.bashrc 中构建一个别名,它在 shell 中工作正常,但在尝试通过绑定键运行它时出现 shell 127 错误。

alias RespawnTmuxPanes='for i in $(/usr/local/bin/tmux list-panes -F "#{line} #{pane_id} #{pane_mode} #{pane_active}" | sort -k3 | grep -v tree-mode | awk '{print$2}'); do /usr/local/bin/tmux respawn-pane -k -t $i; done'

我真的不想为这个脚本创建一个单独的文件,我想.tmux.conf使用绑定密钥直接运行它,我该如何实现这一点?

答案1

我放弃了直接在其中运行脚本的尝试,~/.tmux.conf并将脚本构建为一个单独的文件,让 tmux 运行。

剧本:

#!/bin/bash
for i in $(tmux list-panes -F '#{pane_id} #{pane_mode} #{pane_active}' -f '#{?#{m:tree-mode,#{pane_mode}},0,1}' | sort -k2 | cut -f1 -d' '); do tmux respawn-pane -k -t $i; done

注意:我找到了一种与 tmux 一起使用-f来过滤树模式窗格的方法,因此我不需要使用awk.

这是我的 tmux 文件中的条目:

bind-key R run-shell "/home/mradmin/.tmux_respawn_screens.sh"

这是有效的,因为我现在可以执行 TMUX-ACTION + R,它会重新生成所有不处于树模式的窗格,并执行我最后所在的活动窗格。

答案2

这可能最好通过调用外部脚本(可能使用完全限定的路径,例如/home/user/libexec/tmux-foo)来完成,否则必须处理tmuxsh、 以及awk 插值和引用规则的分层嵌套。乐趣!

此外,该命令太复杂,特别是考虑到它以多种方式被破坏,最值得注意的是内部"必须全部用 转义\",并且也许其中一些$variables还需要\$variable 转义以保护它们免于tmux插值。

因此,我们需要一些简单的东西,以及一种重新加载配置的方法tmux ,以确保我们获得新的配置,并确认它tmux不会对我们大喊大叫,因为您将犯下许多拼写错误(除非您犯的拼写错误比我少) )。另外,我已经有R重新加载的功能,因此我将特殊命令放在 上W,您可能想要更改它。

bind-key R source-file ~/.tmux.conf \; display-message "source-file done"
bind-key W run-shell "tmux list-panes -F \"#{pane_id} #{pane_mode}\" >> SOMEOUTPUTFROMTMUX"

有了这个,我们就可以运行R W并确认没有语法错误tmux报告,然后找到该SOMEOUTPUTFROMTMUX 文件,该文件可能位于您的主目录下,否则应该很容易找到。在另一个终端中,我们可以在修改tmux配置时查看该文件:

tail -f SOMEOUTPUTFROMTMUX

我还根据我运行命令的方式将tmux命令简化为#{line}存在或不存在tmux,并且移动的列使得选择正确的列有点awk困难。 Alsogrep ... | awk ...通常可以简化为更复杂的awk ...表达式,这会缩短我们的命令并节省一些 CPU 时间。

bind-key W run-shell "tmux list-panes -F \"#{pane_id} #{pane_mode}\" | awk '!/tree-mode/{print $1}' >> SOMEOUTPUTFROMTMUX"

R W请务必经常在tmux;中进行测试。试图一次性完成所有事情是很复杂的。在每个新的 shell 命令之后进行测试可以让您知道您是否走在正确的轨道上。以上排除了这些 tree-mode东西。

bind-key W run-shell "tmux list-panes -F \"#{pane_id} #{pane_mode}\" | awk '!/tree-mode/{print $1}' | while read id; do echo $id >> SOMEOUTPUTFROMTMUX; done"

糟糕,输出文件是空的。tmux显然对未引用的内容做了一些处理$id,所以我们用\$id

bind-key W run-shell "tmux list-panes -F \"#{pane_id} #{pane_mode}\" | awk '!/tree-mode/{print $1}' | while read id; do echo \$id >> SOMEOUTPUTFROMTMUX; done"

\$id反过来必须用引号引起来,以防止 POSIX shell 用它做疯狂的事情,否则,但不能用单引号引起来,因为我们确实需要 shell 来插入它:

bind-key W run-shell "tmux list-panes -F \"#{pane_id} #{pane_mode}\" | awk '!/tree-mode/{print $1}' | while read id; do echo \"\$id\" >> SOMEOUTPUTFROMTMUX; done"

无论如何,按照这种方法,应该可以 tmux重新添加其他变量,然后使sort命令正常工作,并且只有在结果看起来不错之后,才用实际 命令echo替换穴居人调试(将输出打印到文件)tmux跑步:

... while read id; do tmux respawn-pane -k -t \"\$id\"; done

或者您可以在外部脚本中执行此操作,这会为您提供一个更容易测试的文件,并且不会违反tmux插值shawk转义规则。

相关内容