¿Cómo verificar cuánto tiempo ha estado ejecutándose un proceso?

243

Me gustaría evitar hacer esto iniciando el proceso desde una aplicación de monitoreo.

tshepang
fuente

Respuestas:

311

En Linux con psfrom procps(-ng)(y la mayoría de los otros sistemas, ya que POSIX lo especifica):

ps -o etime= -p "$$" 

¿Dónde $$está el PID del proceso que desea verificar? Esto devolverá el tiempo transcurrido en el formato [[dd-]hh:]mm:ss.

El uso -o etimele dice psque solo desea el campo de tiempo transcurrido, y =al final de eso suprime el encabezado (sin, obtiene una línea que dice ELAPSEDy luego el tiempo en la siguiente línea; con, obtiene solo una línea con el tiempo) .

O, con las versiones más recientes del conjunto de herramientas procps-ng (3.3.0 o superior) en Linux o en FreeBSD 9.0 o superior (y posiblemente otros), use:

ps -o etimes= -p "$$"

(con un agregado s) para obtener el tiempo formateado como segundos, lo cual es más útil en los scripts.

En Linux, el psprograma obtiene esto /proc/$$/stat, donde uno de los campos (ver man proc) es la hora de inicio del proceso. Desafortunadamente, esto se especifica como el tiempo en segundos (un contador de tiempo arbitrario utilizado en el kernel de Linux) desde el inicio del sistema. Por lo tanto, debe determinar el momento en que el sistema arrancó (desde /proc/stat), la cantidad de jiffies por segundo en este sistema y luego hacer los cálculos para obtener el tiempo transcurrido en un formato útil.

Resulta ridículamente complicado encontrar el valor de HZ (es decir, jiffies por segundo). De los comentarios en sysinfo.cel paquete procps, uno puede A) incluir el archivo de encabezado del núcleo y volver a compilar si se usa un núcleo diferente, B) usar la sysconf()función posix , que, lamentablemente, usa un valor codificado compilado en la biblioteca C, o C) pregunta al kernel, pero no hay una interfaz oficial para hacerlo. Entonces, el pscódigo incluye una serie de errores por los cuales determina el valor correcto. Guau.

Así que es conveniente que pshaga todo eso por ti. :)

Como señala el usuario @ 336_, en Linux (esto no es portátil), puede usar el statcomando para ver las fechas de acceso, modificación o cambio de estado para el directorio /proc/$$(donde nuevamente $$es el proceso de interés). Los tres números deben ser iguales, entonces

stat -c%X /proc/$$

le dará el tiempo que $$comenzó el proceso , en segundos desde la época. Eso todavía no es lo que quieres, ya que aún necesitas hacer los cálculos para restar eso del tiempo actual para obtener el tiempo transcurrido; supongo que algo así date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"funcionaría, pero es un poco desgarbado. Una posible ventaja es que si usa la salida de formato largo como en -c%xlugar de -c%X, obtendrá una resolución mayor que la de un número entero de segundos. Pero, si lo necesita, probablemente debería usar el enfoque de auditoría de procesos porque el momento de ejecutar el comando stat interferirá con la precisión.

mattdm
fuente
1
¡Hola! Es etime=un error tipográfico? Solo puedo encontrar etimeen las páginas del manual.
Kent Pawar
16
@KentPawar No es un error tipográfico. El vacío =suprime el encabezado. Pruébelo sin, o inténtelops -p $$ -o etime="Silly Header Here"
mattdm
44
ps -p $ (pgrep find) -o etime =
mafrosis
1
Agradable. Me prefiero a etimesmí mismo ya que es legible por máquina
Asfand Qazi
1
@alexmurray Eso solo llama sysconf()y por lo tanto le da el valor codificado de la biblioteca C, como se señaló, ¿no es así?
mattdm
36

Portátil:

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

es decir, ese shell se inició el 30 de enero y totalizó aproximadamente 6 segundos de tiempo de CPU.

Puede haber formas más precisas o más fáciles de analizar pero menos portátiles para obtener esta información. Consulte la documentación de su pscomando o su procsistema de archivos.

Bajo Linux, esta información vive en /proc/$pid/stat.

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

El tiempo de CPU está en segundos; No sé de antemano cómo encontrar el valor jiffy del shell. El tiempo de inicio es relativo al tiempo de arranque (que se encuentra en /proc/uptime).

