/ / Befehle anzeigen, die im Hintergrund im tmux-Bereich ausgef√ľhrt werden - Shell, tmux, Multiplexing

Zeigt Befehle an, die im Hintergrund im tmux-Bereich ausgef√ľhrt werden - Shell, tmux, Multiplexing

Sehr oft sende ich nvim, ranger oder andere Anwendungen im Hintergrund mit Strg+z und dann vergessen, in welchem ‚Äč‚ÄčFenster genau es ge√∂ffnet war - es ist eine ziemlich m√ľhsame Aufgabe, Dutzende von Fenstern zu erzwingen.

Gibt es etwas √§hnliches zu ${pane_current_command}, aber f√ľr Hintergrundaufgaben?

#(echo $(jobs -l)) funktioniert wahrscheinlich nicht, weil sie immer an eine andere Sitzung gebunden sind.

Antworten:

0 f√ľr Antwort ‚ĄĖ 1

Gibt es etwas √§hnliches zu ${pane_current_command}, aber f√ľr Hintergrundaufgaben?

Nein, es ist nicht so einfach, wie Sie denken.

#(echo $(jobs -l)) funktioniert wahrscheinlich nicht, weil sie immer an eine andere Sitzung gebunden sind.

jobs ist eine eingebaute Shell. Der Befehl zeigt Ihnen die Jobs der Shell, die ihn ausf√ľhrt. In Ihrem Fall h√§ngt alles davon ab, wie Sie das Snippet ausf√ľhren und wie Sie es zitieren.

  • Wenn du l√§ufst tmux ‚Ķ Das verwendet dieses Snippet direkt in einer Shell, deren Jobs Sie kennen wollen und die Sie nicht in Anf√ľhrungszeichen setzen $(), so wird es vorher durch die Shell erweitert tmux ausf√ľhrbare sogar l√§uft, dann wird es irgendwie funktionieren ("irgendwie", weil richtige Anf√ľhrungszeichen und geraten wird echo ist hier nicht das beste Werkzeug; Erw√§gen printf "%sn").

  • Wenn du l√§ufst tmux ‚Ķ Das verwendet dieses Snippet in einer Shell, die nicht die Shell ist, deren Jobs Sie kennen wollen und die Sie nicht in Anf√ľhrungszeichen setzen $()wird es erweitert (d. h. jobs wird ausgef√ľhrt) von der falschen Shell.

  • Wenn du

    • Lauf tmux ‚Ķ das verwendet dieses Snippet und Sie in Anf√ľhrungszeichen $()
    • oder es gibt keine √§u√üere H√ľlle, die sich ausdehnen k√∂nnte $() Vor tmux ausf√ľhrbare L√§ufe
    • oder Sie verwenden das Snippet direkt in tmux (Pr√§fix: oder √ľber eine Schl√ľsselbindung)

    </ p>

    dann $() wird um eine Shell erweitert, die von tmux das Innere von verarbeiten #(). Beachten Sie in diesem Fall echo oder printf ist nicht erforderlich oder sogar schädlich. Es macht nicht viel aus, weil die Shell, die verarbeitet, was drin ist #() ist sowieso nicht der, den du willst.

Mir ist keine Möglichkeit (Schnittstelle) in einer Shell bekannt, mit der Sie die Shell nach ihren Jobs abfragen können von außen.


