Frage

ich ein Bash-Skript, das eine parallele Verarbeitung in einer Schleife der Fall ist. Ich will nicht der parallele Prozess die CPU Spike, so dass ich einen Schlafbefehl verwenden. Hier ist eine vereinfachte Version.

(while true;do sleep 99999;done)&

So führen Sie ich die obige Zeile aus einer Bash-Eingabeaufforderung und bekommen so etwas wie: [1] 12345

Wo [1] ist die Auftragsnummer und 12345 die Prozess-ID (pid) der while-Schleife. Ich mache eine kill 12345 und bekommen:

[1]+  Terminated              ( while true; do
    sleep 99999;
done )

Es sieht aus wie das gesamte Skript beendet wurde. Ich mache jedoch ein ps aux|grep sleep und finden Sie den Schlafbefehl ist immer noch stark, aber mit seinem eigenen pid! Ich kann die sleep töten und alles scheint in Ordnung. Allerdings, wenn ich den Schlaf zuerst zu töten war, beginnt die while-Schleife einen neue sleep pid. Dies ist so eine Überraschung für mich, da der Schlaf ist mit der while-Schleife nicht parallel ist. Die Schleife selbst ist ein einziger Pfad der Ausführung.

Also ich habe zwei Fragen:

  1. Warum hat der Schlafbefehl seinen eigenen Prozess-ID bekommen?
  2. Wie leicht töten ich die while-Schleife und den Schlaf?
War es hilfreich?

Lösung

  1. Schlaf bekommt seine eigene PID, weil es ein Prozess läuft und wartet nur darauf. Versuchen Sie which sleep zu sehen, wo es ist.
  2. Sie können ps -uf verwenden Sie den Prozessbaum auf Ihrem System zu sehen. Von dort können Sie, was die PPID (übergeordnete PID) der Schale bestimmen (die die Schleife ausgeführt wird) des Schlafes ist.

Andere Tipps

Haben Sie versucht zu tun kill %1, wo 1 ist die Zahl, die Sie erhalten, nachdem Sie den Befehl im Hintergrund starten?

ich habe es gerade jetzt nach (while true;do sleep 99999;done)& einleiten, und es richtig beendet.

"ps --ppid" wählt alle Prozesse mit dem angegebenen übergeordneten pid, zum Beispiel:

$ (while true;do sleep 99999;done)&
[1] 12345

$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)

Sie können die Prozessgruppe töten.

Um die Prozessgruppe des Prozesses Lauf zu finden:

ps --no-headers -o "%r" -p 15864

töten dann die Prozessgruppe mit:

kill -- -[PGID]

Sie können es tun alles in einem Befehl. Lassen Sie uns versuchen Sie es aus:

$ (while true;do sleep 99999;done)&
[1] 16151

$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+  Terminated              ( while true; do
    sleep 99999;
done )
  1. Da "Schlaf" ist ein Prozess, kein Build-in-Funktion oder ähnlich

  2. Sie können die folgenden Aktionen ausführen:

    (while true;do sleep 99999;done)&
    whilepid=$!
    kill -- -$whilepid
    

Der obige Code tötet die Prozeßgruppe, weil die PID als negative Zahl angegeben wird (zum Beispiel -123 anstelle von 123). Darüber hinaus nutzt sie die Variable $!, die speichert die PID des zuletzt ausgeführten Prozess.

Hinweis: Wenn Sie jeden Prozess im Hintergrund auf der interaktiven Modus auszuführen (das heißt die Befehlszeile verwendet wird) erstellt es eine neue Prozessgruppe, die ist, was mit Ihnen geschieht. Auf diese Weise ist es relativ einfach zu „Kill‚em all“, weil Sie nur die gesamte Prozessgruppe zu töten. Wenn jedoch das gleiche in einem Skript fertig ist, spielt es keine neue Gruppe zu erstellen, da alle neuen Prozesse, um das Skript PID gehören, auch wenn sie im Hintergrund ausgeführt wird (Jobs Steuerung ist standardmäßig deaktiviert). So aktivieren Sie Jobs in einem Skript zu steuern, müssen Sie nur die folgende am Anfang des Skripts setzen:

#!/bin/bash

set -m

Um die while Schleife zu töten und die sleep $! mit Ihnen auch ein trap Signal-Handler innerhalb des Sub-Shell verwenden können.

(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top