
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, reloaded
um dem Benutzer mitzuteilen, dass es passiert ist. Aber dies zeigt einen Fehler an, source-file
wenn 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 r
sollte ein oder mehreretmux-Befehle(mit oder ohne Argumente). source-file ~/.tmux.conf
ist 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). echo
Ist aber kein tmux-Befehl.
Es gibt jedoch dierun-shell
tmux-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-file
von einer Shell aus auszuführen, müssen Sie aufrufen tmux source-file …
. Diese Zeile .tmux.conf
sollte funktionieren:
bind-key r run-shell 'tmux source-file ~/.tmux.conf && echo reloaded'
Die Ausgabe der Shell (also echo
in 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-file
und display-message
um 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"'