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

Система - SuSe 11.3 (64 біт); ядро 2.6.34-12; Props версія 3.2.8; кіллалл від PSmisc 22.7; вбити з GNU coreutils 7.1


Ніколи не вбивайте процеси за допомогою SIGKILL (-9).
фонбранд

Що робити тоді, коли процес потрібно припинити?
Радек

Це сама, сама остання інстанція.
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.


дуже хороше пояснення. І я здогадуюсь, ти був правий перший раз. 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
Radek

6

killall намагається узгодити ім'я процесу (але це не дуже добре в частині, що відповідає).

А оскільки "ps | grep" та "ps | grep | kill" роблять набагато кращу роботу, хтось спростив це та створив pgrep та pkill. Прочитайте, що такі команди, як "ps grep" і "ps kill", оскільки ця команда спочатку ps потім grep і, якщо хотіли, вбиває.


2

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

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

Але, як згадувалося в інших коментарях, тут pkill є кращою альтернативою, яка не має однакових проблем.

Вихідний код pkillможна знайти тут https://github.com/acg/psmisc для зацікавлених.


0

В системах Ubuntu 16 / proc / pid / stat буде містити ім'я потоку (яке програма може за допомогою системного виклику pthread_setname_np .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.