Kontext:
Benutzer stellen mir ihre benutzerdefinierten Skripts zur Verfügung. Diese Skripts können wie Skripts zum Starten mehrerer GUI-Programme, Back-End-Dienste, verwendet werden. Ich habe keine Kontrolle darüber, wie die Skripte geschrieben werden. Diese Skripts können blockierend sein, d. H. Die Ausführung wartet, bis alle untergeordneten Prozesse (Programme, die nacheinander ausgeführt werden) den Befehl
beenden %Vor%oder nicht blockierender Typ, d. h. solche, die child im Hintergrund abzweigen und etwas wie
verlassen %Vor%Was versuche ich zu erreichen?
Vom Benutzer bereitgestellte Skripts können einen der beiden oben genannten Typen oder eine Kombination aus beidem aufweisen. Meine Aufgabe besteht darin, das Skript auszuführen und zu warten, bis alle von ihm gestarteten Prozesse beendet sind und der Knoten anschließend beendet wird. Wenn es vom Blockiertyp ist, ist der Fall einfach, d. H. Er erhält die PID des Skriptausführungsprozesses und wartet, bis ps -ef | grep -ef PID keine weiteren Einträge mehr hat. Nicht-blockierende Skripts sind diejenigen, die mir Probleme bereiten.
Gibt es eine Möglichkeit, eine Liste von PIDs aller untergeordneten Prozesse zu erhalten, die durch die Ausführung eines Skripts erzeugt werden? Alle Hinweise oder Hinweise werden sehr geschätzt
Sie können wait
verwenden, um auf alle von userscript
gestarteten Hintergrundprozesse zu warten. Da wait
nur für untergeordnete Elemente der aktuellen Shell funktioniert, müssen Sie ihr Skript als Quelle verwenden, anstatt sie als separaten Prozess auszuführen.
Die Beschaffung des Skripts in einer expliziten Subshell sollte das Starten eines neuen Prozesses genau genug simulieren. Wenn nicht, können Sie auch die Subshell im Hintergrund anzeigen, die das Starten eines neuen Prozesses erzwingt, und dann warten, bis es abgeschlossen ist.
%Vor% ps --ppid $PID
listet alle untergeordneten Prozesse des Prozesses mit $PID
auf.
Sie können einen Dateideskriptor öffnen, der von anderen Prozessen geerbt wird, und dann warten, bis er nicht mehr verwendet wird. Dies ist eine Low-Overhead-Methode, die normalerweise gut funktioniert, obwohl es für Prozesse möglich ist, sie zu umgehen, wenn sie möchten:
%Vor% Sie können alle aufgerufenen Prozesse mit ptrace verfolgen, z. B. mit strace
. Dies ist einfacher, hat jedoch einige damit verbundene Gemeinkosten und funktioniert möglicherweise nicht, wenn Skripts suid-Binärdateien aufrufen:
Sie können pgrep -P <parent_pid>
verwenden, um eine Liste der untergeordneten Prozesse zu erhalten. Beispiel:
Und um die Enkelkinder zu bekommen, machen Sie einfach die gleiche Prozedur für jeden Kindprozess.
Schau dir mein Blog an Bash funktioniert, um Signale aufzulisten und zu töten oder zu senden, um Bäume zu verarbeiten .
Sie können eine dieser Funktionen verwenden, um alle in einem Prozess erzeugten Prozesse ordnungsgemäß aufzulisten. Jeder hat seine eigene Methode oder Reihenfolge zum Senden von Signalen zu verarbeiten.
Die einzige Einschränkung ist, dass der Prozess immer noch verbunden und nicht verwaist sein muss. Wenn Sie einen Weg finden könnten, Ihre Prozesse zu gruppieren , dann könnte das Ihre Lösung sein.
Einfach die Frage beantworten, die gestellt wurde. Sie können die Prozess-ID jedes Skripts, das Sie aufrufen, in derselben Variablen speichern:
%Vor%$ child_process_ids wäre nur eine durch Leerzeichen getrennte Zeichenfolge von Prozess-IDs. Nun, dies beantwortet die gestellte Frage, aber was ich tun würde, wäre ein bisschen anders. Ich würde jedes Skript aus einer for-Schleife aufrufen, seine Prozess-ID speichern und dann auf jede einzelne in einer Schleife warten, um sie zu beenden und jeden Beendigungscode einzeln zu prüfen. Mit dem gleichen Beispiel, hier ist, wie es aussehen würde.
%Vor%