Come verificare da quanto tempo è in esecuzione un processo?


243

Vorrei evitare di farlo avviando il processo da un'app di monitoraggio.

Risposte:


311

Su Linux con il psda procps(-ng)(e la maggior parte degli altri sistemi poiché questo è specificato da POSIX):

ps -o etime= -p "$$" 

Dov'è $$il PID del processo che si desidera verificare. Ciò restituirà il tempo trascorso nel formato [[dd-]hh:]mm:ss.

Utilizzando -o etimedice psche vuoi solo il campo del tempo trascorso e =alla fine di ciò sopprime l'intestazione (senza, ottieni una riga che dice ELAPSEDe quindi il tempo sulla riga successiva; con, ottieni solo una riga con il tempo) .

Oppure, con le versioni più recenti della suite di strumenti procps-ng (3.3.0 o successive) su Linux o su FreeBSD 9.0 o successive (e possibilmente altre), usare:

ps -o etimes= -p "$$"

(con l'aggiunta s) per ottenere il tempo formattato in pochi secondi, il che è più utile negli script.

Su Linux, il psprogramma ottiene questo da /proc/$$/statdove uno dei campi (vedi man proc) è l'ora di inizio del processo. Questo, sfortunatamente, è specificato per essere il tempo in jiffies (un contatore temporale arbitrario usato nel kernel Linux) dall'avvio del sistema. Quindi devi determinare il momento in cui il sistema si è avviato (da /proc/stat), il numero di jiffie al secondo su questo sistema e quindi fare i calcoli per ottenere il tempo trascorso in un formato utile.

Risulta ridicolmente complicato trovare il valore di HZ (cioè jiffies al secondo). Dai commenti nel sysinfo.cpacchetto procps, si può A) includere il file header del kernel e ricompilare se si usa un kernel diverso, B) usare la sysconf()funzione posix , che, purtroppo, usa un valore hardcoded compilato nella libreria C, oppure C) chiedi al kernel, ma non esiste un'interfaccia ufficiale per farlo. Quindi, il pscodice include una serie di kludges con cui determina il valore corretto. Wow.

Quindi è conveniente che psfa tutto per te. :)

Come osserva l'utente @ 336_, su Linux (questo non è portatile), è possibile utilizzare il statcomando per esaminare le date di accesso, modifica o modifica dello stato della directory /proc/$$(dove di nuovo $$è il processo di interesse). Tutti e tre i numeri dovrebbero essere uguali, quindi

stat -c%X /proc/$$

ti darà il tempo in cui è $$iniziato il processo , in secondi dall'epoca. Non è ancora quello che vuoi, dal momento che devi ancora fare i conti con la matematica per sottrarlo dal tempo corrente per ottenere il tempo trascorso - immagino che qualcosa del genere date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"funzionerebbe, ma è un po 'sgraziato. Un possibile vantaggio è che se si utilizza l'output di formato lungo come -c%xinvece di -c%X, si ottiene una risoluzione maggiore rispetto ai secondi di numero intero. Ma, se ne hai bisogno, probabilmente dovresti usare l'approccio di auditing dei processi perché i tempi di esecuzione del comando stat interferiranno con precisione.


1
Ciao! È etime=un errore di battitura? Lo trovo solo etimenelle pagine man.
Kent Pawar,

16
@KentPawar Non è un errore di battitura. Il vuoto =sopprime l'intestazione. Provalo senza o provaps -p $$ -o etime="Silly Header Here"
mattdm il

4
ps -p $ (pgrep find) -o etime =
mafrosis

1
Bello. Preferisco etimesme stesso perché è leggibile automaticamente
Asfand Qazi il

1
@alexmurray Che chiama sysconf()e quindi ti dà il valore hardcoded dalla libreria C, come notato, non è vero?
Mattdm

36

Portatile:

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

cioè quella shell è stata avviata il 30 gennaio e ha totalizzato circa 6 secondi di tempo CPU.

Potrebbero esserci modi più precisi o più analizzabili ma meno portatili per ottenere queste informazioni. Controlla la documentazione del tuo pscomando o del tuo procfilesystem.

Sotto Linux, questa informazione vive /proc/$pid/stat.

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

Il tempo della CPU è in jiffies; Non so con disinvoltura come trovare il valore jiffy dalla shell. L'ora di inizio è relativa all'ora di avvio (trovata in /proc/uptime).


