it-swarm.com.de

Wie bekomme ich die Job ID?

Wie wir wissen, ermöglicht die Shell dem Benutzer, Hintergrundprozesse mit & Am Ende der Befehlszeile auszuführen. Jeder Hintergrundprozess wird durch eine Job-ID und natürlich durch seine PID identifiziert.

Wenn ich einen neuen Job ausführe, ist die Ausgabe ungefähr [1] 1234 (Die zweite Nummer ist die Prozess-ID). Der Versuch, Befehle wie stop 1 Und stop %1 Aufzurufen, führt zu einer Fehlermeldung: stop: Unknown job: 1

Als ich verstand, dass der Befehl stop dazu führt, dass ein Job angehalten wird, habe ich mich gefragt wie man die Job-ID erhält und es richtig macht. Wenn die einzige Möglichkeit, einen Job zu beenden, die Prozess-ID ist, was ist der Zweck der Job-ID?

14
Reflection

Nachdem ein Prozess mit & In den Hintergrund gesendet wurde, kann seine PID aus der Variablen $! Abgerufen werden. Die Job-IDs können mit dem Befehl jobs angezeigt werden. Der Schalter -l Zeigt auch die PID an.

 $ sleep 42 &
 [1] 5260
 $ echo $!
 5260
 $ jobs -l
 [1]  - 5260 running    sleep 42

Einige kill-Implementierungen ermöglichen das Beenden nach Job-ID anstelle von PID. Eine sinnvollere Verwendung der Job-ID besteht jedoch darin, einen bestimmten Prozess selektiv in den Vordergrund zu stellen. Wenn Sie fünf Prozesse im Hintergrund starten und den dritten in den Vordergrund stellen möchten, können Sie den Befehl jobs ausführen, um zu sehen, welche Prozesse Sie gestartet haben, und dann fg %3, Um den mit der Job-ID drei in den Vordergrund zu stellen .

24
Marco

Job Control ist eine Funktion, die BSD-Systemen in den frühen 80er Jahren hinzugefügt wurde. csh Da es sich um die BSD-Shell handelt, ist es nicht verwunderlich, dass die Funktion zuerst in dieser Shell eingeführt wurde. Sie mussten einige Jahre warten, bevor die Jobkontrolle zu Nicht-BSD-Unices und anderen Shells hinzugefügt wurde (beginnend mit der Korn-Shell).

Es sollte beachtet werden, dass die Jobsteuerung nicht die Fähigkeit ist, einen Prozess asynchron zu starten (dh die Shell wartet nicht auf ihre Beendigung, bevor sie die nächste Eingabeaufforderung ausgibt; die Bourne Shell hatte von Anfang an &, Hat dies aber nicht getan). Unterstützung der Jobkontrolle bis 10 Jahre später), aber über die Fähigkeit, mit mehreren Aufgaben vom selben Terminal aus zu interagieren.

Wir sprechen von Jobs, nicht von Prozessen. Zur Implementierung der Jobsteuerung wurden Prozessgruppen eingeführt. Ein Job ist eine Prozessgruppe (Job aus Sicht des Benutzers, Prozessgruppe aus Sicht des Betriebssystems).

In der Regel handelt es sich um interaktive Shells, mit denen Prozessgruppen erstellt und verwaltet werden. Auch hier dreht sich alles um die Interaktion mit dem Terminal.

Wenn Sie einen Befehl ausführen, werden alle Prozesse und ihre Nachkommen in einer neuen Prozessgruppe abgelegt.

In einer Sitzung auf einem bestimmten Terminal wird einer Prozessgruppe ein privilegierter Zugriff auf das Terminal gewährt. Das ist die Vordergrundprozessgruppe des Terminals. Diese Prozessgruppe ist diejenige, deren Mitglieder beim Drücken ein SIGINT/SIGTSTP/SIGQUIT erhalten CTRL-{C,Z,\}. Prozesse in anderen Prozessgruppen werden angehalten, wenn sie versuchen, vom Terminal zu lesen (und manchmal darauf zu schreiben). usw.

Wenn Sie einen Job im Vordergrund starten, macht die interaktive Shell ihre Prozessgruppe zur Vordergrundprozessgruppe des Terminals und nicht zu den im Hintergrund gestarteten.

Auf diese Weise kann ein Benutzer mehrere Dinge gleichzeitig in einem Terminal ausführen. Er kann eine Liste von Jobs haben, bei denen es sich um Gruppen von Prozessen handelt, die im Vordergrund (mit privilegiertem Zugriff auf das Terminal), im Hintergrund, ausgeführt oder angehalten werden können. Der Job kann von/nach Hintergrund/Vordergrund verschoben und angehalten/ausgeführt werden.

Heutzutage unterstützen alle Systeme und alle Shells die Jobsteuerung (obwohl Sie in der Bourne Shell explizit mit set -m IIRC danach fragen müssen).

Alle an der Eingabeaufforderung gestarteten Befehle erhalten eine Auftragsnummer. Aus Systemsicht werden diese Prozessgruppen-IDs zugeordnet.

 $ ps -fj | cat
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
chazelas  8237  7315  8237  8237  0 15:54 pts/7    00:00:00 /bin/zsh
chazelas 10720  8237 10720  8237  0 21:25 pts/7    00:00:00 ps -fj
chazelas 10721  8237 10720  8237  0 21:25 pts/7    00:00:00 cat

Oben habe ich diesen ps -j | cat - Job im Vordergrund gestartet. Es wurde die Prozessgruppe 10720 zugewiesen (die zufällig auch die Prozess-ID von ps ist). Wenn Sie die Vordergrund-Prozessgruppen-ID des Terminals zu dem Zeitpunkt abgefragt hätten, an dem sie ausgeführt wurden (mit tcgetpgrp()), hätten Sie 10720 erhalten.

