Wie überprüfe ich, wie lange ein Prozess läuft?

243

Ich möchte dies vermeiden, indem ich den Prozess über eine Überwachungs-App starte.

Tshepang
quelle

Antworten:

311

Unter Linux mit psfrom procps(-ng)(und den meisten anderen Systemen, da dies von POSIX angegeben wird):

ps -o etime= -p "$$" 

Wo $$ist die PID des Prozesses, den Sie überprüfen möchten. Dies gibt die verstrichene Zeit im Format zurück [[dd-]hh:]mm:ss.

Mit -o etimeerzählt , psdass Sie nur die verstrichene Zeit Feld möchten, und die =am Ende , dass unterdrückt den Header (ohne Sie eine Linie erhalten , die sagt , ELAPSEDund dann die Zeit , in der nächsten Zeile, mit, Sie nur eine Zeile mit der Zeit zu bekommen) .

Oder verwenden Sie mit neueren Versionen der procps-ng-Tool-Suite (3.3.0 oder höher) unter Linux oder unter FreeBSD 9.0 oder höher (und möglicherweise anderen):

ps -o etimes= -p "$$"

(mit einem zusätzlichen s), um die Zeit nur als Sekunden zu formatieren, was in Skripten nützlicher ist.

Unter Linux pserhält das Programm dies /proc/$$/stat, wobei eines der Felder (siehe man proc) die Prozessstartzeit ist. Dies ist leider die Zeit in Sekunden (ein beliebiger Zeitzähler, der im Linux-Kernel verwendet wird) seit dem Systemstart. Sie müssen also den Zeitpunkt bestimmen, von dem aus das System gestartet wurde /proc/stat, die Anzahl der Sekundensprünge auf diesem System ermitteln und dann die verstrichene Zeit in einem nützlichen Format berechnen.

Es erweist sich als lächerlich kompliziert, den Wert von HZ zu ermitteln (dh Sekundenschnelle). Aus den Kommentaren im sysinfo.cprocps-Paket kann man A) die Kernel-Header-Datei einbinden und neu kompilieren, wenn ein anderer Kernel verwendet wird, B) die posix- sysconf()Funktion verwenden, die leider einen in die C-Bibliothek kompilierten fest codierten Wert verwendet, oder C) Frage den Kernel, aber es gibt keine offizielle Schnittstelle, um das zu tun. Der psCode enthält also eine Reihe von Kludges, mit denen der richtige Wert ermittelt wird. Beeindruckend.

So ist es bequem, psdass das alles für Sie erledigt. :)

Wie der Benutzer @ 336_ feststellt, können Sie unter Linux (dies ist nicht portierbar) mit dem statBefehl die Zugriffs-, Änderungs- oder Statusänderungsdaten für das Verzeichnis anzeigen /proc/$$(wobei dies wiederum $$von Interesse ist). Alle drei Zahlen sollten also gleich sein

stat -c%X /proc/$$

gibt Ihnen die Zeit an, zu der der Prozess $$gestartet wurde, in Sekunden seit der Epoche. Das ist immer noch nicht ganz das, was Sie wollen, da Sie immer noch die Mathematik durchführen müssen, um das von der aktuellen Zeit abzuziehen, um die verstrichene Zeit zu erhalten date +%s --date="now - $( stat -c%X /proc/$$ ) seconds". Ein möglicher Vorteil ist, dass Sie eine höhere Auflösung als ganze Sekunden erhalten , wenn Sie die Ausgabe im Langformat wie -c%xanstelle von verwenden -c%X. Wenn Sie dies jedoch benötigen, sollten Sie wahrscheinlich den Prozessüberwachungsansatz verwenden, da der Zeitpunkt der Ausführung des Befehls stat die Genauigkeit beeinträchtigen wird.

mattdm
quelle
1
Hallo! Ist etime=ein Tippfehler? Ich kann nur etimein den Manpages finden.
Kent Pawar
16
@ KentPawar Es ist kein Tippfehler. Das Leerzeichen =unterdrückt den Header. Versuchen Sie es ohne, oder versuchen Sieps -p $$ -o etime="Silly Header Here"
mattdm
4
ps -p $ (pgrep find) -o etime =
mafrosis
1
Nett. Ich bevorzuge etimesmich selbst, da es dann maschinenlesbar ist
Asfand Qazi
1
@alexmurray Das ruft einfach auf sysconf()und gibt Ihnen daher den fest codierten Wert aus der C-Bibliothek, wie bereits erwähnt, nicht wahr ?
Mattdm
36

Tragbar:

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

Das heißt, diese Shell wurde am 30. Januar gestartet und dauerte insgesamt etwa 6 Sekunden CPU-Zeit.

Möglicherweise gibt es genauere oder besser analysierbare, aber weniger tragbare Methoden, um diese Informationen abzurufen. Überprüfen Sie die Dokumentation Ihres psBefehls oder Ihres procDateisystems.

Unter Linux leben diese Informationen in /proc/$pid/stat.

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

Die CPU-Zeit ist in Sekundenschnelle. Ich weiß nicht sofort, wie ich den Sofortwert aus der Shell herausfinden soll. Die Startzeit ist relativ zur Startzeit (gefunden in /proc/uptime).

