Matando um processo nomeado com mais de X minutos? (sem killall -o)

1

Ok, primeiro post! Então, tenho essa situação em que preciso verificar se há um processo com mais de 5 minutos por um nome de processo específico. O problema é que o sistema em questão é uma versão customizada do CentOS 4, então ele tem o pmisc 21.4 e o killall não incorpora -o / - mais que o 22.9. Eu não tenho nenhuma opção de atualizar o sistema, então, por favor, não sugira isso como uma opção. É um sistema interno sem acesso externo, portanto, os possíveis problemas de segurança não são uma grande preocupação para esse cliente.

Engenheiros estão trabalhando em uma solução para descobrir por que esse processo está sendo desconectado ocasionalmente, mas nesse meio tempo, eu só preciso cronografar um script para verificar se o processo foi cancelado se ele estiver sendo executado por mais de 5 min, porque normalmente deve levar apenas 30-45 segundos para ser concluído.

Tenho certeza de que isso pode ser feito com a saída do ps, algumas sintaxes egrep e regex, mas não sei como colocá-las juntas.

O processo é chamado de "synch". Alguém me deu o seguinte código sugerido, mas parece não funcionar corretamente.

#!/bin/bash

for i in $(pgrep -f synch)
do
TIME=$(ps --no-headers -o etime $i | cut -d":" -f 2)
if [ "$TIME" -gt 4 ] ; then
kill $i
fi
done
    
por user179421 12.07.2016 / 20:31

5 respostas

2

De acordo com a página man, o formato para etime é [[DD-]hh:]mm:ss , o que é um pouco chato de analisar porque alguns campos podem estar faltando.

Se assumirmos que o processo está sendo executado apenas por um breve período, o primeiro campo deve ser de minutos. Portanto, tente com cut -d: -f1 em vez de -f2 . Isso lhe dará horas, se o processo estiver sendo executado por um tempo ...

( etimes seria muito melhor, mas não parece estar presente mesmo no psmisc 22.2-5, então você provavelmente não pode usá-lo.)

    
por 12.07.2016 / 21:09
2

Se o velho CentOS 4 tiver find , pode valer a pena tentar.

find /proc -maxdepth 1 -regex '/proc/[0-9]*' -type d -mmin +5 -exec kill {} \;
    
por 12.07.2016 / 21:55
2

Teste -o etimes , que fornece o tempo em segundos, em vez de uma representação amigável para os seres humanos. Então você pode se livrar do cut e verificar se o tempo é de pelo menos 300 segundos:

#!/bin/bash

for i in $(pgrep -f synch)
do
    TIME=$(ps --no-headers -o etimes $i)
    if [ "$TIME" -ge 300 ] ; then
        kill $i
    fi
done
    
por 12.07.2016 / 21:02
1
find /proc/ -maxdepth 1 -type d -name '[0-9]*' -mmin +5 | 
  sed -e 's:$:/comm:' | 
  xargs -r grep -l '^synch$' |
  cut -d/ -f3 |
  xargs -r kill

encontre todos os processos com mais de 5 minutos com o nome do processo ( /proc/PID/comm ) correspondente ao regexp ^synch$ e elimine-os.

    
por 13.07.2016 / 08:26
0

Se você não se importa com o C ++, e a máquina tem os recursos de sobra, você pode escrever um programa recursivo como o seguinte:

int main()
{
 int Started;
 int Passed;
RUNAGAIN:
 system("time=$(date); echo $time > ~/timeStarted");
CHECKTIME:
 system("passed0=$(date); echo $passed0 > ~/timePassed; passed 1=$(cut -c15,16 ~/timePassed); echo $passed1 > ~/timePassedCut; started0=$(cut -c15,16 ~/timeStarted; echo $started0 > ~/timeStartedCut");
 ifstream STARTED("~/timeStartedCut");
 STARTED>>Started;
 STARTED.close();
 ifstream PASSED("~/timePassedCut");
 PASSED>>Passed;
 PASSED.close();
 int TimePassed
 TimePassed = Started - Passed;
 if(TimePassed>4)
   {
    system("killall *process name here*; ~/*process name here*//to start it again, omit if uneeded//");
    goto RUNAGAIN;
   }
 else if(TimePassed<5)
   {
    goto CHECKTIME;
   }
}

Ele puxará a data de quando o programa iniciar, cortará o minuto da hora, gravará em um arquivo, carregará o arquivo como uma variável, fará o mesmo após algum tempo, e se a diferença entre o contagem de minutos da hora de início e contagem de minutos da hora de verificação é 5 ou maior mata o processo. Inicie o processo em questão com um script de shell básico contendo o seguinte para garantir que tanto o processo quanto o cronômetro iniciem simultaneamente:

#!/bin/sh

~/*process name here* & ~/CheckTime
    
por 12.07.2016 / 21:47