Encuentra (y elimina) procesos antiguos

10

Básicamente, necesito poder escanear el árbol de procesos y encontrar procesos que coincidan con un nombre determinado y comencé a correr más de una semana. Una vez que los tengo, necesito matarlos. Todos los procesos todavía son vistos como en estado de ejecución por el sistema, simplemente sin usar ningún tiempo del sistema. Por lo general, también se sentarán para siempre en este estado.

Idealmente me gustaría algo similar para encontrar, pero para procesos.

El sistema es Debian Linux y esto será programado y ejecutado por cron, así que no tengo problemas reales con algo grande pero comprensible.

Ryaner
fuente
44
¿Cómo vas a diferenciar entre los procesos antiguos pero importantes y los que estás feliz de matar?
Chopper3

Respuestas:

9

Puedes hacer esto con una combinación de ps, awk y kill:

ps -eo pid,etime,comm

Le da una salida de tres columnas, con el PID del proceso, el tiempo transcurrido desde que comenzó el proceso y el nombre del comando, sin argumentos. El tiempo transcurrido se parece a uno de estos:

mm:ss
hh:mm:ss
d-hh:mm:ss

Dado que desea procesos que se hayan estado ejecutando durante más de una semana, debería buscar líneas que coincidan con ese tercer patrón. Puede usar awk para filtrar los procesos por tiempo de ejecución y por nombre de comando, así:

ps -eo pid,etime,comm | awk '$2~/^7-/ && $3~/mycommand/ { print $1 }'

que imprimirá los pids de todos los comandos que coinciden con 'mycommand' que se han estado ejecutando durante más de 7 días. Canaliza esa lista en kill, y listo:

ps -eo pid,etime,comm | awk '$2~/^7-/ && $3~/mycommand/ { print $1 }' | kill -9
Ian Clelland
fuente
Buena gracias. Se olvidó por completo de las opciones de formato en ps.
Ryaner el
2
Esto no muestra los procesos que se ejecutan "más de 7 días". Muestra procesos que se ejecutan entre 7 días pero menos de 8 días.
hobodave
etimeses más útil - serverfault.com/a/393476/67675
poige
4

killall --quiet --older-than 1w process_name

billyw
fuente
1
Esto funciona de maravilla en Ubuntu 16.04 y puedes usarlo con el indicador -i (interactivo) para probar y asegurarte de que está dirigido a los procesos que crees que deberían ser.
ezwrighter
1

Se puede obtener toda la información que necesita ps -ef. Ver la columna "TIEMPO". Combina eso con greppara ordenar los procesos que necesitas. En ese punto, puede utilizar cutpara tomar el pid de todos los procesos de coincidencia y pasarlos a kill.

Avíseme si desea obtener más detalles sobre cómo hacer esto.

EEAA
fuente
Me gustaría más detalles Las otras respuestas son simplemente incorrectas.
hobodave
1

si eres root, para deshacerte de la basura (/ proc / fs proc / stat ...)

find /proc -maxdepth 1 -regex '/proc/[0-9]*' -type d -mtime +2 -exec basename {} \;

fuente
0

Cuando se inicia un proceso, crea un directorio en el sistema de archivos / proc. Puede usar el comando find para obtener directorios de más de 7 días y eliminar los procesos de la siguiente manera:

find /proc -user myuser -maxdepth 1 -type d -mtime +7 -exec basename {} \; | xargs kill -9 
dogbane
fuente
Esto tampoco funciona. Tal como está, genera esta advertencia y no hay salida adicional: al find: warning: you have specified the -maxdepth option after a non-option argument -user, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.mover -maxdepth para que sea la primera salida, no devuelve ningún proceso, y estoy seguro de que muchos deberían coincidir.
hobodave
¿también por qué mtime no ctime si está buscando la fecha de creación del directorio? dir teóricamente podría modificarse si se creara un hijo más, que yo no descartaría (tal vez un módulo del núcleo recién cargada extendería sysfs de alguna manera)
jmtd
0

Nadie mencionó ps-watcher aquí. Creo que podría comparar $ start_time usando la función elapsed2sec, pero no estoy completamente seguro. Aquí está mi primer pensamiento:

[myproc]
occurs = every
trigger = elapsed2secs('$start_time') > 7*DAYS
action = <<EOT
  echo "$command has been running more than 7 days" | /bin/mail user\@host
  kill -TERM $pid
EOT

No tengo idea si eso funciona, pero debería ser un buen punto de partida.

Phil Hollenback
fuente