killall дает мне "процесс не найден", но PS

17

Может ли кто-нибудь объяснить мне разницу между killи killall? Почему не killallвидит, что psпоказывает?

# 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

Система соответствует требованиям 11,3 (64 бита); ядро 2.6.34-12; procps версия 3.2.8; killall от PSmisc 22,7; убить из GNU coreutils 7.1

Радек
источник
Никогда не убивайте процессы с помощью SIGKILL (-9).
vonbrand
Что делать тогда, когда процесс должен быть остановлен?
Радек
Это очень, очень последнее средство.
vonbrand

Ответы:

19

Это на Linux?

Есть на самом деле несколько тонко разные варианты названия команды, которые используются ps, killallи т.д.

Два основных варианта: 1) длинное имя команды, которое вы получаете при запуске ps u; и 2) короткое имя команды, которое вы получаете, когда запускаете psбез каких-либо флагов.

Вероятно, самое большое различие происходит, если ваша программа представляет собой скрипт оболочки или что-то, что требует интерпретатора, например, Python, Java и т. Д.

Вот действительно тривиальный скрипт, который демонстрирует разницу. Я назвал это mycat:

#!/bin/sh
cat

После запуска, вот два разных типа ps.

Во-первых, без u:

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

Во-вторых, с u:

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

Обратите внимание, как начинается вторая версия /bin/sh?

Теперь, насколько я могу судить, на killallсамом деле читает /proc/<pid>/statи берет второе слово между скобками в качестве имени команды, так что это действительно то, что вам нужно указать при запуске killall. Логично, что это должно быть то же, что и psбез uфлага, но было бы неплохо проверить.

Вещи, чтобы проверить:

  1. что cat /proc/<pid>/statговорит имя команды?
  2. что ps -e | grep db2говорит имя команды?
  3. сделать ps -e | grep db2и ps au | grep db2показать одно и то же имя команды?

Примечания

Если вы используете и другие флаги ps, вам может быть проще использовать его ps -o commдля просмотра короткого имени и ps -o cmdдлинного имени.

Вы также можете найти pkillлучшую альтернативу. В частности, pkill -fпытается сопоставить, используя полное имя команды, то есть имя команды, напечатанное с помощью ps uили ps -o cmd.

Mikel
источник
очень хорошее объяснение. И я думаю, вы были правы в первый раз. ps -e |grep db2 gives me 3084? 00:00:00 db2syscr` и ps aux | grep db2 дают мне root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd. Мог бы прокомментировать это. Я немного потерян.
Радек
Я не уверен. Возможно, что программа меняет свое название. Вы знаете, как это работает? Что ls -l /proc/3084/exeговорит? А что whichили whenceили typeнайти файл , а затем lsи typeувидеть , если это символическая или скрипт или двоичный?
Микель
ls -l / proc / 3084 / exe дает намlrwxrwxrwx 1 root root 0 Jun 6 16:49 /proc/3084/exe -> /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Радек
ls -l / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr дает мне-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Радек
тип дает мне / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr/var/lib/db2/db2inst1/sqllib/adm/db2syscr is /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Радек
6

killall пытается сопоставить имя процесса (но на самом деле это не так хорошо в соответствующей части).

А поскольку «ps | grep» и «ps | grep | kill» работают намного лучше, кто-то упростил это и создал pgrep и pkill. Прочитайте такие команды, как «ps grep» и «ps kill», так как эта команда сначала «ps», затем «grep» и, если нужно, «убивает».

Johan
источник
2

У меня была похожая проблема, но она /proc/<pid>/statсодержала ожидаемую строку. Используя strace, я мог видеть, что killall также доступен /proc/<pid>/cmdline.

Я продолжил исследовать использование gdb, чтобы обнаружить, что в моем случае он не прошел проверку моей команды до полной команды, включая все найденные аргументы /proc/<pid>/cmdline. Казалось, что этот путь к коду запускается из-за того, что имя файла длиннее 15 символов (что является жестко заданным значением в источнике killall). Я не до конца исследовал, смогу ли я заставить его работать с killall.

Но, как уже упоминалось в других комментариях, pkill - лучшая альтернатива, у которой нет тех же проблем.

Исходный код pkillможет быть найден здесь https://github.com/acg/psmisc для заинтересованных.

Zitrax
источник
0

В системах Ubuntu 16 / proc / pid / stat будет содержать имя потока (что может сделать программа через системный вызов pthread_setname_np) .

gerardw
источник