killall me da "no se encontró ningún proceso" pero

17

¿Podría alguien explicarme la diferencia entre killy killall? ¿Por qué no killallve lo que psmuestra?

# 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

El sistema es SuSe 11.3 (64 bit); núcleo 2.6.34-12; procps versión 3.2.8; killall de PSmisc 22.7; matar desde GNU coreutils 7.1

Radek
fuente
Nunca elimine procesos con SIGKILL (-9).
vonbrand
¿Qué hacer entonces cuando un proceso necesita ser terminado?
Radek el
Este es el último recurso.
vonbrand

Respuestas:

19

¿Está esto en Linux?

En realidad, hay algunas versiones ligeramente diferentes del nombre del comando que son utilizados por ps, killall, etc.

Las dos variantes principales son: 1) el nombre de comando largo, que es lo que obtienes cuando corres ps u; y 2) el nombre corto del comando, que es lo que obtienes cuando corres pssin ningún indicador.

Probablemente la mayor diferencia ocurre si su programa es un script de shell o cualquier cosa que requiera un intérprete, por ejemplo, Python, Java, etc.

Aquí hay un script realmente trivial que demuestra la diferencia. Lo llamé mycat:

#!/bin/sh
cat

Después de ejecutarlo, aquí están los dos tipos diferentes de ps.

Primero, sin u:

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

En segundo lugar, con u:

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

¿Observa cómo comienza la segunda versión /bin/sh?

Ahora, por lo que puedo decir, en killallrealidad lee /proc/<pid>/staty toma la segunda palabra entre los parens como el nombre del comando, así que eso es realmente lo que necesitas especificar cuando corres killall. Lógicamente, eso debería ser lo mismo que dice psla ubandera, pero sería una buena idea verificarlo.

Cosas para verificar:

  1. ¿Qué cat /proc/<pid>/statdice el nombre del comando?
  2. ¿Qué ps -e | grep db2dice el nombre del comando?
  3. hacer ps -e | grep db2y ps au | grep db2mostrar el mismo nombre de comando?

Notas

Si también está utilizando otros indicadores ps, puede que le resulte más fácil de usar ps -o commpara ver el nombre corto y ps -o cmdel nombre largo.

También puede encontrar pkilluna mejor alternativa. En particular, pkill -fintenta hacer coincidir usando el nombre completo del comando, es decir, el nombre del comando tal como se imprime con ps uo ps -o cmd.

Mikel
fuente
Muy buena explicación. Y supongo que tenías razón la primera vez. ps -e |grep db2 gives me 3084? 00:00:00 db2syscr` y ps aux | grep db2 me da root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd. Podría comentar sobre eso. Estoy un poco perdido
Radek
No estoy seguro. Es posible que el programa esté cambiando su nombre. ¿Sabes cómo se está ejecutando? Que ls -l /proc/3084/exedice ¿Qué pasa con whicho whenceo typepara buscar el archivo y, a continuación ls, y typepara ver si es un enlace simbólico o una secuencia de comandos o un archivo binario?
Mikel
ls -l / proc / 3084 / exe nos dalrwxrwxrwx 1 root root 0 Jun 6 16:49 /proc/3084/exe -> /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek
ls -l / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr me da-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Radek
type me da / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr/var/lib/db2/db2inst1/sqllib/adm/db2syscr is /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek
6

killall intenta hacer coincidir el nombre de un proceso (pero en realidad no es tan bueno en la parte correspondiente).

Y como "ps | grep" y "ps | grep | kill" funcionan mucho mejor, alguien simplificó esto y creó pgrep y pkill. Lea los comandos como "ps grep" y "ps kill", ya que ese comando primero ps luego grep y si lo desea mata.

Johan
fuente
2

Tuve un problema similar pero /proc/<pid>/statcontenía la cadena esperada. Al usar strace pude ver que Killall también accedió /proc/<pid>/cmdline.

Continué investigando usando gdb para encontrar que en mi caso falló en una verificación de mi comando al comando completo, incluidos todos los args encontrados /proc/<pid>/cmdline. Parecía que esa ruta del código se activó debido a que el nombre del archivo tenía más de 15 caracteres (que es un valor codificado en la fuente de killall). No investigué completamente si de alguna manera podría hacer que funcionara con killall.

Pero como se menciona en otros comentarios aquí, pkill es una mejor alternativa que no tiene los mismos problemas.

El código fuente de pkillse puede encontrar aquí https://github.com/acg/psmisc para los interesados.

Zitrax
fuente
0

En los sistemas Ubuntu 16, / proc / pid / stat contendrá el nombre del hilo (que un programa puede llamar a través del sistema pthread_setname_np ).

gerardw
fuente