Intereting Posts

killall дает мне «никакого процесса найдено», но ps

Может ли кто-нибудь объяснить мне разницу между kill и kill ? Почему 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 

Системой является SuSe 11.3 (64 бит); ядро 2.6.34-12; procps версия 3.2.8; killall от PSmisc 22.7; убить из GNU coreutils 7.1

Это на 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 и захватывает второе слово между parens как имя команды, так что это действительно то, что вам нужно указать при запуске killall . Логично, что это должно быть то же самое, что и ps без флага u , но было бы неплохо проверить.

Что нужно проверить:

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

Заметки

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

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

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

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

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

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

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

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