Tengo un problema con algunos procesos tipo zombie en un determinado servidor que deben ser eliminados de vez en cuando. ¿Cómo puedo identificar mejor a los que se han ejecutado durante más de una hora más o menos?¿Cómo se eliminan todos los procesos de Linux que son anteriores a cierta edad?
Respuesta
Si sólo necesitan ser matado:
if [[ "$(uname)" = "Linux" ]];then killall --older-than 1h someprocessname;fi
Si quieres ver lo que es a juego
if [[ "$(uname)" = "Linux" ]];then killall -i --older-than 1h someprocessname;fi
La bandera -i
le indicará si/no para cada partido proceso.
Buen consejo. Me encontré con el --derder-- que cambiar más tarde, pero el -i lo hace útil para comprobar antes de matar quién sabe qué. – yukondude
¿Cuál es el punto de 'if [[" $ (uname) "=" Linux "]];'? ¿La porción relevante no es solo el comando 'killall'? (Parece que la cláusula 'if' de los alrededores podría eliminarse para hacer que esta respuesta sea un poco más directa) – rinogo
@ringo Porque en algunos sistemas (por ejemplo, Solaris), killall es un comando completamente diferente.En Solaris, finaliza todos los comandos. – ctc
El uso de ps es la manera correcta. Ya hice algo similar antes, pero no tengo la fuente a mano. Generalmente, ps tiene una opción para indicarle qué campos mostrar y ordenar. Puede ordenar el resultado por tiempo de ejecución, grep el proceso que desea y luego matarlo.
HTH
Para cualquier cosa más viejo que un día,
ps aux
le dará la respuesta, pero desciende a día precisión que podría no ser tan útil.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7200 308 ? Ss Jun22 0:02 init [5]
root 2 0.0 0.0 0 0 ? S Jun22 0:02 [migration/0]
root 3 0.0 0.0 0 0 ? SN Jun22 0:18 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S Jun22 0:00 [watchdog/0]
Si estás en Linux u otro sistema con el sistema de archivos/proc, en este ejemplo, sólo se puede ver que el proceso 1 ha estado funcionando desde el 22 de junio, pero que se inició ninguna indicación de la hora.
stat /proc/<pid>
le dará una respuesta más precisa. Por ejemplo, aquí hay un sello de tiempo exacto para el proceso 1, que ps muestra sólo como Jun22:
ohm ~$ stat /proc/1
File: `/proc/1'
Size: 0 Blocks: 0 IO Block: 4096 directory
Device: 3h/3d Inode: 65538 Links: 5
Access: (0555/dr-xr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2008-06-22 15:37:44.347627750 -0700
Modify: 2008-06-22 15:37:44.347627750 -0700
Change: 2008-06-22 15:37:44.347627750 -0700
Parece que 'ps' y' stat' muestran resultados diferentes para mí. 'ps' muestra que el proceso comenzó hace 1 día y la estadística muestra que comenzó hoy. ¿Por qué? – pl1nk
Tenga en cuenta que la columna 'TIME' en la salida' ps' no muestra el tiempo de ejecución real de un proceso. Muestra el tiempo de CPU acumulado del proceso, el tiempo que las CPU funcionaron con el proceso. –
gracias, stat/proc/
encontrado una respuesta que funciona para mí:
advertencia: esto encontrará y matar procesos de larga ejecución
ps -eo uid,pid,etime | egrep '^ *user-id' | egrep ' ([0-9]+-)?([0-9]{2}:?){3}' | awk '{print $2}' | xargs -I{} kill {}
(Donde user-id es ID de un usuario específico con procesos de larga duración.)
La segunda expresión regular coincide con la hora a que tiene una cifra de días opcional, seguida de una hora, minutos y un segundo componente, y por lo tanto tiene al menos una hora de duración.
Umm, ¿estás matando el proceso? Espero que las personas se den cuenta de que este código no solo busca, sino que también mata, o pueden enojarse. –
@ButtleButkus Buen punto. Sí, todo el motivo de la pregunta era encontrar los procesos anteriores y matarlos, pero no se menciona explícitamente todo eso con claridad. Nota para los demás: ignore la última parte de la línea a menos que disfrute las llamadas molestas de los usuarios. – yukondude
wtf! por favor cambie el título de la pregunta. ¡afortunadamente no tuve el proceso! –
De esta manera se puede obtener la lista de los diez procesos más antiguos:
ps -elf | sort -r -k12 | head -n 10
cosas buenas, gracias por esto. –
En realidad, eso le da los 10 procesos más recientes porque de manera predeterminada muestra STIME, que es el momento en que se inició el programa. Si mostraba ETIME cuál es el tiempo transcurrido desde que se inició el programa, entonces esto sería correcto. –
hacer un ps -aef
. esto le mostrará la hora en que comenzó el proceso. Luego, usando el comando date
, encuentre la hora actual. Calcule la diferencia entre los dos para encontrar la edad del proceso.
Lamentablemente, la salida de tiempo aquí es difícil de analizar. Puede ser "HH: MM" para procesos de ejecución corta, o "MonDD" (¡posiblemente localizado!) O incluso solo el año para procesos muy largos. –
Proc de Perl :: ProcessTable hará el truco: http://search.cpan.org/dist/Proc-ProcessTable/
puede instalarlo en Debian o Ubuntu con sudo apt-get install libproc-processtable-perl
Aquí hay una sola línea:
perl -MProc::ProcessTable -Mstrict -w -e 'my $anHourAgo = time-60*60; my $t = new Proc::ProcessTable;foreach my $p (@{$t->table}) { if ($p->start() < $anHourAgo) { print $p->pid, "\n" } }'
O, más formateado, ponlo en un archivo llamado proceso.pl:
#!/usr/bin/perl -w
use strict;
use Proc::ProcessTable;
my $anHourAgo = time-60*60;
my $t = new Proc::ProcessTable;
foreach my $p (@{$t->table}) {
if ($p->start() < $anHourAgo) {
print $p->pid, "\n";
}
}
continuación, ejecute perl process.pl
Esto le da más versatilidad y 1-segunda resolución sobre la hora de inicio.
hice algo similar a la respuesta aceptada, pero un poco diferente ya que quiero para que coincida con base en nombre del proceso y en base a la mala proceso que se ejecuta durante más de 100 segundos
kill $(ps -o pid,bsdtime -p $(pgrep bad_process) | awk '{ if ($RN > 1 && $2 > 100) { print $1; }}')
stat -t /proc/<pid> | awk '{print $14}'
para obtener el tiempo de inicio del proceso en segundos desde la época. Compare con la hora actual (date +%s
) para obtener la edad actual del proceso.
Podemos unir los dos comandos para obtener segundos desde que comenzó el proceso: "echo' stat -t/proc/
Esto no siempre tenga razón, al menos no para los sistemas Linux 2.6. Tengo un proceso que comenzó a las 9:49 pero stat -t (y stat) muestran que comenzó a las 13:14. –
@dpk: a veces tienes un proceso principal y algunas horquillas ejecutándose. El proceso principal debe ser 9:49, pero el proceso hijo puede tener un tiempo más reciente. Lo mismo se aplica a los hilos de un proceso. – higuita
En caso de que alguien necesita esto en C, puede utilizar readproc.h y libproc:
#include <proc/readproc.h>
#include <proc/sysinfo.h>
float
pid_age(pid_t pid)
{
proc_t proc_info;
int seconds_since_boot = uptime(0,0);
if (!get_proc_stats(pid, &proc_info)) {
return 0.0;
}
// readproc.h comment lies about what proc_t.start_time is. It's
// actually expressed in Hertz ticks since boot
int seconds_since_1970 = time(NULL);
int time_of_boot = seconds_since_1970 - seconds_since_boot;
long t = seconds_since_boot - (unsigned long)(proc_info.start_time/Hertz);
int delta = t;
float days = ((float) delta/(float)(60*60*24));
return days;
}
Puede utilizar bc
a unirse a los dos comandos en la respuesta de la multitud y obtener el número de segundos ellapsed desde que se inició el proceso:
echo `date +%s` - `stat -t /proc/<pid> | awk '{print $14}'` | bc
edición:
Por aburrimiento a la espera de largos procesos para ejecutar , esto es lo que salió después de unos minutos jugueteando:
#file: sincetime
#!/bin/bash
init=`stat -t /proc/$1 | awk '{print $14}'`
curr=`date +%s`
seconds=`echo $curr - $init| bc`
name=`cat /proc/$1/cmdline`
echo $name $seconds
Si pones esto en su camino y lo llama así: desde la vez
imprimirá el proceso cmdline y segundos desde que se inició. También se puede poner esto en su camino:
#file: greptime
#!/bin/bash
pidlist=`ps ax | grep -i -E $1 | grep -v grep | awk '{print $1}' | grep -v PID | xargs echo`
for pid in $pidlist; do
sincetime $pid
done
Y que si se ejecuta:
greptime <pattern>
donde los patrones es una cadena o expresión regular extendida, se imprimirá a cabo todos los procesos coincidan con este patrón y el segundos desde que comenzaron. :)
Jodie C y otros han señalado que se puede usar killall -i
, lo cual está bien si quiere usar el nombre del proceso para matar. Pero si quiere matar con los mismos parámetros que pgrep -f
, debe usar algo como lo siguiente, usando pure bash y el sistema de archivos /proc
.
#!/bin/sh
max_age=120 # (seconds)
naughty="$(pgrep -f offlineimap)"
if [[ -n "$naughty" ]]; then # naughty is running
age_in_seconds=$(echo "$(date +%s) - $(stat -c %X /proc/$naughty)" | bc)
if [[ "$age_in_seconds" -ge "$max_age" ]]; then # naughty is too old!
kill -s 9 "$naughty"
fi
fi
Esto le permite encontrar y matar procesos mayores de max_age
segundos utilizando el nombre proceso completo; es decir, el proceso llamado /usr/bin/python2 offlineimap
se puede eliminar por referencia a "offlineimap", mientras que las soluciones killall
presentadas aquí solo funcionarán en la cadena "python2".
Encontré somewhere..thought es simple y útil
Usted puede usar el comando crontab en forma directa,
* * * * * ps -lf | grep "user" | perl -ane '($h,$m,$s) = split /:/,$F
+[13]; kill 9, $F[3] if ($h > 1);'
o, podemos escribir como script de shell,
#!/bin/sh
# longprockill.sh
ps -lf | grep "user" | perl -ane '($h,$m,$s) = split /:/,$F[13]; kill
+ 9, $F[3] if ($h > 1);'
Y llámalo crontab como tal,
* * * * * longprockill.sh
- 1. ¿Cómo se eliminan los archivos que contienen cierta cadena utilizando el archivo por lotes en Windows?
- 2. ¿Cómo se eliminan todos los caracteres alfabéticos de una cadena?
- 3. Hacer que el comando "Esperar" de Linux espere a TODOS los procesos secundarios
- 4. ¿Cómo encontrar todos los procesos secundarios?
- 5. ¿Por qué se eliminan todos los NUL de mi script?
- 6. Cómo eliminar de TFS todos los archivos que se eliminan de la copia de trabajo?
- 7. SharedPreferences a veces se eliminan
- 8. Listar todos los objetos de cierta clase
- 9. ¿Cómo se enumeran todos los procesos secundarios en python?
- 10. Robocopy mueve los archivos anteriores a
- 11. phpMailer - Cómo se eliminan los destinatarios
- 12. Cómo calcular la utilización de CPU de un proceso y todos sus procesos secundarios en Linux?
- 13. Esperando en PowerShell para que finalicen todos los procesos secundarios
- 14. enumerando todos los procesos en iOS 5.0.1
- 15. ¿Cómo puedo enumerar todos los procesos que se ejecutan en Windows?
- 16. ¿Cuándo se eliminan los archivos de NSCachesDirectory?
- 17. ¿Cómo encontrar todos los archivos con cierta extensión en Android?
- 18. ¿Cómo encuentro todos los procedimientos almacenados que insertan, actualizan o eliminan registros?
- 19. ¿Cómo puedo ignorar todos los archivos excepto los que tienen cierta extensión en git?
- 20. Seleccionar todos los usuarios que están dentro de un cierto rango de edad
- 21. ¿Cómo evito que los elementos vacíos que se eliminan se eliminen al dividir cadenas?
- 22. Linux (Ubuntu) Terminal-how para ver páginas anteriores que no son visibles más
- 23. ¿Cómo se inician los procesos de MPI?
- 24. ¿Cómo se eliminan los caracteres especiales XML en Perl?
- 25. detectar ipad cuando se eliminan los UIPopoverControllers
- 26. Java Garbage Collection detiene todos los procesos de Java
- 27. LINUX: Enlace todos los archivos de uno a otro directorio
- 28. ¿Cómo puedo verificar si todos los archivos dentro de los directorios son jpegs válidos (Linux, se necesita script sh)?
- 29. Los hilos java se eliminan cuando terminan
- 30. ¿Ruby tiene un tipo de lista que mantiene los contenidos ordenados a medida que se suceden/eliminan?
En Linux use 'killall -i --older-than 1h someprocessname' – sanmai
O vea mi respuesta que usa' pgrep' y por lo tanto es más flexible que 'killall'. – g33kz0r