$ (sleep 100;:) | sleep 101 &
[1] 10787 10789
$ ps -fj
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
chazelas  8237  7315  8237  8237  0 15:54 pts/7    00:00:00 /bin/zsh
chazelas 10787  8237 10787  8237  0 21:33 pts/7    00:00:00 /bin/zsh
chazelas 10788 10787 10787  8237  0 21:33 pts/7    00:00:00 sleep 100
chazelas 10789  8237 10787  8237  0 21:33 pts/7    00:00:00 sleep 101
chazelas 10790  8237 10790  8237  0 21:33 pts/7    00:00:00 ps -fj

Dieses Mal habe ich im Hintergrund eine Pipeline gestartet. Die Shell gab mir eine Jobnummer (1) und 2 Prozess-IDs ((t)csh, pdksh und zsh gibt alle Prozess-IDs an, das Verhalten variiert in anderen Shells), eine für eine Unterschale eine für sleep 101. Diese Subshell hat übrigens einen dritten Prozess ausgelöst (sleep 100). Die Shell hat die PID dieser nicht gemeldet, weil sie nichts darüber weiß, aber sie ist immer noch Teil desselben Jobs (Prozessgruppe 10787 oben).

Jetzt haben Sie einige Befehle, um diese Jobs zu bearbeiten: fg, bg, kill, wait und jobs (einige Shells haben auch ein disown und Aliase zu kill, um ein anderes Standardsignal zu senden.

Diese nehmen Job-IDs im Format %n An, wobei n die Jobnummer ist. Es gibt %foo, Um auf den Job zu verweisen, dessen Befehl mit foo beginnt, und mehr (siehe Handbuch Ihrer Shell).

kill %1

sendet das SIGTERM-Signal an alle Prozesse des Jobs 1. kill -s STOP %1, das manchmal auf stop ausgerichtet ist, sendet stattdessen das Signal SIGSTOP.

fg %1

stellt es in den Vordergrund (macht es zur Vordergrundprozessgruppe des Terminals, sendet das SIGCONT-Signal und weist die Shell an, auf seinen Abschluss zu warten).

bg %1

setzt einen gestoppten Hintergrundjob fort (sendet ein SIGCONT).

wait %1

stellt den Job nicht in den Vordergrund, sondern wartet auf seine Fertigstellung (oder bis er angehalten wird).

jobs

listet die aktuellen Jobs auf (jobs -l mit pgids und/oder pids).

%% Und %+ Beziehen sich auf den Job aktuell. Es ist zu beachten, dass der aktuelle Job nicht unbedingt der zuletzt gestartete Job ist. Dies ist der Job, der mit einem + In der Ausgabe von jobs 'markiert ist. Es ist auch der Job, mit dem sich fg oder bg ohne Argument befassen. Es ist der zuletzt angehaltene Job, wenn es angehaltene gibt, oder der zuletzt gestartete, wenn alle ausgeführt werden.

Achten Sie also darauf, dass kill %% Den gerade im Hintergrund gestarteten Job nicht beendet, wenn angehaltene Jobs vorhanden sind. Es ist immer eine gute Idee, jobs auszuführen, um zu sehen, welche Jobs gerade ausgeführt werden, bevor Sie einen beenden.

Es sollte beachtet werden, dass Sie nicht mit Prozess-IDs verwenden sollten, wenn Sie mit Jobs arbeiten.

$! Gibt die Prozess-ID des zuletzt im Hintergrund ausgeführten Befehls zurück. Im Fall einer Pipeline ist dies die PID des Befehls ganz rechts.

$ sleep 100 | sleep 101 & ps -fj; echo "$!"
[1] 11044 11045
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
chazelas  8237  7315  8237  8237  0 15:54 pts/7    00:00:00 /bin/zsh
chazelas 11044  8237 11044  8237  0 22:08 pts/7    00:00:00 sleep 100
chazelas 11045  8237 11044  8237  0 22:08 pts/7    00:00:00 sleep 101
chazelas 11046  8237 11046  8237  0 22:08 pts/7    00:00:00 ps -fj
11045

Über $! ist 11045, aber die Prozessgruppe von Job 1 ist 11044. Wenn ich kill "$1", werde ich nur sleep 101 töten, nicht sleep 100. Wenn ich kill -- "-$!" (Das heißt, alle Prozesse in der Prozessgruppe 11045 beenden), schlägt dies fehl, da es keine solche Prozessgruppe gibt.

Dort möchten Sie kill %1 (Oder kill %sleep Oder möglicherweise kill %%) Verwenden, um diesen Job zu beenden (was einen kill -- -11044 Ausführt).

11

Es sieht so aus, als hätten Sie bei der Eingabe von stop tatsächlich den Befehl ausgeführt, der mit upstart geliefert wird, der nichts mit dem eingebauten csh oder kshstop Befehle, mit denen Sie vertraut sind. Die Fehlermeldung zu einem "Unbekannten Job" gilt also nicht für das, was Sie versucht haben.

ksh implementiert stop als Alias ​​für kill -s STOP, Der die Notation %n Für Jobs oder Prozessgruppen-IDs versteht. Dieser Alias ​​funktioniert auch in anderen Shells, z. B. wenn Ihre Shell bash lautet:

$ alias stop='kill -s STOP'
$ sleep 30&
[3] 9820
$ stop %3
[3]+  Stopped     sleep 30
3
Mark Plotnick