killall me dá 'nenhum processo encontrado' mas ps

13

Alguém poderia me explicar a diferença entre kill e killall ? Por que não killall vê o que ps mostra?

# ps aux |grep db2
root      1123  0.0  0.8 841300 33956 pts/1    Sl   11:48   0:00 db2wdog                                         
db2inst1  1125  0.0  3.5 2879496 143616 pts/1  Sl   11:48   0:02 db2sysc                                        
root      1126  0.0  0.6 579156 27840 pts/1    S    11:48   0:00 db2ckpwd                                        
root      1127  0.0  0.6 579156 27828 pts/1    S    11:48   0:00 db2ckpwd                                        
root      1128  0.0  0.6 579156 27828 pts/1    S    11:48   0:00 db2ckpwd 

# killall db2ckpwd
db2ckpwd: no process found

# kill -9 1126
# kill -9 1127
# kill -9 1128

O sistema é SuSe 11.3 (64 bits); kernel 2.6.34-12; procps versão 3.2.8; killall do PSmisc 22.7; matar do GNU coreutils 7.1

    
por Radek 06.06.2011 / 04:48

3 respostas

16

Isso é no Linux?

Na verdade, existem algumas versões sutilmente diferentes do nome do comando que são usadas por ps , killall , etc.

As duas principais variantes são: 1) o nome do comando longo, que é o que você obtém quando executa ps u ; e 2) o nome curto do comando, que é o que você obtém quando executa ps sem nenhum sinalizador.

Provavelmente, a maior diferença acontece se o seu programa for um script de shell ou qualquer coisa que exija um intérprete, por exemplo, Python, Java, etc.

Aqui está um script realmente trivial que demonstra a diferença. Eu chamei de mycat :

#!/bin/sh
cat

Depois de executá-lo, veja os dois tipos diferentes de ps .

Em primeiro lugar, sem u :

$ ps -p 5290
  PID TTY      ... CMD
 5290 pts/6    ... mycat

Em segundo lugar, com u :

$ ps u 5290
USER       PID ... COMMAND
mikel     5290 ... /bin/sh /home/mikel/bin/mycat

Observe como a segunda versão começa com /bin/sh ?

Agora, até onde eu sei, killall realmente lê /proc/<pid>/stat , e pega a segunda palavra entre os parentes como o nome do comando, então é exatamente isso que você precisa especificar quando você executa killall . Logicamente, isso deve ser o mesmo que ps sem a declaração u , mas seria uma boa ideia verificar.

Coisas a verificar:

  1. o que é que cat /proc/<pid>/stat diz o nome do comando?
  2. o que é que ps -e | grep db2 diz o nome do comando?
  3. do ps -e | grep db2 e ps au | grep db2 mostram o mesmo nome de comando?

Notas

Se você estiver usando outros sinalizadores de ps também, talvez seja mais simples usar ps -o comm para ver o nome abreviado e ps -o cmd para ver o nome longo.

Você também pode achar pkill uma alternativa melhor. Em particular, pkill -f tenta corresponder usando o nome completo do comando, ou seja, o nome do comando conforme impresso por ps u ou ps -o cmd .

    
por 06.06.2011 / 06:24
5

killall tenta combinar em um nome de processo (mas não é tão bom na parte correspondente).

E como "ps | grep" e "ps | grep | kill" faz um trabalho muito melhor, alguém simplificou isso e criou o pgrep e o pkill. Leia os comandos como "ps grep" e "ps kill", já que o comando primeiro ps depois grep e se queria mata.

    
por 06.06.2011 / 15:12
1

Eu tive um problema semelhante, mas /proc/<pid>/stat continha a string esperada. Usando strace eu pude ver que killall também acessou /proc/<pid>/cmdline .

Continuei a investigar usando o gdb para descobrir que, no meu caso, houve falha na verificação do meu comando para o comando completo, incluindo todos os argumentos encontrados em /proc/<pid>/cmdline . Parecia que o caminho do código foi acionado devido ao nome do arquivo ter mais de 15 caracteres (que é um valor codificado na origem do killall). Eu não investiguei totalmente se eu poderia de alguma forma fazê-lo funcionar com o killall.

Mas, como mencionado em outros comentários, aqui pkill é uma alternativa melhor que não tem os mesmos problemas.

O código-fonte de pkill pode ser encontrado aqui link para os interessados.

    
por 15.08.2014 / 16:45