Gilles
quelle
3
Das Auffinden des Wertes von HZ (also Sekundenschnelle) erweist sich als lächerlich kompliziert! Aus den Kommentaren im sysinfo.cprocps-Paket kann man a) die Kernel-Header-Datei einschließen (und neu kompilieren, wenn ein anderer Kernel verwendet wird), b) die posix sysconf () -Funktion verwenden, die leider einen fest codierten Wert verwendet, in den kompiliert wurde die c Bibliothek oder c) den Kernel fragen, und es gibt keine offizielle Schnittstelle, um das zu tun. Der Code enthält also eine Reihe von Kludges, mit denen der richtige Wert ermittelt wird. Beeindruckend.
Mattdm
1
Die psManpage gibt an, dass timees sich um "kumulative CPU-Zeit" handelt. Ich denke, wonach das OP gesucht hat etime, oder "die verstrichene Zeit, seit der Prozess gestartet wurde". pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo
1
Immerhin nicht so "portabel": "ps: stime: keyword not found" unter FreeBSD. Zumindest unterstützt es etime.
23.
18
ps -eo pid,comm,cmd,start,etime | grep -i X

X ist der Name des Prozesses

Mezi
quelle
2
sollte wahrscheinlich ein grep -v grep hinzufügen.
Brian
ps -o pid,comm,cmd,start,etime -p XPID X zu sehen.
Codeforester
13

psEs wird eine -oOption zum Angeben des Ausgabeformats verwendet, und eine der verfügbaren Spalten lautet etime. Nach der Manpage:

Etime - Verstrichene Zeit seit dem Start des Prozesses in der Form [[dd-] hh:] mm: ss.

So können Sie dies ausführen, um die PID und die verstrichene Zeit jedes Prozesses zu erhalten:

$ ps -eo pid,etime

Wenn Sie die abgelaufene Zeit einer bestimmten PID (z. B. 12345) anzeigen möchten, können Sie Folgendes tun:

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

( Bearbeiten : Es stellt sich heraus, dass es eine kürzere Syntax für den obigen Befehl gibt; siehe die Antwort von mattdm )

Michael Mrozek
quelle
5

Unsicher, warum dies noch nicht vorgeschlagen wurde: Unter Linux können Sie stat()das Verzeichnis / proc / [nnn] für Ihre PID verwenden.

Dieses Verhalten ist explizit darauf ausgelegt, die Prozessstartzeit zurückzugeben, die mit hoher Auflösung ausgeführt werden kann und die der Kernel ohne die Jiffies-Hacks genau ausführen kann, da der Kernel (offensichtlich) einfach die relevanten Informationen überprüfen kann. Die Felder "Zugriff", "Datenänderung" und "Statusänderung" geben die Startzeit des Prozesses zurück.

Das Beste ist, dass Sie stat(1)die Shell oder die entsprechende Bindung stat(2)von $ favorite_programming_language verwenden können, sodass Sie möglicherweise nicht einmal einen externen Prozess starten müssen.

HINWEIS, dass dies unter FreeBSD nicht funktioniert /usr/compat/linux/proc. Die zurückgegebenen Zugriffs / Änderungs- / Statusänderungszeiten sind die aktuelle Zeit und die Geburtszeit ist die UNIX-Epoche. Sehr dumm, dass der Support nicht da ist, wenn du mich fragst.

i336_
quelle
Wo in der Ausgabe von stat sehe ich die Info? Ich sehe nur Zugriff, Ändern und Ändern.
Tshepang
@Tshepang Beachten Sie, dass diese Werte alle gleich sind und es sich um die Startzeit des Prozesses handelt. Sie müssen immer noch rechnen, aber das ist definitiv besser, als zu versuchen, die in meiner Antwort angegebenen Probleme zu lösen.
Mattdm
Sie nennen es so: stat /proc/4480Dies gibt Ihnen die Geburts-, Änderungs-, Änderungs- und Zugriffstermine des Prozesses. Wenn Sie die Prozess-ID benötigen, verwenden Sie einfach "top"
user890332
2

Wenn Sie Zeit ausführen und dann einen Befehl ausführen können, erhalten Sie genau das, was Sie suchen. Sie können dies nicht für einen bereits ausgeführten Befehl ausführen.

[0]% Zeitschlaf 20

sleep 20 0.00s user 0.00s system 0% cpu 20.014 gesamt

Schrägstrich
quelle
Wissen Sie, wie ich es bei laufender Prozessüberwachung bis zum Ende tun kann?
lrkwz
1

Sie können die Startzeit des Prozesses statabrufen, indem procSie sich die von erzeugte stat-Datei ansehen , sie mit formatieren dateund von der aktuellen Zeit subtrahieren:

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

Wo 13494ist dein Prozess?

Spulen
quelle
1

$ ps -eo lstart Holen Sie sich die Startzeit

$ ps -eo etime Dauer / verstrichene Zeit abrufen

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

61819 ist die Prozess-ID.

Terry Wang
quelle
Die Verwendung von lstart problematisch sein kann, es skews - unix.stackexchange.com/questions/274610/...
slm
1

Verstrichene Zeit in Sekunden: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)

Shardj
quelle
Dies scheint mir eine sehr kleine Abwandlung von einer zu sein, die mattdm bereits erwähnt hat : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller
Dieser hat auf meiner sehr minimalen Alpine Docker-Instanz nicht funktioniert, also habe ich diesen geschrieben
Shardj