Matando todo o processo de um comando, exceto primeiro processo

3

Às vezes, fico preso em uma situação em que um script / comando mantido no Cron é executado mais de uma vez por alguns motivos (a primeira instância não é concluída totalmente, a segunda instância do mesmo processo é iniciada) e em algum momento. esses processos aumentam muito e mostram o sistema pendurado etc. Então, o que eu quero como uma solução temporária aqui é verificar se há mais de uma instância do script / comando dizendo,

ps -ef | pgrep -f 'DELETE OPERATION_CONTEXT'

ou diretamente matar todos os processos deste comando

ps -ef | pkill -f 'DELETE OPERATION_CONTEXT'

Mas eu quero ter uma ideia de como posso matar todos os processos do comando pgrepped, exceto pelo primeiro processo (isso permitiria que um dos processos continuasse funcionando e todas as outras duplicatas fossem eliminadas).

    
por Ankit Vashistha 02.01.2013 / 12:44

4 respostas

3

Você pode fazer isso, por exemplo, com:

OLDEST_PID=$(pgrep -o 'DELETE OPERATION_CONTEXT')
test $OLDEST_PID && pgrep 'DELETE OPERATION_CONTEXT' | grep -vw $OLDEST_PID | xargs -r kill

A primeira linha encontra o PID mais antigo. A segunda linha verifica primeiro se $OLDEST_PID contém alguma coisa. Se sim, lista todos os processos correspondentes, filtra o $OLDEST_PID out e mate-os (se algum permanecer).

A melhor maneira é evitar processos duplicados adicionando arquivos de travamento ao script cron como nesta pergunta .

    
por 02.01.2013 / 13:12
3

Abaixo Exemplo de processo apache2, ele matará todos os PID, exceto o primeiro

pgrep apache2 |awk 'NR >= 2' | xargs -n1  echo kill

se a saída do comando acima parece bem, então você pode remover echo

    
por 02.01.2013 / 13:14
2

você pode experimentar:

ps -e --sort=start -o start,pid,cmd|grep <cmd>|egrep -v grep |sed 1d

isto fornecerá a seguinte saída formatada:

hora de início, PID, comando sendo executado

for i in 'ps -e --sort=start -o start,pid,cmd|grep <cmd>|egrep -v grep |sed 1d'
do
     kill -9 $i
done

substitua o kill por echo primeiro para garantir que ele mate os novos.

    
por 02.01.2013 / 13:12
0

se você tiver java crons e quiser verificar antes da execução desse cron, tente isto: System.out.println ("Verificando sessões anteriores deste cron:" + cronname);

            String proname=ManagementFactory.getRuntimeMXBean().getName();
            String pid=proname.split("@")[0];
            System.out.println("Current PID:"+pid);

            Process proc = Runtime.getRuntime().exec(new String[]{"bash","-c"," ps aux | grep "+cronname+" | awk '{print $2}' "});

            BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String s = null;
            String killid="";

            while ((s = stdInput.readLine()) != null ) {                                        
                if(s.equals(pid)==false)
                {
                    killid=killid+s+" ";    
                }
            }
            System.out.println("Running PID'S except current:"+killid);

            proc.waitFor();             

            Process proc1 = Runtime.getRuntime().exec(new String[]{"bash","-c","kill -9 "+killid});
            proc1.waitFor();                

            System.out.println("Previous duplicate sessions closed for: "+cronname);        

passa o cronname como ur cronname.jar

    
por 28.12.2016 / 09:57