Wie sende ich einen Befehl an alle Fenster in tmux?


189

Ich rufe gerne :clear-historyFenster mit einem riesigen Scrollback auf. Ich möchte jedoch ein Skript erstellen, um diesen Befehl an alle Bereiche in den verschiedenen Fenstern zu senden.

Ich weiß, wie ich dank dieser Frage einen Befehl an alle Fenster senden kann, aber wie kann ich einen Befehl auch an alle Fenster in welchem ​​Fenster senden?

send-keysund synchronize-panesvon der tmux manpage kommen mir in den Sinn, aber ich bin mir nicht sicher, wie ich sie zusammen heiraten soll. Aber vielleicht gibt es einen einfacheren Weg, dies zu tun.

Zusätzliche Beobachtungen:

Wenn Sie ein wenig darüber nachdenken, werden tmux list-panes -aanscheinend alle Bereiche der aktuellen Sitzung aufgelistet. Ziemlich nützlich, um damit zu beginnen. Wohin gehe ich von hier aus?


Denn in der Hoffnung , auf diese Frage diejenigen , die eine Lösung zu finden, das für jede Scheibe gilt, in jedem Fenster, in jeder Sitzung: scripter.co/command-to-every-pane-window-session-in-tmux
chb

Antworten:


351

Haben Sie versucht, im tmux-Fenster mit mehreren Fenstern zu folgen?

Ctrl-B :

setw synchronize-panes on

clear history

52
Nur der Vollständigkeit halber, um auszuschalten, wenn Sie es tun würdenCtrl-b :setw synchronize-panes off
Mitch

19
und Sie können Verknüpfungen dafür binden, ~/.tmux.confindem Sie hinzufügen: bind -n C-x setw synchronize-panes on und bind -n M-x setw synchronize-panes off
guneysus

4
ist es möglich, den gleichen Shorcut für das Umschalten einzustellen?
Arnold Roa

20
@ArnoldRoa Ja, die Option wird umgeschaltet, wenn Sie gehen on/off. Sobind -n C-x setw synchronize-panes
Sensation

1
Wenn ich bind -n C-x setw synchronize-paneswelche Verknüpfung hinzufüge , sollte ich drücken, um sie aufzurufen? Ist es Präfix + C & x. Ich habe viele Optionen ausprobiert
Bill Goldberg

28

Ein bisschen spät zur Party, aber ich wollte keine Synchronisierungsfenster setzen und deaktivieren, nur um einen Befehl zu senden, also habe ich eine Wrapper-Funktion um tmux erstellt und eine benutzerdefinierte Funktion namens hinzugefügt send-keys-all-panes.

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

Ich erstelle auch einen Wrapper um den Befehl tmux, um das Aufrufen dieser Funktion zu vereinfachen (der Einfachheit halber). Der Wrapper und der obige Code sind alle hier .

Dadurch kann ich alle Fenster ausführen tmux send-keys-all-panes <command>oder tmux skap <commandan sie senden <command>.

Beachten Sie, dass tmux auf meine Wrapper-Funktion tmux_pp ausgerichtet ist.


Dies ist Bash, aber kann man das gleiche von der tmux-Eingabeaufforderung aus tun, ich meine damitprefix + :
Rho Phi

Ich weiß nicht wie oder ob das möglich ist. In welchem ​​Anwendungsfall müssen Sie einen Befehl senden <prefix>:?
Kshenoy

Ich würde empfehlen, das Bash-Snippet ( : run "yourscript.sh yourargs...") aufzurufen . Wenn Ihr Befehl ausgegeben wurde, zeigt Ihr aktiver oder angegebener Bereich die Ergebnisse an, bis Sie q drücken. In diesem Fall sollte dies jedoch nicht der Fall sein. Natürlich können Sie dies alias / nach Ihren Wünschen binden. Abgesehen davon können innere Prozesse Ihre Tastenanschläge oder deren Auswirkungen unterschiedlich interpretieren, sodass #{pane_current_cmd}möglicherweise eine Whitelist oder eine Blacklist erforderlich ist. Ich habe Strg + K gebunden, um Strg + L und Clear-History zu senden; Dies funktioniert gut für Muscheln, verstopft aber Vims Puffer. Ich müsste verfeinert werden, bevor ich meine Strg + k senden kann.
John P

Dies kann eher ein XY-Problem sein. Die Tmux-Eingabeaufforderung ist nützlich, aber es scheint, als würden Sie sie verwenden, da keine andere Eingabeaufforderung geöffnet ist. Sie können eine Schlüsselbindung einrichten - ohne das Präfix, wenn Sie möchten -, um einen zusätzlichen Bereich mit der Shell Ihrer Wahl umzuschalten und zu fokussieren, anstatt <prefix>:vor jedem Befehl zu senden , die Ausgabe nach dem Verlassen des Befehls zu verlieren und alle Fallstricke, die dies sind kommen mit der Ausführung über Tmux. Zum Beispiel führt <prefix>:run "man cat"dies nicht dazu, dass der Mensch in pidof manoder sogar ps auxf | grep manals "weniger" in meinem aktuellen Pager für den Menschen erscheint.
John P

