tmux führt eine Pipe/Befehlskette mit Tastenkombination aus

tmux führt eine Pipe/Befehlskette mit Tastenkombination aus

Wie kann ich eine Befehlskette wie in Shells mit tmux ausführen? Ich möchte mehrere Befehle basierend auf ihrem Erfolg ausführen. Ich möchte eine Echoausgabe an das Terminal (oder die Befehlsleiste) senden.

Ich habe z. B. eine Tastenkombination, um die Konfiguration wie folgt neu zu laden. Und ich möchte auch eine Ausgabe, reloadedum dem Benutzer mitzuteilen, dass es passiert ist. Aber dies zeigt einen Fehler an, source-filewenn ich es auslöse.

bind r source-file ~/.tmux.conf   # works fine
bind r source-file ~/.tmux.conf && echo reloaded.   # doesn't work shows source-file help in command bar.
bind r source-file ~/.tmux.conf; echo reloaded.  # doesn't work, says not recognized 'echo'

Und auf welcher Shell wird dieser Befehl aufgerufen? Standard-Shell oder aktuelle Shell oder Vordergrundprogramm, das im Tab/Fenster/Bereich ausgeführt wird? Meine Standard-Shell ist fish.

Antwort1

Was Sie danach angeben, bind rsollte ein oder mehreretmux-Befehle(mit oder ohne Argumente). source-file ~/.tmux.confist ein gültiger tmux-Befehl. source-file ~/.tmux.conf && echo reloaded.ist nicht. Um mehr als einen tmux-Befehl auszuführen, müssen Sie verwenden ;(manchmal in Form von \;, sieheBinden einer tmux-Taste an mehrere Befehlefür Details). echoIst aber kein tmux-Befehl.

Es gibt jedoch dierun-shelltmux-Befehl, mit dem Sie ausführen könnenwillkürlichCode in einer Shell. Meine Tests sagen mir, dass die Shell es ist sh(auch wenn mein Befehlsinterpreter es nicht ist sh). Das Handbuch bestätigt:

Shell-BefehlArgumente sind sh(1)Befehle.

Um es source-filevon einer Shell aus auszuführen, müssen Sie aufrufen tmux source-file …. Diese Zeile .tmux.confsollte funktionieren:

bind-key r run-shell 'tmux source-file ~/.tmux.conf && echo reloaded'

Die Ausgabe der Shell (also echoin diesem Fall von ) wird im Ansichtsmodus angezeigt. Mir persönlich wäre es lieber, wenn die Kurzmeldung in der Statuszeile angezeigt würde, daher würde ich eher diese Variante verwenden:

bind-key r run-shell 'tmux source-file ~/.tmux.conf && tmux display-message reloaded'

Es ist recht aufschlussreich zu analysieren, was passiert, wenn Sie diese Bindung auslösen. Sie befinden sich in einem Tmux-Client, der mit einem Tmux-Server kommuniziert. Wenn der Client eine entsprechende Tastenfolge empfängt, prefixrinformiert er den Server, und der Server handelt entsprechend der Bindung: Er führt eine Shell aus. Die Shell führt einen weiteren Tmux-Client aus, der mit demselben Tmux-Server kommuniziert und ihn dazu bringt, den source-file …Befehl auszuführen. Dann führt die Shell einen weiteren Tmux-Client aus, der mit dem Server kommuniziert und ihm mitteilt, dass er ausführen soll display-message ….

Mit anderen Worten: Der Server führt einen Code aus, der Clients erzeugt, die demselben Server sagen, etwas zu tun.

Ihre ursprünglich funktionierende Bindung ( bind r source-file ~/.tmux.conf) ist viel einfacher, der Server läuft source-file …direkt.

Da es sich bei source-fileund display-messageum tmux-Befehle handelt, können Sie beide mit einem Tastendruck ausführen, ohne eine Shell zu starten:

bind-key r source-file ~/.tmux.conf \; display-message reloaded

Man würde erwarten, \;dass es hier wie in einer Shell funktioniert ;, aber in Wirklichkeit ist es eher wie &&. Das HandbuchZustände:

Jeder Befehl wird durch eine neue Zeile oder ein Semikolon ( ;) abgeschlossen. Durch Semikolon getrennte Befehle bilden zusammen einBefehlssequenz- Wenn bei einem Befehl in der Sequenz ein Fehler auftritt, werden keine nachfolgenden Befehle ausgeführt.

Diese letzte Bindung scheint in Ihrem Fall also genau richtig zu sein, sie erzeugt keine unnötige Shell. Trotzdem ist es gut zu wissen, dass Sie alles über ausführen können run-shell, sogar zusätzliche tmux-Clients.

Sie können die beiden Ansätze mischen:

bind-key r source-file ~/.tmux.conf \; run-shell '#some complex logic here or whatever'

Und da istif-shell. Beispiel:

bind-key r if-shell 'tmux source-file ~/.tmux.conf' 'display-message reloaded' 'display-message "reload failed"'

verwandte Informationen