Encontre (e mate) processos antigos

10

Basicamente, preciso verificar a árvore de processos e encontrar processos que correspondam a um determinado nome e que começaram a ser executados mais de uma semana por semana. Depois de tê-los, preciso matá-los. Todos os processos ainda são vistos como em estado de execução pelo sistema, apenas sem usar nenhum horário do sistema. Eles também costumam ficar para sempre nesse estado.

Idealmente, eu gostaria de algo semelhante para encontrar, mas para processos.

O sistema é o Debian linux e isso será script e executado pelo cron, então não tenho problemas reais com algo grande, mas compreensível.

Ryaner
fonte
4
como você vai diferenciar processos antigos, mas importantes, daqueles que você está feliz em matar?
Chopper3

Respostas:

9

Você pode fazer isso com uma combinação de ps, awk e kill:

ps -eo pid,etime,comm

Fornece uma saída de três colunas, com o PID do processo, o tempo decorrido desde o início do processo e o nome do comando, sem argumentos. O tempo decorrido se parece com um destes:

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

Como você deseja que os processos estejam em execução há mais de uma semana, procure linhas que correspondam ao terceiro padrão. Você pode usar o awk para filtrar os processos executando o tempo e o nome do comando, assim:

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

que imprimirá os pids de todos os comandos correspondentes a 'mycommand' que estão em execução há mais de 7 dias. Canalize essa lista para matar, e pronto:

ps -eo pid,etime,comm | awk '$2~/^7-/ && $3~/mycommand/ { print $1 }' | kill -9
Ian Clelland
fonte
Agradável obrigado. Esqueci completamente as opções de formatação no ps.
21909 Ryaner
2
Isso não mostra os processos em execução "mais de 7 dias". Ele mostra os processos em execução entre 7 dias e menos de 8 dias.
hobodave
etimesé mais útil - serverfault.com/a/393476/67675
poige
4

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

billyw
fonte
1
Isso funciona muito bem no Ubuntu 16.04 e você pode usar o sinalizador -i (interativo) para testar e garantir que ele esteja direcionado aos processos que você acha que deveria ser.
Ezwrighter # 10/18
1

Todas as informações que você precisa podem ser obtidas ps -ef. Veja a coluna "STIME". Combine isso com greppara resolver os processos que você precisa. Nesse ponto, você pode usar cutpara pegar o pid de todos os processos correspondentes e passá-los para kill.

Entre em contato se desejar obter mais detalhes sobre como fazer isso.

EEAA
fonte
Eu gostaria de mais detalhes. As outras respostas estão simplesmente incorretas.
hobodave
1

se você é root, para se livrar do lixo (/ proc / fs proc / stat ...)

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

fonte
0

Quando um processo é iniciado, ele cria um diretório no sistema de arquivos / proc. Você pode usar o comando find para obter diretórios com mais de 7 dias e eliminar os processos da seguinte maneira:

find /proc -user myuser -maxdepth 1 -type d -mtime +7 -exec basename {} \; | xargs kill -9 
dogbane
fonte
Isso também não funciona. Como está, gera esse aviso e nenhuma saída adicional: 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 ser a primeira saída que não retorna nenhum processo, e tenho certeza de que muitos devem corresponder.
hobodave
também porque mtime não ctime se você está procurando a data de criação do diretório? a dir poderia, teoricamente, ser modificado se uma criança adicional foi criado, que eu não descartaria (talvez um módulo do kernel recém-carregado estenderia sysfs de alguma forma)
jmtd
0

Ninguém mencionou ps-watcher aqui. Eu acho que você pode comparar $ start_time usando a função decorrido2sec, mas não tenho certeza. Aqui está o meu primeiro pensamento:

[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

não faço ideia se isso funciona, mas deve ser um bom ponto de partida.

Phil Hollenback
fonte