Jak mogę wyświetlić całe drzewo procesów odrodzone przez dany proces jako drzewo i tylko to drzewo, tzn. Żadnych innych procesów?
Wynik może np. Wyglądać
4378 ? Ss 0:10 SCREEN
4897 pts/16 Ss 0:00 \_ -/bin/bash
25667 pts/16 S+ 0:00 | \_ git diff
25669 pts/16 S+ 0:00 | \_ less -FRSX
11118 pts/32 Ss+ 0:00 \_ -/bin/bash
11123 pts/32 S+ 0:00 \_ vi
Nie mogłem uzyskać pożądanego rezultatu wyłącznie z parametrami do ps
.
Poniższe wyniki dają pożądany rezultat, ale wydają się być trochę zaangażowane:
#!/bin/bash
pidtree() {
echo -n $1 " "
for _child in $(ps -o pid --no-headers --ppid $1); do
echo -n $_child `pidtree $_child` " "
done
}
ps f `pidtree 4378`
Czy ktoś ma łatwiejsze rozwiązanie?
ps auxf
.Odpowiedzi:
To
pstree
bardzo dobre rozwiązanie, ale jest trochę powściągliwe. Używamps --forest
zamiast tego. Ale nie dla aPID
(-p
), ponieważ drukuje tylko określony proces, ale dla session (-g
). Może wydrukować dowolną informację, którąps
można wydrukować w fantazyjnym drzewie graficznym ASCII określającym-o
opcję.Więc moja sugestia dotycząca tego problemu:
Jeśli proces nie jest liderem sesji, należy zastosować nieco więcej sztuczki:
Najpierw pobiera identyfikator sesji (SID) bieżącego procesu, a następnie ponownie wywołuje ps z tym identyfikatorem sid.
Jeśli nagłówki kolumn nie są potrzebne, dodaj „=” po każdej definicji kolumny w opcjach „-o”, takich jak:
Przykładowy przebieg i wynik:
Niestety to nie działa,
screen
ponieważ ustawia sid dla każdego ekranu potomnego i wszystkich bashów wnuka.Aby wszystkie procesy zostały odrodzone przez proces, należy zbudować całe drzewo. Użyłem do tego awk . Najpierw buduje tablicę skrótów, która zawiera wszystko
PID => ,child,child...
. Na koniec wywołuje funkcję rekurencyjną, aby wyodrębnić wszystkie procesy potomne danego procesu. Wynik jest przekazywany do innego wps
celu sformatowania wyniku. Rzeczywisty PID musi być zapisany jako argument do awk zamiast<PID>
:W przypadku procesu SCREEN (pid = 8041) przykładowe dane wyjściowe wyglądają następująco:
źródło
ps
miałoby opcję flagi filtrowania, aby filtrować do wszystkich potomków PID.gdzie
${pid}
jest pid procesu nadrzędnego.W Gentoo Linux
pstree
znajduje się w pakiecie „psmisc”, najwyraźniej znajdującym się pod adresemhttp://psmisc.sourceforge.net/źródło
pstree
, ale przegapiłem bardziej szczegółowy format wyjściowy. Jednakpstree -p <pid>
przynajmniej wydrukuj stawki, które są dość blisko.sed
wszystko ... mmm to działa :)pstree -pn 4008 |grep -o "([[:digit:]]*)" |grep -o "[[:digit:]]*"
Oto moja wersja, która działa natychmiast (ponieważ jest
ps
wykonywana tylko raz). Działa w bash i zsh.źródło
echo $1
do pierwszej pętli for i zmieniając ją naecho $i
.Stworzyłem mały skrypt bash, aby utworzyć listę pid procesów potomnych rodzica. Rekurencyjnie, aż znajdzie ostatni proces potomny, który nie ma żadnych potomków. Nie daje widoku drzewa. Po prostu wyświetla wszystkie pid.
pierwszym argumentem list_offspring jest pid nadrzędny
źródło
ps -H -g "$pid" -o comm
nie dodaje drzewa jako takiego, to tylko lista procesów.
daje na przykład
źródło
-H
Opcja służy do wyświetlania drzewa procesu lub „proces hierarchii (las)”Pracowałem nad rozwiązaniem tego samego problemu. Zasadniczo ps manpage nie dokumentuje żadnej opcji pozwalającej robić to, co chcemy za pomocą jednego polecenia. Wniosek: potrzebny jest skrypt.
Wymyśliłem skrypt bardzo podobny do twojego. Wkleiłem go w moim ~ / .bashrc, dzięki czemu mogę go używać z dowolnej powłoki.
źródło
Po drodze w wierszu polecenia:
generuje:
bardziej eleganckim sposobem jest zdefiniowanie funkcji w
.bashrc
:następnie w wierszu poleceń:
źródło
Daje to tylko pid + pid + pid dla każdego na jednej linii, co jest przydatne do dalszego przetwarzania.
źródło
Zrobiłem podobny skrypt na podstawie powyższego Philippe'a
Powoduje to wyświetlenie wszystkich pid podrzędnych, wnuków itp. W formacie rozdzielanym spacjami. To z kolei może być karmione ps, jak w
źródło
dla całego procesu - pstree -a pokaż według użytkownika - pstree user
źródło