Der Link ist tot
Mateusz Piotrowski

10

Update Juni 2019

Kurze Darstellung, wie Sie Ihre eigene Bindung für die Synchronisierung von Fenstern konfigurieren .

Folgendes wurde zu meinem hinzugefügt tmux.conf(die Kommentare gelten sicherlich für meine Gesamtkonfiguration):

# 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

Jetzt kann ich die Möglichkeit zum Synchronisieren von Befehlen über mehrere Bereiche hinweg umschalten <C-a><C-y>.

(Ja, ich habe den Bindeschlüssel erneut Strg a zugeordnet.)


4

Keine der oben genannten Antworten hat bei mir funktioniert (tmux v2.3), aber dies geschah über die Bash-Befehlszeile:

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

Ein allgemeineres Skript für andere tmux-Befehle als 'clear-history' würde dieses Element nur durch einen Parameter ersetzen, z. $ 1. Seien Sie vorsichtig, wenn Sie beabsichtigen, ein Skript für eine Reihe von tmux-Befehlen zu schreiben, da auf jedes "-t $ {_ pane}" angewendet werden muss.

Beachten Sie, dass der -aParameter to tmux list-paneserforderlich ist, um alle Bereiche in allen Fenstern in allen Sitzungen abzudecken. Ohne dies sind nur Fenster in Ihrem aktuellen tmux-Fenster betroffen. Wenn Sie mehr als eine tmux Sitzung geöffnet haben und wollen nur den Befehl Scheiben in der aktuellen Sitzung anwenden, ersetzen -amit -s(Es ist alles in der tmux Manpage).

Ich habe nicht die Mod-Punkte, um jede der oben genannten Antworten direkt zu kommentieren. Deshalb haben sie hier nicht für mich funktioniert:

Das Problem, das ich mit der Antwort von @ shailesh-garg hatte, war, dass die Synchronisierung nur Befehle betraf, die innerhalb der Fenster ausgegeben wurden, nicht tmux-Befehle, die mit Ctrl-B :außerhalb der Fenster ausgegeben wurden .

Die drei Probleme, die ich mit @kshenoys Antwort hatte, waren folgende:

  1. Es sendet Tastenanschläge innerhalb eines Bereichs, nicht an die tmux-Operation dieses Bereichs. Wenn beispielsweise eine Bash-Shell im Bereich ausgeführt wird und das Skript zum Senden von "Clear-History" verwendet wird, sind dies die Tastenanschläge würde in der Bash-Befehlszeile erscheinen. Eine Problemumgehung wäre, "tmux clear-history" zu senden oder "tmux" an "$ @" anzuhängen, aber ich habe die Antwort aufgrund meiner anderen Probleme mit der Antwort nicht bearbeitet.
  2. Ich konnte nicht herausfinden, wie man ein neues Zeilenzeichen sendet, ohne die Zeile buchstäblich zu unterbrechen.
  3. Selbst wenn ich das tat, hatte das Senden von "tmux clear-history" keine Auswirkung.

3

meine tmux version ist 1.9a und das funktioniert bei mir, ein schlüssel reicht sowohl zum ein- als auch zum aus

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  

Ersetzen Sie die "Sitzungs-ID" und den "Befehl" entsprechend.


möchte etwas über diese fremde Sprache sagen
Muhammad Omer Aslam

Was? Englisch ist nicht schwer. Aber wenn Sie etwas zu sagen haben, dann sagen Sie es.
RJ

4
:DAlter, Sie müssen Ihrer Antwort eine Beschreibung hinzufügen, da sie nur sehr wenig Text enthält. Aus diesem Grund erkennt Stackoverflow sie als Spam oder Post von geringer Qualität. Fügen Sie einfach einige Details hinzu, damit sie nicht darunter angezeigt werden.
Muhammad Omer Aslam

6
Das ist lustig, die akzeptierte Antwort hat auch keine Beschreibung und nur den Code, aber was auch immer.
RJ

0

Dies ist meine Dienstprogrammfunktion, die den Befehl nur ausführt, wenn im Bereich nichts ausgeführt wird.

#!/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
}

Beispiel für eine Sitzung mit dem Namen dev, bei der eine Python-Virtualenv in allen Bereichen aktiviert wird, die sich in befinden, bashoder zshdie Ausführung des Befehls in Bereichen mit vim oder einer anderen ausführbaren Datei vermieden wird:

_send_bash_command_to_session dev workon myvirtualenv

oder leichter zu merken: um es in der aktuellen Sitzung zu tun:

tmux_set_venv myvirtualenv

Finden Sie meine Konfigurationsdatei mit dieser Funktion.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.