Jak sprawdzić, jak długo proces działa?

242

Chciałbym tego uniknąć, uruchamiając proces z aplikacji do monitorowania.

tshepang
źródło

Odpowiedzi:

311

W systemie Linux z psod procps(-ng)(i większości innych systemów, ponieważ ten jest określony przez POSIX):

ps -o etime= -p "$$" 

Gdzie $$jest PID procesu, który chcesz sprawdzić. Zwróci czas, który upłynął w formacie [[dd-]hh:]mm:ss.

Używanie -o etimemówi, psże chcesz tylko pola czasu, które upłynęły, a =na końcu tego pomija nagłówek (bez, dostajesz linię, która mówi, ELAPSEDa następnie czas w następnej linii; z, otrzymujesz tylko jedną linię z czasem) .

Lub, w nowszych wersjach pakietu narzędzi procps-ng (3.3.0 lub nowszy) w systemie Linux lub FreeBSD 9.0 lub nowszym (i ewentualnie w innych), użyj:

ps -o etimes= -p "$$"

(z dodanym s), aby sformatować czas w sekundach, co jest bardziej przydatne w skryptach.

W systemie Linux psprogram pobiera to /proc/$$/stat, skąd jednym z pól (patrz man proc) jest czas rozpoczęcia procesu. Niestety jest to określony czas w jiffies (dowolny licznik czasu używany w jądrze Linuksa) od momentu uruchomienia systemu. Musisz więc określić czas, w którym system został uruchomiony (z /proc/stat), liczbę jiffies na sekundę w tym systemie, a następnie wykonać obliczenia matematyczne, aby uzyskać upływający czas w przydatnym formacie.

Okazuje się, że znalezienie HZ (absurdów na sekundę) jest absurdalnie skomplikowane. Na podstawie komentarzy w sysinfo.cpakiecie procps można A) dołączyć plik nagłówka jądra i dokonać ponownej kompilacji, jeśli używane jest inne jądro, B) użyć sysconf()funkcji posix , która niestety używa zakodowanej wartości wkompilowanej w bibliotekę C lub C) zapytaj jądro, ale nie ma do tego oficjalnego interfejsu. Tak więc pskod zawiera serię kludges, dzięki którym określa poprawną wartość. Łał.

To wygodne, że psto wszystko dla Ciebie. :)

Jak zauważa użytkownik @ 336_, w systemie Linux (nie jest to przenośny) można użyć statpolecenia, aby sprawdzić daty dostępu, modyfikacji lub zmiany statusu dla katalogu /proc/$$(gdzie znowu $$jest procesem zainteresowania). Wszystkie trzy liczby powinny być takie same, więc

stat -c%X /proc/$$

da ci czas, w którym proces się $$rozpoczął, w sekundach od epoki. To wciąż nie jest dokładnie to, czego chcesz, ponieważ nadal musisz wykonać matematykę, aby odjąć to od bieżącego czasu, aby upłynąć czas - Myślę, że coś takiego date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"działałoby, ale jest to trochę niezręczne. Jedną możliwą zaletą jest to, że jeśli użyjesz danych wyjściowych o długim formacie, takich jak -c%xzamiast -c%X, otrzymasz wyższą rozdzielczość niż liczba całkowita w sekundach. Ale jeśli jest to potrzebne, prawdopodobnie powinieneś zastosować metodę kontroli procesu, ponieważ czas uruchomienia polecenia stat będzie zakłócał dokładność.

mattdm
źródło
1
Cześć! Czy etime=literówka? Mogę znaleźć tylko etimena stronach podręcznika.
Kent Pawar
16
@KentPawar To nie literówka. Puste =pomija nagłówek. Wypróbuj bez lub spróbujps -p $$ -o etime="Silly Header Here"
mattdm
4
ps -p $ (pgrep find) -o etime =
mafrosis
1
Miły. Wolę etimessiebie, ponieważ jest to do odczytu maszynowego
Asfand Qazi
1
@alexmurray To tylko wywołuje, sysconf()a zatem daje ci zakodowaną wartość z biblioteki C, jak wspomniano, prawda?
mattdm
36

Przenośny:

% ps -o stime,time $$
STIME     TIME
Jan30 00:00:06

tzn. powłoka została uruchomiona 30 stycznia i trwała około 6 sekund czasu procesora.

Mogą istnieć bardziej precyzyjne lub dokładniejsze, ale mniej przenośne sposoby uzyskania tych informacji. Sprawdź dokumentację swojego pspolecenia lub procsystemu plików.

Pod Linuksem ta informacja żyje /proc/$pid/stat.

awk '{print "CPU time: " $14+$15; print "start time: " $22}' /proc/$$/stat

Czas procesora jest w jiffies; Nie wiem od razu, jak znaleźć wartość jiffy z powłoki. Czas rozpoczęcia zależy od czasu rozruchu (można znaleźć w /proc/uptime).

