killall me dá `nenhum processo encontrado ', mas ps

17

Alguém poderia me explicar a diferença entre kille killall? Por que não killallvê o que psmostra?

# 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 a partir do GNU coreutils 7.1

Radek
fonte
Nunca mate processos com SIGKILL (-9).
vonbrand
O que fazer quando um processo precisa terminar?
Radek
Este é o último, muito último recurso.
vonbrand

Respostas:

19

Isso está no Linux?

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

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 abreviado do comando, que é o que você obtém ao executar pssem nenhum sinalizador.

Provavelmente a maior diferença acontece se o seu programa for um shell script 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 mycat:

#!/bin/sh
cat

Depois de executá-lo, eis 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 /bin/sh?

Agora, até onde eu sei, killallna verdade lê /proc/<pid>/state pega a segunda palavra entre parênteses como o nome do comando, então é exatamente isso que você precisa especificar ao executar killall. Logicamente, isso deve ser o mesmo que o que psnão uindica a bandeira, mas seria uma boa ideia verificar.

Coisas a verificar:

  1. o que cat /proc/<pid>/statdiz o nome do comando?
  2. o que ps -e | grep db2diz o nome do comando?
  3. fazer ps -e | grep db2e ps au | grep db2mostrar o mesmo nome de comando?

Notas

Se você estiver usando outros sinalizadores ps também, talvez seja mais fácil usá-lo ps -o commpara ver o nome abreviado e ps -o cmdo nome longo.

Você também pode encontrar pkilluma alternativa melhor. Em particular, pkill -ftenta corresponder usando o nome completo do comando, ou seja, o nome do comando impresso por ps uou ps -o cmd.

Mikel
fonte
muito boa explicação. E eu acho que você estava certo da primeira vez. ps -e |grep db2 gives me 3084? 00:00:00 db2syscr` e ps aux | grep db2 me dá root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd. Poderia comentar sobre isso. Estou um pouco perdido.
Radek
Não tenho certeza. É possível que o programa esteja mudando seu nome. Você sabe como está sendo executado? O que ls -l /proc/3084/exediz? Que tal whichou whenceou typepara encontrar o arquivo e, em seguida, lse typepara ver se é um link simbólico ou um script ou um binário?
6117 Mikel
ls -l / proc / 3084 / exe nos dálrwxrwxrwx 1 root root 0 Jun 6 16:49 /proc/3084/exe -> /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek
O ls -l / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr me fornece-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Radek
tipo me / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr/var/lib/db2/db2inst1/sqllib/adm/db2syscr is /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek
6

O killall tenta corresponder ao nome de um processo (mas não é realmente tão bom na parte correspondente).

E como "ps | grep" e "ps | grep | kill" fazem um trabalho muito melhor, alguém simplificou isso e criou pgrep e pkill. Leia os comandos como "ps grep" e "ps kill", pois esse comando primeiro ps depois grep e, se desejado, mata.

Johan
fonte
2

Eu tive um problema semelhante, mas /proc/<pid>/statcontinha a string esperada. Usando strace, pude ver que o killall também acessava /proc/<pid>/cmdline.

I continuou a investigar usando gdb para descobrir que no meu caso ele falhou em um cheque 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 fonte do killall). Eu não investiguei completamente se eu poderia de alguma forma fazê-lo funcionar com killall.

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

O código fonte pkillpode ser encontrado aqui https://github.com/acg/psmisc para os interessados.

Zitrax
fonte
0

Nos sistemas Ubuntu 16, o / proc / pid / stat conterá o nome do thread (que um programa pode via pthread_setname_np ).

gerardw
fonte