killall me donne `aucun processus trouvé` mais ps

17

Quelqu'un pourrait-il m'expliquer la différence entre killet killall? Pourquoi ne killallvoit pas ce que psmontre?

# 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

Le système est SuSe 11.3 (64 bits); noyau 2.6.34-12; procps version 3.2.8; killall de PSmisc 22.7; tuer de GNU coreutils 7.1

Radek
la source
Ne tuez jamais les processus avec SIGKILL (-9).
vonbrand
Que faire alors lorsqu'un processus doit se terminer?
Radek
C'est le tout dernier recours.
vonbrand

Réponses:

19

Est-ce sur Linux?

Il y a en fait quelques versions légèrement différentes du nom de la commande qui sont utilisés par ps, killall, etc.

Les deux variantes principales sont: 1) le nom de la commande longue, qui est ce que vous obtenez lorsque vous exécutez ps u; et 2) le nom de commande court, qui est ce que vous obtenez lorsque vous exécutez pssans aucun indicateur.

La plus grande différence se produit probablement si votre programme est un script shell ou tout ce qui nécessite un interprète, par exemple Python, Java, etc.

Voici un script vraiment trivial qui montre la différence. Je l'ai appelé mycat:

#!/bin/sh
cat

Après l'avoir exécuté, voici les deux types différents de ps.

Premièrement, sans u:

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

Deuxièmement, avec u:

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

Notez comment commence la deuxième version /bin/sh?

Maintenant, pour autant que je sache, killalllit /proc/<pid>/statet saisit le deuxième mot entre les parens comme nom de commande, c'est donc vraiment ce que vous devez spécifier lorsque vous exécutez killall. Logiquement, cela devrait être la même chose que pssans le udrapeau, mais ce serait une bonne idée de vérifier.

A vérifier:

  1. que cat /proc/<pid>/statdit le nom de la commande?
  2. que ps -e | grep db2dit le nom de la commande?
  3. faire ps -e | grep db2et ps au | grep db2afficher le même nom de commande?

Remarques

Si vous utilisez également d'autres indicateurs ps, vous pouvez trouver plus simple à utiliser ps -o commpour voir le nom court et ps -o cmdvoir le nom long.

Vous pourriez également trouver pkillune meilleure alternative. En particulier, pkill -fessaie de faire correspondre le nom de commande complet, c'est-à-dire le nom de commande tel qu'imprimé par ps uou ps -o cmd.

Mikel
la source
très bonne explication. Et je suppose que vous aviez raison la première fois. ps -e |grep db2 gives me 3084? 00:00:00 db2syscr` et ps aux | grep db2 me donne root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd. Pourrait commenter cela. Je suis un peu perdu.
Radek
Je ne suis pas sûr. Il est possible que le programme change de nom. Savez-vous comment cela fonctionne? Que ls -l /proc/3084/exedit-on? Qu'en est-il de whichou whenceou typepour trouver le fichier et ensuite lset typepour voir s'il s'agit d'un lien symbolique ou d'un script ou d'un binaire?
Mikel
ls -l / proc / 3084 / exe nous donnelrwxrwxrwx 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 donne-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Radek
type me donne / 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 essaie de faire correspondre un nom de processus (mais n'est pas vraiment bon pour la partie correspondante).

Et puisque "ps | grep" et "ps | grep | kill" font un bien meilleur travail, quelqu'un a simplifié cela et a créé pgrep et pkill. Lisez ces commandes comme "ps grep" et "ps kill", puisque cette commande commence par ps puis grep et si vous le souhaitez, tue.

Johan
la source
2

J'ai eu un problème similaire mais /proc/<pid>/statcontenait la chaîne attendue. En utilisant strace, j'ai pu voir que killall avait également accès /proc/<pid>/cmdline.

J'ai continué d'enquêter en utilisant gdb pour découvrir que dans mon cas, il avait échoué lors d'une vérification de ma commande à la commande complète, y compris tous les arguments trouvés dans /proc/<pid>/cmdline. Il semblait que ce chemin du code se soit déclenché car le nom de fichier dépassait 15 caractères (ce qui est une valeur codée en dur dans la source de killall). Je n'ai pas cherché à savoir si je pouvais le faire fonctionner avec killall.

Mais comme mentionné dans d'autres commentaires ici, pkill est une meilleure alternative qui n'a pas les mêmes problèmes.

Le code source de pkillpeut être trouvé ici https://github.com/acg/psmisc pour les personnes intéressées.

Zitrax
la source
0

Sur les systèmes Ubuntu 16, / proc / pid / stat contiendra le nom du thread (qu'un programme peut utiliser via l' appel système pthread_setname_np .

gerardw
la source