Einen Befehl eingeben (don "t)

Eine beschwerliche Sache, die Sie tun k√∂nnen, ist zu spritzen jobs -lEingeben in die eigentliche Shell, die in einem Bereich ausgef√ľhrt wird, als ob Sie sie eingegeben h√§tten; tmux kann das mit Sicherheit (send-keys). Dann m√ľssen Sie die Ausgabe erfassen und isolieren. tmux kann das wahrscheinlich. Aber:

  • Das Fenster befindet sich m√∂glicherweise im Kopiermodus oder in einem anderen Modus.
  • Der Prozess im Bereich ist m√∂glicherweise keine Shell.
  • oder es kann eine Shell sein, die gerade etwas ausf√ľhrt (Schl√ľssel gehen zu einem untergeordneten Programm);
  • oder die Befehlszeile darf nicht leer sein, wenn Sie mit der Injektion beginnen;
  • und selbst wenn das Injizieren gut verl√§uft, kann es andere (Hintergrund-) Prozesse geben, die an die Konsole ausgegeben werden.

Dieser Ansatz ist sehr unzuverlässig. Sie können es verbessern, indem Sie den Befehl selbst dazu bringen, tmux aufzufordern, etwas zu drucken. Beispiel:

tmux run-shell "printf "%sn" "$(jobs -l)""

Wenn Sie es in einer Shell ausf√ľhren, deren Jobs Sie wissen m√∂chten, doppelte Anf√ľhrungszeichen $() (es ist doppelt zitiert) wird also um diese Shell erweitert jobs wird zur√ľckgeben, was Sie wollen. Endlich printf wird laufen in Ein weiterer Shell, die die Ausgabe von bekommt jobs als Zeichenfolge (so Dies trifft nicht zu).

Aber vorher printf l√§uft, tmux interpretiert die Zeichenkette und die innere H√ľlle interpretiert die Zeichenkette. Ob jobs gibt alles aus, um das erweitert werden kann tmux run-shell (z.B. #{pane_id}) dann wird es erweitert. Wenn es einfache Anf√ľhrungszeichen ausgibt, wird unser einfaches Anf√ľhrungszeichen vorzeitig geschlossen. Syntaxfehler k√∂nnen auftreten, aber es ist nicht das Schlimmste, was passieren kann. Code-Injection kann passieren jobs kann helfen, aber es ist nicht einfach, dies richtig zu machen.

Um es zu automatisieren, m√ľssen Sie den Befehl in eine Shell einf√ľgen (in der Praxis: viele Shells). Wie wir gesehen haben, ist das Injizieren durch Senden von Schl√ľsseln m√ľhsam. Es geht auch anders.


Muschelfalle (nicht wirklich n√ľtzlich)

Wenn Sie diese Funktion in jeder in tmux geöffneten Shell definiert haben:

_tmux_show_jobs () { tmux run-shell -t "$TMUX_PANE" "printf "%sn" "$(jobs -l)""}

und dann in jeder schale trap ein Signal, damit es die Funktion ausl√∂st, und tmux dann √ľber die verf√ľgbaren Fenster iteriert und Signale an sendet #{pane_pid} - Dann k√∂nnen Sie jede Shell die Ausgabe von √ľbergeben lassen jobs -l zu tmux, um in seinem Bereich angezeigt zu werden. Jedoch:

  • Es kann immer noch zu unerw√ľnschtem Parsen und Ersetzen kommen. Sie k√∂nnen es beheben, indem Sie umleiten jobs -l in eine tempor√§re Datei (f√ľr jede Shell getrennt) und catdie Datei hinein tmux run-shell.
  • Unabh√§ngig davon, f√ľr welches Signal Sie sich entscheiden, m√∂chten Sie es nicht unn√∂tigerweise an jeden Bereich senden. Es ist m√∂glich, einen Bereich zu erstellen, in dem alles ausgef√ľhrt wird (ich meine nicht unbedingt eine Shell). Es ist m√∂glich zu exec zu etwas aus einer Muschel. Beliebige Tools reagieren auf Signale auf ihre eigene Weise, und Sie k√∂nnen nicht davon ausgehen, dass jedes Signal sicher ist. Bestimmtes SIGUSR1 und SIGUSR2 Beenden Sie den Vorgang standardm√§√üig. Andere Signale sind aussagekr√§ftig und k√∂nnen die Funktion ausl√∂sen, wenn Sie sie nicht m√∂chten.
  • Auch wenn Sie es schaffen, tmux dazu zu bringen, Signale an zu sendenMuscheln nur und fangen das gew√§hlte Signal in jeder einzelnen Muschel ein. In vielen F√§llen reagieren Muscheln nicht sofort auf Signale.

Ohne jobs (endlich n√ľtzlich)

Wir können die Tatsache ausnutzen, dass Sie es nicht wirklich wissen wollen alle Jobs oder Hintergrundaufgaben. Sie möchten Aufgaben finden, die sind gestoppt. Diese können von außen abgefragt werden. Betrachten Sie diesen Basiscode:

#!/bin/sh

unset IFS
for p in $(
tmux list-panes -F "#{pane_id}"
)
do
tmux run-shell -t "$p" "ps -o s,pid,args -g #{pane_pid} | sed -e "/^T/!d" -e "s/. //""
done

Anmerkungen:

  • for p in $( ‚Ķ ); do ‚Ķ ist im Allgemeinen falsch aber hier ist das Format gut definiert, die Syntax wird mit der Standardeinstellung funktionieren IFS. Wenn Sie den Code au√üerdem in tmux ausf√ľhren, wird mindestens ein Fenster angezeigt $() erzeugt niemals genau null W√∂rter (was zu einem Syntaxfehler f√ľhren w√ľrde).
  • Anstatt -g #{pane_pid} es k√∂nnte sein --ppid #{pane_pid} aber
    • es ist nicht POSIX;
    • -g Umfasst Enkelkinder, wenn Sie also laufen (nicht exec) eine Muschel aus der urspr√ľnglichen Muschel oder sudo su -F√ľhren Sie einen anderen Prozess aus, und beenden Sie ihn. Der Code findet ihn weiterhin. Ich denke es ist besser.
  • list-panes Standardm√§√üig werden alle Bereiche im aktuellen Fenster aufgelistet. Wenn Sie in der aktuellen Sitzung alle Bereiche durchlaufen m√∂chten, verwenden Sie list-panes -s.

Es gibt jedoch einen Nachteil. Das Ergebnis (falls nicht leer) f√ľr jeden Bereich wird im Kopiermodus im Bereich angezeigt. Befindet sich der Bereich jedoch bereits in einem anderen als dem Standardmodus, wird das Ergebnis m√∂glicherweise nie angezeigt oder an die angezeigten Elemente angeh√§ngt. Insbesondere wenn die Ergebnisse sichtbar sind und Sie den Code zum zweiten Mal ausf√ľhren, werden doppelte Zeilen angezeigt.

Die einzige Möglichkeit, die ich gefunden habe, um sicherzustellen, ist das FensterWenn das Kontrollkästchen vor dem Drucken des Ergebnisses deaktiviert wird und das Ergebnis immer angezeigt wird, wird der nicht standardmäßige Modus, in dem sich das Fenster befindet, beendet. Der folgende Code erledigt dies. Es ändert absichtlich nicht den Modus, wenn das Ergebnis leer ist.

#!/bin/sh

unset IFS
tmux list-panes -F "#{pane_id} #{pane_pid}" | while
read -r id pid
do
output="$(ps -o s,pid,args -g "$pid" | sed -e "/^T/!d" -e "s/. //")"
[ "$output" ] && {
[ "$(tmux display-message -p -t "$id" "#{pane_in_mode}")" -eq 1 ] && tmux send-keys -t "$id" q
tmux run-shell -t "$id" "printf "Stopped processes:n n%sn" "$output""
}
done
exit 0

Ich habe es gespeichert als _tmux-find-stopped in einem Verzeichnis, in dem meine $PATH verweist auf. Ich habe diese Zeile zu meiner hinzugef√ľgt ~/.tmux.conf:

bind -T prefix j run-shell "_tmux-find-stopped"

Nachdem ich Präfix:source-file ~/.tmux.confEingebenIch kann gestoppte Prozesse mit finden Präfixj. Neue tmux-Server geben die Datei standardmäßig als Quelle aus.