3
Trovare il valore di HZ (cioè jiffies al secondo) risulta ridicolmente complicato! Dai commenti nel sysinfo.cpacchetto procps, si può a) includere il file header del kernel (e ricompilare se si usa un kernel diverso, b) usare la funzione posix sysconf () che, purtroppo, usa un valore hardcoded compilato in la libreria c, o c) chiedi al kernel, e non esiste un'interfaccia ufficiale per farlo. Quindi, il codice include una serie di kludges con cui determina il valore corretto. Wow.
Mattdm,

1
La psmanpage indica che timeè "tempo cumulativo della CPU". Penso che ciò che l'OP stava cercando sia etime"il tempo trascorso dall'inizio del processo". pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo

1
Dopotutto non così "portatile": "ps: stime: parola chiave non trovata" su FreeBSD. Almeno supporta etime, comunque.
n.

18
ps -eo pid,comm,cmd,start,etime | grep -i X

X è il nome del processo


2
dovrebbe probabilmente aggiungere un grep -v grep.
Brian,

ps -o pid,comm,cmd,start,etime -p Xper guardare PID X.
codeforester

13

psaccetta -oun'opzione per specificare il formato di output e una delle colonne disponibili è etime. Secondo la pagina man:

etime - tempo trascorso dall'inizio del processo, nella forma [[dd-] hh:] mm: ss.

Quindi puoi eseguirlo per ottenere il PID e il tempo trascorso di ogni processo:

$ ps -eo pid,etime

Se vuoi il tempo trascorso di un particolare PID (ad es. 12345), puoi fare qualcosa del tipo:

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

( Modifica : si scopre che c'è una sintassi più breve per il comando sopra; vedi la risposta di mattdm )


5

Non so perché questo non sia stato ancora suggerito: su Linux puoi stat()la directory / proc / [nnn] per il tuo PID.

Questo comportamento è esplicitamente progettato per restituire l'ora di inizio del processo, cosa che può fare ad alta risoluzione e che il kernel può fare con precisione senza gli hack jiffies poiché il kernel può (ovviamente) semplicemente controllare le informazioni rilevanti. I campi di accesso, modifica dei dati e modifica dello stato restituiscono l'ora di inizio del processo.

Soprattutto, è possibile utilizzare stat(1)nella shell o il binding appropriato stat(2)da $ favorite_programming_language, quindi potrebbe non essere necessario avviare un processo esterno.

NOTA che questo non funziona con /usr/compat/linux/procFreeBSD; i tempi di accesso / modifica / cambio di stato restituiti sono l'ora corrente e l'ora di nascita è l'epoca UNIX. Abbastanza stupido il supporto non c'è se me lo chiedi.


Dove nell'output di stat vedo le informazioni? Vedo solo Accesso, Modifica e Modifica.
Tshepang,

@Tshepang Notare che quei valori sono tutti uguali e sono l'ora di inizio del processo. Devi ancora fare i conti, ma questo è decisamente meglio che cercare di capire i jiffies come indicato nella mia risposta.
Mattdm,

Lo chiami in questo modo: stat /proc/4480questo ti darà le date di nascita, modifica, modifica e accesso del processo. Se hai bisogno dell'ID del processo, usa "top"
user890332 il

2

Se puoi eseguire il tempo e poi eseguire un comando otterrai esattamente quello che stai cercando. Non puoi farlo contro un comando già in esecuzione.

[0]% tempo di sospensione 20

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


Sai come posso farlo su un monitoraggio del processo in esecuzione fino al termine?
lrkwz,

1

è possibile ottenere l'ora di inizio del processo osservando il statfile stat prodotto da proc, formattarlo utilizzando datee sottrarlo dall'ora corrente:

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

dov'è il 13494tuo processo 'pid


1

$ ps -eo lstart ottenere l'ora di inizio

$ ps -eo etime ottenere durata / tempo trascorso

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

61819 è l'id del processo.


L'uso di lstart può essere problematico, inclina
slm

1

Tempo trascorso in secondi: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)


Questa mi sembra una leggera variazione di quella già menzionata da Mattdm : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller

Quello non ha funzionato per me sulla mia istanza di docker alpina molto minimale, quindi ho scritto questo
Shardj il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.