Gilles
fuente
3
¡Encontrar el valor de HZ (es decir, jiffies por segundo) resulta ser ridículamente complicado! De los comentarios en el sysinfo.cpaquete procps, uno puede a) incluir el archivo de encabezado del núcleo (y recompilar si se usa un núcleo diferente, b) usar la función posix sysconf (), que, lamentablemente, usa un valor codificado compilado en la biblioteca c, o c) pregunta al kernel, y no hay una interfaz oficial para hacerlo. Entonces, el código incluye una serie de errores por los cuales determina el valor correcto. Guau.
mattdm
1
La página de psmanual indica que timees "tiempo de CPU acumulativo". Creo que lo que estaba buscando el OP es etime, o "el tiempo transcurrido desde que se inició el proceso". pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo
1
Después de todo, no es tan "portátil": "ps: stime: palabra clave no encontrada" en FreeBSD. Sin embargo, al menos es compatible etime.
n
18
ps -eo pid,comm,cmd,start,etime | grep -i X

X es el nombre del proceso

mezi
fuente
2
probablemente debería agregar un grep -v grep.
Brian
ps -o pid,comm,cmd,start,etime -p Xmirar PID X.
codeforester
13

pstoma una -oopción para especificar el formato de salida, y una de las columnas disponibles es etime. Según la página del manual:

etime: tiempo transcurrido desde que se inició el proceso, en la forma [[dd-] hh:] mm: ss.

Por lo tanto, puede ejecutar esto para obtener el PID y el tiempo transcurrido de cada proceso:

$ ps -eo pid,etime

Si desea el tiempo transcurrido de un PID particular (por ejemplo, 12345), puede hacer algo como:

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

( Editar : Resulta que hay una sintaxis más corta para el comando anterior; ver la respuesta de mattdm )

Michael Mrozek
fuente
5

No estoy seguro de por qué esto aún no se ha sugerido: en Linux puede stat()usar el directorio / proc / [nnn] para su PID.

Este comportamiento está diseñado explícitamente para devolver el tiempo de inicio del proceso, lo que puede hacer en alta resolución y lo que el núcleo puede hacer con precisión sin los trucos instantáneos, ya que el núcleo puede (obviamente) simplemente verificar la información relevante. Los campos de acceso, modificación de datos y cambio de estado devuelven la hora de inicio del proceso.

Lo mejor de todo es que puede usarlo stat(1)en el shell o en el enlace apropiado stat(2)desde $ favorite_programming_language, por lo que es posible que ni siquiera necesite iniciar un proceso externo.

NOTA que esto no funciona con /usr/compat/linux/procFreeBSD; los tiempos de acceso / modificación / cambio de estado devueltos son la hora actual y la hora de nacimiento es la época de UNIX. Bastante estúpido, el apoyo no está allí si me preguntas.

i336_
fuente
¿Dónde en la salida de stat veo la información? Solo veo Acceso, Modificar y Cambiar.
tshepang
@Tshepang Tenga en cuenta que esos valores son todos iguales y son la hora de inicio del proceso. Todavía tienes que hacer los cálculos, pero esto es definitivamente mejor que tratar de resolver los errores como se señala en mi respuesta.
mattdm
Lo llamas así: stat /proc/4480esto te dará las fechas de nacimiento, cambio, modificación y acceso del proceso. Si necesita la identificación del proceso, simplemente use "top"
user890332
2

Si puede ejecutar el tiempo y luego ejecutar un comando, obtendrá exactamente lo que está buscando. No puede hacer esto contra un comando que ya se está ejecutando.

[0]% de tiempo de sueño 20

dormir 20 0.00s usuario 0.00s sistema 0% cpu 20.014 total

slashdot
fuente
¿Sabes cómo puedo hacerlo en un proceso de monitoreo en ejecución hasta que finalice?
lrkwz
1

puede obtener la hora de inicio del proceso mirando el statarchivo de estadísticas producido proc, formateándolo datey restándolo de la hora actual:

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

donde 13494esta tu proceso pid

bobinas
fuente
1

$ ps -eo lstart obtener hora de inicio

$ ps -eo etime obtener duración / tiempo transcurrido

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

61819 es la identificación del proceso.

Terry Wang
fuente
El uso de lstart puede ser problemático, sesga
unix.stackexchange.com/questions/274610/…
1

Tiempo transcurrido en segundos: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)

Shardj
fuente
Esto me parece una variación muy leve de una que mattdm ya mencionó : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller
Ese no funcionó para mí en mi mínima instancia de
acoplador