如何向tmux中的所有窗格发送命令?


189

我喜欢:clear-history在滚动大的窗格上进行调用。但是,我想编写一种脚本来将此命令发送到各个窗口中的所有窗格。

出于这个问题,我知道如何向所有窗口发送命令,但是如何也向所有窗口的所有窗格发送命令?

send-keyssynchronize-panes从TMUX手册页浮现在脑海中,但我不知道如何将它们一起结婚。但是也许有一种更简单的方法可以做到这一点。

额外观察:

考虑一下这一点,tmux list-panes -a似乎列出了当前会话中的所有窗格。首先非常有用。我从这里去哪里?


对于那些希望找到适用于每个窗格,每个窗口,每个会话的解决方案的人:scripter.co/command-to-every-pane-window-session-in-tmux
chb

Answers:


351

您是否尝试过在带有多个窗格的tmux窗口中关注

Ctrl-B :

setw synchronize-panes on

clear history

52
只是为了完整起见,如果您不愿意,请关闭Ctrl-b :setw synchronize-panes off
Mitch

19
您可以~/.tmux.conf通过添加以下内容来绑定快捷方式:bind -n C-x setw synchronize-panes on bind -n M-x setw synchronize-panes off
guneysus

4
是否可以为切换设置相同的快捷方式?
Arnold Roa

20
@ArnoldRoa是的,如果您离开,该选项将切换on/off。所以bind -n C-x setw synchronize-panes
轰动

1
如果添加bind -n C-x setw synchronize-panes什么快捷方式应该按调用?它是前缀+ C&x。我尝试了很多选择
Bill Goldberg

28

聚会晚了一点,但是我不想设置和取消设置同步窗格只是为了发送一个命令,所以我围绕tmux创建了包装函数,并添加了一个自定义函数send-keys-all-panes

_tmux_send_keys_all_panes_ () {
  for _pane in $(tmux list-panes -F '#P'); do
    tmux send-keys -t ${_pane} "$@"
  done
}

我还围绕tmux命令创建了一个包装器,以简化对该函数的调用(为方便起见)。包装器和上面的代码都在这里

这使我可以运行tmux send-keys-all-panes <command>tmux skap <command发送<command>到所有窗格。

请注意,tmux是我的包装函数tmux_pp的别名。


这是bash,但是可以从tmux命令提示符中做同样的事情,我的意思是这样做prefix + :
Rho Phi 2016年

我不知道如何或是否有可能。您需要通过<prefix>:哪种方式发送命令?
kshenoy '16

我建议调用bash片段(: run "yourscript.sh yourargs...");如果命令已输出,则活动或指定的窗格将一直显示结果,直到按q为止,但在这种情况下则不会。当然,您可以根据自己的喜好对其进行别名/绑定。顺便说一句,内部流程可能会以不同的方式解释您的击键或其效果,因此#{pane_current_cmd}可能需要白名单或黑名单。我必须按ctrl + k来发送ctrl + l和清除历史记录;这对于s​​hell很有效,但是会破坏Vim的缓冲区。在广播ctrl + k之前,我需要改进。
约翰·P

这可能更多是XY问题;Tmux命令提示符很有用,但听起来好像您正在使用它,因为您没有打开其他命令提示符。您可以设置一个键绑定(如果需要,可以不带前缀)来切换并集中显示一个带有您选择的外壳的额外窗格,而不是<prefix>:在每个命令之前发送,在离开命令之后丢失输出以及所有的陷阱通过Tmux执行。例如,<prefix>:run "man cat"不会导致man出现在我当前的man寻呼机中,pidof man甚至ps auxf | grep man不会出现,甚至也不会显示为“ less”。
约翰·P

链接已
消失

10

2019年6月更新

关于如何配置自己的绑定以同步窗格的快速说明。

在我的内容中添加了以下内容tmux.conf(这些注释当然适用于我的整体配置):

# synchronize all panes in a window
# don't use control S, too easily confused
# with navigation key sequences in tmux (show sessions)
unbind C-S
bind C-Y set-window-option synchronize-panes

