Tmux blockieren, bis das Programm abgeschlossen ist

Tmux blockieren, bis das Programm abgeschlossen ist

Ich bin beeindruckt von den Fernsteuerungsfunktionen von tmux:

tmux new-window -t p12346 'echo foo;sleep 10' 

Dadurch wird in der Sitzung ein neues Fenster mit dem Namen p12346 erstellt und nichts auf dem Bildschirm gedruckt. Das ist großartig. Aber wie kann ich dem obigen Befehl sagen, dass er warten soll, bis der Ruhezustand beendet ist, bevor er zurückkehrt? D. h. ich möchte, dass dies dasselbe tut, aber die Ausführung 10 Sekunden dauert:

time tmux new-window -t p12346 'echo foo;sleep 10' 

Hintergrund

Wenn dies realisierbar ist, könnte es ein Feature von GNU Parallel werden: Auf die aktuell laufenden Jobs kann über in jedem ihrer Fenster zugegriffen werden tmux, sodass Sie den Fortschritt jedes Jobs in Echtzeit verfolgen können.

Wird daher tmuxnicht im Vordergrund ausgeführt: Der Benutzer muss eine Verbindung dazu herstellen.

Antwort1

tmux1.8 hat den wait-forBefehl eingeführt, mit dem Sie das gewünschte Ergebnis erzielen können:

time tmux new-window -t p12346 'echo foo;sleep 10;tmux wait-for -S p12346-neww-done' \; \
          wait-for p12346-neww-done

Der Name des „Kanals“ ( p12346-neww-doneim obigen Beispiel) kann beliebig sein (solange er an beiden Stellen gleich ist; wenn Sie mehrere möglicherweise gleichzeitige Aufrufe erwarten, möchten Sie wahrscheinlich auch für jeden Aufruf einen eindeutigen Wert verwenden). Wichtig ist, dass Sie nach dem new-windowBefehl auf das Signal „warten“ (als Teil desselbentmuxBefehl, daher das maskierte Semikolon:tmuxmuss es verarbeiten, nicht die Shell) und das Signal als letzten Schritt des Fensterbefehls senden.

Wenn Sie etwas robuster sein müssen, um zu verhindern, dass Ihre Befehlssequenz auf hässliche oder unbequeme Weise abgebrochen wird, können Sie versuchen, zum Senden des Signals eine Shell-Trap zu verwenden (der Lesbarkeit halber etwas neu angeordnet(?)):

time \
tmux new-window -t p12346 '
       trap "tmux wait-for -S p12346-neww-done" 0
       echo foo
       sleep 10
       ' \; wait-for p12346-neww-done

Antwort2

Möglicherweise ist der folgende alternative Ansatz für Sie geeigneter:

Außerhalb von tmux:

mkfifo fifo && tmux new -d '(echo foo;sleep 3) 9> fifo' && time cat fifo

Innerhalb von tmux:

mkfifo fifo && tmux new-window '(echo foo;sleep 10) 9> fifo' && cat fifo 

Ein Unterschied besteht darin wait-for, dass dieser Ansatz wie ein Totmannschalter funktioniert: Er funktioniert auch dann, wenn der wait-for -SBefehl aus irgendeinem Grund nie ausgeführt wird.

Ein weiterer Unterschied besteht darin, dass gewartet wird, bis alle untergeordneten Prozesse des Hauptprozesses beendet werden (es sei denn, sie schließen explizit andere Dateideskriptoren, was bei Programmen häufig vorkommt, die versuchen, sich in den Hintergrund zu versetzen).

Erklärung: Der catBefehl wartet, bis etwas das andere Ende des FIFO öffnet, und wird dann beendet, wennalleInstanzen dieses Dateideskriptors werden geschlossen. Dies geschieht, wenn alle Prozesse, die ihn enthalten, beendet werden. Der Effekt wird auf untergeordnete Prozesse übertragen, da Dateideskriptoren standardmäßig die offenen Dateideskriptoren des übergeordneten Prozesses erben.

verwandte Informationen