Comment vérifier depuis combien de temps un processus est en cours d'exécution?

243

Je voudrais éviter cela en lançant le processus à partir d'une application de surveillance.

Tshepang
la source

Réponses:

311

Sous Linux avec le psde procps(-ng)(et la plupart des autres systèmes puisque ceci est spécifié par POSIX):

ps -o etime= -p "$$" 

Où se $$trouve le PID du processus que vous souhaitez vérifier. Cela retournera le temps écoulé dans le format [[dd-]hh:]mm:ss.

Utiliser -o etimeindique psque vous voulez juste le champ de temps écoulé et que, =à la fin de celui-ci, l'en-tête est supprimé (sans, vous obtenez une ligne qui indique ELAPSEDensuite l'heure sur la ligne suivante; avec seulement une ligne avec l'heure) .

Ou, avec les versions plus récentes de la suite d’outils procps-ng (3.3.0 ou supérieure) sous Linux ou FreeBSD 9.0 ou ultérieure (et éventuellement d’autres), utilisez:

ps -o etimes= -p "$$"

(avec un ajouté s) pour obtenir l'heure formatée en secondes, ce qui est plus utile dans les scripts.

Sous Linux, le psprogramme obtient cela /proc/$$/stat, où l'un des champs (voir man proc) est l'heure de début du processus. Ceci est malheureusement spécifié comme étant le temps en jiffies (un compteur de temps arbitraire utilisé dans le noyau Linux) depuis le démarrage du système. Vous devez donc déterminer l'heure à laquelle le système a démarré (depuis /proc/stat), le nombre de jiffies par seconde sur ce système, puis faire le calcul pour obtenir le temps écoulé dans un format utile.

Il s'avère ridiculement compliqué de trouver la valeur de HZ (c'est-à-dire jiffies par seconde). A partir des commentaires sysinfo.cdu paquet procps, on peut A) inclure le fichier d’en-tête du noyau et le recompiler si un autre noyau est utilisé, B) utiliser la sysconf()fonction posix , qui utilise malheureusement une valeur codée en dur, compilée dans la bibliothèque C, ou C) demandez au noyau, mais il n'y a pas d'interface officielle pour le faire. Ainsi, le pscode comprend une série de kludges par lesquels il détermine la valeur correcte. Sensationnel.

Donc, c’est pratique de psfaire tout cela pour vous. :)

Comme l'utilisateur @ 336_ le remarque, sous Linux (ce n'est pas portable), vous pouvez utiliser la statcommande pour consulter les dates d'accès, de modification ou de changement d'état du répertoire /proc/$$(où $$est à nouveau le processus qui vous intéresse). Les trois chiffres doivent être identiques, donc

stat -c%X /proc/$$

vous donnera l'heure à laquelle le processus a $$commencé, en secondes depuis l'époque. Ce n’est pas encore tout à fait ce que vous voulez, car vous devez encore faire le calcul pour soustraire cela du temps actuel au temps écoulé - je suppose que quelque chose comme date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"cela fonctionnerait, mais c’est un peu disgracieux. Un avantage possible est que si vous utilisez la sortie au format long comme à la -c%xplace de -c%X, vous obtenez une résolution supérieure à la seconde en nombre entier. Mais si vous en avez besoin, vous devriez probablement utiliser une approche d’audit de processus, car le moment d’exécution de la commande stat va interférer avec la précision.

mattdm
la source
1
Salut! Est-ce etime=une faute de frappe? Je ne peux que trouver etimedans les pages de manuel.
Kent Pawar
16
@KentPawar Ce n'est pas une faute de frappe. Le vide =supprime l'en-tête. Essayez sans, ou essayezps -p $$ -o etime="Silly Header Here"
mattdm
4
ps -p $ (recherche pgrep) -o etime =
mafrosis
1
Agréable. Je etimesme préfère car alors il est lisible par machine
Asfand Qazi
1
@alexmurray Cela appelle sysconf()et vous donne donc la valeur codée en dur de la bibliothèque C, comme indiqué, n'est-ce pas?
Mattdm
36

Portable:

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

En d'autres termes, ce shell a été démarré le 30 janvier et totalise environ 6 secondes de temps processeur.

Il existe peut-être des moyens plus précis ou plus faciles à analyser, mais moins portables, pour obtenir ces informations. Consultez la documentation de votre pscommande ou de votre procsystème de fichiers.

Sous Linux, cette information réside dans /proc/$pid/stat.

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

Le temps de calcul est rapide. Je ne sais pas par avance comment trouver la valeur Jiffy à partir du shell. L'heure de début est relative à l'heure de démarrage (trouvée dans /proc/uptime).