现在,我可以使用切换跨多个窗格同步命令的功能<C-a><C-y>

(是的,我将绑定键重新映射为Ctrl a)。


4

上面的答案都不对我有用(tmux v2.3),但这确实是从bash命令行执行的:

for _pane in $(tmux list-panes -a -F '#{pane_id}'); do \
  tmux clear-history -t ${_pane}  ; done

对于tmux命令(不是“清除历史记录”),更通用的脚本将只是用参数替换该元素。$ 1。如果要编写脚本来处理一系列tmux命令,请务必小心,因为“ -t $ {__ pane}”将需要应用于每个命令。

请注意,必须使用-a参数to tmux list-panes才能覆盖所有会话中所有窗口中的所有窗格。否则,仅会影响当前tmux窗口中的窗格。如果您打开了多个tmux会话,并且只想将该命令应用于当前会话内的窗格,请替换-a-s(全部在tmux手册页中)。

我没有Mod点可以直接对以上每个答案进行评论,所以这就是为什么它们对我不起作用的原因:

我对@ shailesh-garg的回答所遇到的问题是,同步仅影响窗格内发出的命令,而不影响窗格外使用的tmux命令Ctrl-B :

我对@kshenoy的答案的三个问题是:

  1. 它会将击键发送到窗格内,而不是发送到该窗格的tmux操作,因此,例如,如果一个击键在该窗格中运行,并且使用脚本发送“清除历史记录”,则这些击键将是将出现在bash命令行中。解决方法是发送“ tmux清除历史记录”或在“ $ @”之前添加“ tmux”,但是由于答案存在其他问题,因此我没有编辑答案。
  2. 我不知道如何发送换行符而又不打断行。
  3. 即使我这样做,发送“ tmux清除历史记录”也没有效果。

3

我的tmux版本是1.9a,这对我有用,一键开启和关闭都足够

bind-key X set-window-option synchronize-panes\; display-message "synchronize-panes is now #{?pane_synchronized,on,off}"

2
tmux send-keys -t <session id> <command> C-m  

相应地替换“会话ID”和“命令”。


想谈一谈这种外语
穆罕默德·奥默·阿斯兰

什么?英语不难。但是,如果您有话要说,那就说吧。
RJ

4
:D伙计,您需要在答案中添加一些说明,因为它的文字非常少,因此,Stackoverflow将其检测为垃圾邮件或低质量的帖子,只需为其添加一些细节,使其不会出现在其下方。
穆罕默德·奥默·阿斯兰

6
太好笑了,被接受的答案也没有描述,只有代码,但无论如何。
RJ

0

这是我的实用程序功能,仅当窗格中没有任何运行时才执行命令。

#!/bin/bash

_send_bash_command_to_session() {
    if [[ $# -eq 0 || "$1" = "--help" ]] ; then
        echo 'Usage: _send_bash_command_to_session $session_name what ever command you want: '
        return
    fi
    input_session="$1"
    input_command="${@:2}"
    for _pane in $(tmux list-panes -s -t ${input_session} -F '#{window_index}.#{pane_index}'); do
        # only apply the command in bash or zsh panes.
        _current_command=$(tmux display-message -p -t ${input_session}:${_pane} '#{pane_current_command}')
        if [ ${_current_command} = zsh ] || [ ${_current_command} = bash ] ; then
            tmux send-keys -t ${_pane} "${input_command}" Enter
        fi
    done
}

tmux_set_venv() {
    _current_session=$(tmux display-message -p '#{session_name}')
    _send_bash_command_to_session ${_current_session} workon $1
}

以一个名为dev的会话为目标的示例,在bash或中的所有窗格中启用python virtualenv zsh,避免在具有vim或任何其他可执行文件的窗格中执行命令:

_send_bash_command_to_session dev workon myvirtualenv

或更容易记住:在当前会话中进行:

tmux_set_venv myvirtualenv

使用此功能查找我的配置文件

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.