Gilles
źródło
3
Znalezienie wartości HZ (czyli jiffies na sekundę) okazuje się absurdalnie skomplikowane! Z komentarzy w sysinfo.cpakiecie procps można: a) dołączyć plik nagłówka jądra (i dokonać ponownej kompilacji, jeśli używane jest inne jądro, b) użyć funkcji posix sysconf (), która niestety używa zakodowanej na stałe wartości wkompilowanej w biblioteka c lub c) zapytaj jądro i nie ma oficjalnego interfejsu do robienia tego. Tak więc kod zawiera serię kludges, dzięki którym określa poprawną wartość. Łał.
mattdm
1
Strona psman stwierdza, że timejest to „skumulowany czas pracy procesora”. Myślę, że to, czego szukał PO, to etime„czas, jaki upłynął od rozpoczęcia procesu”. pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo
1
W końcu nie tak „przenośny”: „ps: stime: nie znaleziono słowa kluczowego” na FreeBSD. etimeJednak przynajmniej obsługuje .
n
18
ps -eo pid,comm,cmd,start,etime | grep -i X

X to nazwa procesu

mezi
źródło
2
powinien prawdopodobnie dodać grep -v grep.
Brian
ps -o pid,comm,cmd,start,etime -p Xspojrzeć na PID X.
codeforester
13

psprzyjmuje -oopcję określenia formatu wyjściowego, a jedną z dostępnych kolumn jest etime. Według strony podręcznika:

etime - czas, jaki upłynął od rozpoczęcia procesu, w postaci [[dd-] hh:] mm: ss.

W ten sposób możesz uruchomić to, aby uzyskać PID i upływ czasu każdego procesu:

$ ps -eo pid,etime

Jeśli chcesz, aby upłynął czas określonego PID (np. 12345), możesz zrobić coś takiego:

$ ps -eo pid,etime | awk '/^12345/ {print $2}'

( Edycja : okazuje się, że dla powyższego polecenia istnieje krótsza składnia; zobacz odpowiedź mattdm )

Michał Mrożek
źródło
5

Nie wiem, dlaczego nie zostało to jeszcze zasugerowane: w systemie Linux możesz mieć stat()katalog / proc / [nnn] dla swojego PID.

To zachowanie zostało wyraźnie zaprojektowane, aby zwrócić czas rozpoczęcia procesu, co może zrobić w wysokiej rozdzielczości, i które jądro może zrobić dokładnie bez hakowania jiffies, ponieważ jądro może (oczywiście) po prostu sprawdzić odpowiednie informacje. Pola dostępu, modyfikacji danych i zmiany statusu zwracają czas rozpoczęcia procesu.

Najlepsze jest to, że możesz użyć stat(1)w powłoce lub odpowiednim powiązaniu stat(2)z $ favour_programming_language, więc może nie być konieczne uruchomienie zewnętrznego procesu.

UWAGA , że ma nie pracować /usr/compat/linux/procna FreeBSD; zwrócone czasy dostępu / modyfikacji / zmiany statusu są bieżącym czasem, a czas narodzin to epoka UNIX. Całkiem głupie wsparcie nie istnieje, jeśli mnie o to poprosisz.

i336_
źródło
Gdzie w danych wyjściowych statystyki widzę informacje? Widzę tylko Access, Modify and Change.
tshepang
@Tshepang Zauważ, że wszystkie te wartości są takie same i czasem rozpoczęcia procesu. Nadal musisz wykonać matematykę, ale jest to zdecydowanie lepsze niż próbowanie rozgryźć jiffies, jak zauważono w mojej odpowiedzi.
mattdm
Nazywasz to w ten sposób: Otrzymasz stat /proc/4480datę urodzenia, zmiany, modyfikacji i dostępu do procesu. Jeśli potrzebujesz identyfikatora procesu, po prostu użyj „góry”
890332
2

Jeśli możesz uruchomić czas, a następnie wykonać polecenie, otrzymasz dokładnie to, czego szukasz. Nie możesz tego zrobić w stosunku do już uruchomionego polecenia.

[0]% czasu snu 20

spać 20 0,00s użytkownik 0,00s system 0% cpu 20,014 ogółem

slashdot
źródło
Czy wiesz, jak mogę to zrobić w trakcie monitorowania procesu, dopóki się nie zakończy?
lrkwz
1

możesz uzyskać czas rozpoczęcia procesu, patrząc na statplik statystyk utworzony przez proc, sformatuj go za pomocą datei odejmij od bieżącego czasu:

echo $(( $(date +%s) - $(date -d "$(stat /proc/13494/stat | grep Modify | sed 's/Modify: //')" +%s) ))

gdzie 13494jest twój pid proces

szpulki
źródło
1

$ ps -eo lstart uzyskać czas rozpoczęcia

$ ps -eo etime uzyskać czas trwania / upływający czas

$ ps -eo pid,lstart,etime | grep 61819
  PID                   STARTED     ELAPSED
  61819 Mon Sep 17 03:01:35 2018    07:52:15

61819 jest identyfikatorem procesu.

Terry Wang
źródło
Korzystanie z lstart może być problematyczne, to wypacza
slm
1

Czas, który upłynął w sekundach: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)

Shardj
źródło
Wydaje mi się, że jest to bardzo niewielka odmiana tego, o którym wspomniał już Mattdm : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller
Ten nie działał dla mnie na mojej bardzo minimalnej instancji alpejskiego dokera, więc napisałem ten
Shardj