Ich möchte eine Liste aller Prozesse erhalten, von denen ich abstamme (z. B. Kinder, Enkelkinder usw.) $pid
. Dies ist der einfachste Weg, den ich mir ausgedacht habe:
pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"
Gibt es einen Befehl oder eine einfachere Möglichkeit, die vollständige Liste aller untergeordneten Prozesse abzurufen?
'\n'
, ob es' '
abgegrenzt oder abgegrenzt ist). Ein praktischer Anwendungsfall ist: a) ein Daemonizer-Skript, das ich aus reinem Masochismus geschrieben habe (insbesondere muss die "Stop" -Funktionalität sich mit jedem Prozessbaum befassen, den der daemonisierte Prozess hervorgebracht hat); und b) ein Zeitüberschreitungsskript, das alle durch die Zeitüberschreitung verursachten Vorgänge beendet.kill
. Siehe unix.stackexchange.com/questions/9480/... , unix.stackexchange.com/questions/50555/...ps ax -opid,ppid,pgrp,cmd
Ich sehe, dass es viele Prozesse gibt, die den gleichenpgrp
Teilbaum haben, den ich töten möchte. (Außerdem kann ich dassetpgrp
Programm nirgends in den stabilenAntworten:
Das Folgende ist etwas einfacher und hat den zusätzlichen Vorteil, dass Zahlen in den Befehlsnamen ignoriert werden:
Oder mit Perl:
Wir suchen nach Zahlen in Klammern, damit wir beispielsweise keine 2 als untergeordneten Prozess angeben, wenn wir darauf stoßen
gif2png(3012)
. Wenn der Befehlsname jedoch eine Zahl in Klammern enthält, sind alle Wetten deaktiviert. Es gibt nur so weit Textverarbeitung können Sie.Daher denke ich auch, dass Prozessgruppen der richtige Weg sind. Wenn Sie möchten, dass ein Prozess in einer eigenen Prozessgruppe ausgeführt wird, können Sie das Tool 'pgrphack' aus dem Debian-Paket 'daemontools' verwenden:
Oder Sie könnten sich wieder an Perl wenden:
Die einzige Einschränkung besteht darin, dass Prozessgruppen nicht verschachtelt werden. Wenn also ein Prozess seine eigenen Prozessgruppen erstellt, befinden sich seine Unterprozesse nicht mehr in der von Ihnen erstellten Gruppe.
quelle
pstree -lp | grep -Po "(?<=\()\d+(?=\))"
quelle
bash
,zsh
,fish
, und sogarksh 99
), aber möglicherweise nicht auf älteren Muscheln, zBksh 88
Die kürzeste Version, die ich gefunden habe, befasst sich auch korrekt mit Befehlen wie
pop3d
:Es befasst sich falsch , wenn Sie Befehle haben , die seltsame Namen haben wie:
my(23)prog
.quelle
ffmpeg
Verwendung von Threads. Aus kurzen Beobachtungen geht hervor, dass die Fäden mit ihrem Namen in geschweiften Klammern angegeben sind{ }
.Es gibt auch die Frage der Richtigkeit. Das einfache Parsen der Ausgabe von
pstree
ist aus mehreren Gründen problematisch:Wenn Sie Python und das
psutil
Paket installiert haben, können Sie dieses Snippet verwenden, um alle nachfolgenden Prozesse aufzulisten:(Das psutil-Paket wird zB als eine Abhängigkeit des
tracer
Befehls installiert, der auf Fedora / CentOS verfügbar ist.)Alternativ können Sie den Prozessbaum in einer Bourneshell im ersten Schritt durchlaufen:
Zur Berechnung des Transitiv-Verschlusses einer PID kann der Endteil weggelassen werden.
Beachten Sie, dass der obige Befehl keine Rekursion verwendet und auch in ksh-88 ausgeführt wird.
Unter Linux kann man den
pgrep
Aufruf unterdrücken und stattdessen die Informationen lesen von/proc
:Dies ist effizienter, da für jede PID ein Fork / Exec gespeichert wird und
pgrep
bei jedem Aufruf zusätzliche Arbeit geleistet wird.quelle
Diese Linux-Version benötigt nur / proc und ps. Es ist aus dem letzten Stück von @ maxschlepzigs exzellenter Antwort angepasst . Diese Version liest / proc direkt aus der Shell, anstatt einen Unterprozess in einer Schleife zu erzeugen. Es ist ein bisschen schneller und wohl etwas eleganter, als der Titel dieses Threads verlangt.
quelle
Warum möchten Sie in jedem Ihrer beiden (scheinbar sehr künstlichen) Anwendungsfälle die Unterprozesse eines unglücklichen Prozesses beenden? Woher weißt du besser als ein Prozess, wann seine Kinder leben oder sterben sollten? Dies scheint mir ein schlechtes Design zu sein. Ein Prozess sollte nach sich selbst bereinigen.
Wenn Sie es wirklich besser wissen, sollten Sie diese Unterprozesse forken, und der "daemonisierte Prozess" ist anscheinend zu dumm, um ihm zu vertrauen
fork(2)
.Sie sollten vermeiden, Listen von untergeordneten Prozessen zu führen oder den Prozessbaum zu durchsuchen, z. B. indem Sie die untergeordneten Prozesse in eine separate Prozessgruppe einteilen, wie von @Gilles vorgeschlagen.
Ich vermute auf jeden Fall, dass Ihr daemonisierter Prozess besser dazu geeignet ist, einen Worker-Thread-Pool zu erstellen (der notwendigerweise zusammen mit dem enthaltenen Prozess abstirbt) als einen tiefen Baum von Sub-Sub-Sub-Prozessen, die irgendwo aufgeräumt werden müssen .
quelle
Hier ist ein pgrep-Wrapper-Skript, mit dem Sie pgrep verwenden und alle Nachkommen gleichzeitig abrufen können.
~/bin/pgrep_wrapper
:Rufen Sie auf die gleiche Weise auf, wie Sie normale pgrep aufrufen würden
pgrep_recursive -U $USER java
, um beispielsweise alle Java-Prozesse und -Unterprozesse des aktuellen Benutzers zu finden.quelle
IFS
und Verwenden von Arrays ("${array[*]}
") ersetzt werden könnte.