Chciałbym uzyskać listę wszystkich procesów, które zstępują (np. Dzieci, wnuki itp.) $pid
. Oto najprostszy sposób, jaki wymyśliłem:
pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"
Czy istnieje jakieś polecenie lub prostszy sposób na uzyskanie pełnej listy wszystkich procesów potomnych?
'\n'
rozdzielanie czy' '
rozdzielanie). Praktycznym przykładem użycia jest: a) skrypt demonizatora, który napisałem z czystego masochizmu (konkretnie, funkcja „stop” ma do czynienia z dowolnym drzewem procesów, które pojawił się proces demonizowany); oraz b) skrypt przekroczenia limitu czasu, który zabije wszystko, co udało się stworzyć proces przekroczenia limitu czasu.kill
. Zobacz unix.stackexchange.com/questions/9480/… , unix.stackexchange.com/questions/50555/...ps ax -opid,ppid,pgrp,cmd
Widzę, że istnieje wiele procesów, które współużytkują dokładnie to samopgrp
poddrzewo, które chcę zabić. (Dodatkowo nie widzęsetpgrp
programu nigdzie wymienionego w pakietach stabilnych Debiana: packages.debian.org/… )Odpowiedzi:
Poniższe jest nieco prostsze i ma tę dodatkową zaletę, że ignoruje liczby w nazwach poleceń:
Lub z Perlem:
Szukamy liczb w nawiasach, aby na przykład nie podawać 2 jako procesu potomnego, gdy natkniemy się na
gif2png(3012)
. Ale jeśli nazwa polecenia zawiera liczbę w nawiasach, wszystkie zakłady są wyłączone. Tylko do tej pory przetwarzanie tekstu może Cię zabrać.Myślę też, że grupy procesowe są do zrobienia. Jeśli chcesz uruchomić proces we własnej grupie procesów, możesz użyć narzędzia „pgrphack” z pakietu Debian „daemontools”:
Lub możesz ponownie zwrócić się do Perla:
Jedynym zastrzeżeniem jest to, że grupy procesów nie zagnieżdżają się, więc jeśli jakiś proces tworzy własne grupy procesów, jego podprocesy nie będą już w grupie, którą utworzyłeś.
źródło
pstree -lp | grep -Po "(?<=\()\d+(?=\))"
źródło
bash
,zsh
,fish
, a nawetksh 99
), ale może nie działać na starszych muszli, na przykładksh 88
Najkrótsza wersja, którą znalazłem, która również poprawnie obsługuje polecenia takie jak
pop3d
:Zajmuje błędnie jeśli masz polecenia, które mają dziwne nazwy, jak:
my(23)prog
.źródło
ffmpeg
używaniem wątków. Choć od szybkich uwag, wydaje się, że wątki są podane wraz z nazwą wewnątrz nawiasów klamrowych,{ }
.Istnieje również kwestia poprawności. Naiwne analizowanie wyników
pstree
jest problematyczne z kilku powodów:Jeśli masz
psutil
zainstalowany Python i pakiet, możesz użyć tego fragmentu kodu, aby wyświetlić listę wszystkich procesów potomnych:(Pakiet psutil jest np. Instalowany jako zależność
tracer
polecenia dostępnego na Fedorze / CentOS.)Alternatywnie możesz wykonać pierwsze przejście drzewa przetwarzania w powłoce Bourne'a:
W celu obliczenia przechodniego zamknięcia pid część ogonową można pominąć.
Zauważ, że powyższe nie używa rekurencji i działa również w ksh-88.
W systemie Linux można wyeliminować
pgrep
połączenie i zamiast tego odczytać informacje z/proc
:Jest to bardziej wydajne, ponieważ zapisujemy jeden fork / exec dla każdego PID i
pgrep
wykonujemy dodatkową pracę w każdym wywołaniu.źródło
Ta wersja systemu Linux wymaga tylko / proc i ps. Jest to adaptacja ostatniego fragmentu doskonałej odpowiedzi @ maxschlepzig . Ta wersja czyta / proc bezpośrednio z powłoki zamiast odradzania podprocesu w pętli. Jest to nieco szybsze i prawdopodobnie nieco bardziej eleganckie, jak wymaga tego tytuł wątku.
źródło
W każdym z dwóch (pozornie bardzo sztucznych) przypadków użycia, dlaczego chcesz zabić podprocesy jakiegoś niefortunnego procesu? Skąd wiesz lepiej niż proces, kiedy jego dzieci powinny żyć lub umrzeć? Wydaje mi się to złym projektem; proces powinien po sobie posprzątać.
Jeśli naprawdę wiesz lepiej, powinieneś rozwidlać te podprocesy, a „proces demonizowany” jest najwyraźniej zbyt głupi, aby można było mu zaufać
fork(2)
.Powinieneś unikać prowadzenia list procesów potomnych lub przeszukiwania drzewa procesów, np. Umieszczając procesy potomne w osobnej grupie procesów, jak sugeruje @Gilles.
W każdym razie podejrzewam, że lepiej byłoby, gdyby twój demonizowany proces stworzył pulę wątków roboczych (która z konieczności umiera wraz z zawartym w niej procesem) niż głębokie drzewo pod-podprocesów, które coś gdzieś musi następnie wyczyścić .
źródło
Oto skrypt otoki pgrep, który pozwala używać pgrep i uzyskiwać wszystkich potomków jednocześnie.
~/bin/pgrep_wrapper
:Wywołaj w taki sam sposób, jak przy normalnym pgrep, na przykład w
pgrep_recursive -U $USER java
celu znalezienia wszystkich procesów Java i podprocesów od bieżącego użytkownika.źródło
IFS
i użyciem tablic ("${array[*]}
").