Gilles
la source
3
Trouver la valeur de HZ (c'est-à-dire jiffies par seconde) s'avère ridiculement compliqué! À partir des commentaires du sysinfo.cpaquet procps, on peut a) inclure le fichier d’en-tête du noyau (et le recompiler si un autre noyau est utilisé, b) utiliser la fonction posix sysconf (), qui utilise malheureusement une valeur codée en dur, compilée dans la bibliothèque c, ou c) demandez au noyau, et il n'y a pas d'interface officielle pour le faire. Ainsi, le code comprend une série de kludges par lesquels il détermine la valeur correcte. Sensationnel.
Mattdm
1
La pspage de manuel indique qu'il times'agit d'un "temps CPU cumulé". Je pense que ce que recherchait le PO, c’est-à- etimedire "le temps écoulé depuis le début du processus". pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo
1
Pas si "portable" après tout: "ps: stime: mot-clé non trouvé" sur FreeBSD. Il supporte au moins etime, cependant.
2016
18
ps -eo pid,comm,cmd,start,etime | grep -i X

X est le nom du processus

mezi
la source
2
devrait probablement ajouter un grep -v grep.
Brian
ps -o pid,comm,cmd,start,etime -p Xregarder PID X.
codeforester
13

psprend une -ooption pour spécifier le format de sortie, et l’une des colonnes disponibles est etime. Selon la page de manuel:

etime - temps écoulé depuis le début du processus, sous la forme [[jj-] hh:] mm: ss.

Ainsi, vous pouvez exécuter ceci pour obtenir le PID et le temps écoulé de chaque processus:

$ ps -eo pid,etime

Si vous voulez le temps écoulé d'un PID particulier (par exemple 12345), vous pouvez faire quelque chose comme:

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

( Edit : il s'avère que la syntaxe est plus courte pour la commande ci-dessus; voir la réponse de mattdm )

Michael Mrozek
la source
5

Vous ne savez pas pourquoi cela n’a pas encore été suggéré: sous Linux, vous pouvez stat()utiliser le répertoire / proc / [nnn] pour votre PID.

Ce comportement est explicitement conçu pour renvoyer l’heure de début du processus, ce qu’il peut faire à haute résolution et que le noyau peut effectuer avec précision sans les fous jiffies puisque le noyau peut (bien entendu) simplement vérifier les informations pertinentes. Les champs d'accès, de modification des données et de changement d'état renvoient tous à l'heure de début du processus.

Mieux encore, vous pouvez utiliser stat(1)le shell ou la liaison appropriée à stat(2)partir de $ favorite_programming_language, de sorte que vous n’aurez peut-être pas besoin de lancer un processus externe.

NOTE que cela ne fonctionne pas avec /usr/compat/linux/procFreeBSD; les heures d'accès / de modification / de changement d'état renvoyées sont l'heure actuelle et l'heure de naissance est l'époque UNIX. Assez stupide, le support n’est pas là si vous me le demandez.

i336_
la source
Où dans la sortie de stat puis-je voir l'info? Je ne vois que Access, Modify et Change.
Tshepang
@Tshepang Notez que ces valeurs sont toutes identiques et qu'elles correspondent à l'heure de début du processus. Vous devez encore faire le calcul, mais c'est certainement mieux que d'essayer de comprendre ce qui se passe comme indiqué dans ma réponse.
Mattdm
Vous l'appelez comme ceci: stat /proc/4480ceci vous donnera les dates de naissance, de modification, de modification et d'accès du processus. Si vous avez besoin de l'identifiant du processus, utilisez simplement "top"
user890332
2

Si vous pouvez exécuter le temps puis exécuter une commande, vous obtiendrez exactement ce que vous recherchez. Vous ne pouvez pas faire cela avec une commande déjà en cours d'exécution.

[0]% temps de sommeil 20

dormir 20 0.00s utilisateur 0.00s système 0% cpu 20.014 total

slashdot
la source
Savez-vous comment puis-je le faire sur un processus en cours de surveillance jusqu'à la fin?
lrkwz
1

vous pouvez obtenir l'heure de début du processus en consultant le statfichier de statistiques généré par proc, en le formatant à l'aide de dateet en le soustrayant de l'heure actuelle:

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

13494est votre processus 'pid

bobines
la source
1

$ ps -eo lstart obtenir l'heure de début

$ ps -eo etime obtenir la durée / le temps écoulé

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

61819 est l'identifiant du processus.

Terry Wang
la source
L’utilisation de lstart peut poser problème, elle est biaisée
unix.stackexchange.com/questions/274610/…
1

Temps écoulé en secondes: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)

Shardj
la source
Cela me semble être une très légère variation de celle que mattdm a déjà mentionnée : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller
Celui-ci n'a pas fonctionné pour moi sur mon très minime exemple de docker Alpine. J'ai donc écrit celui-ci
Shardj