killall daje mi „nie znaleziono procesu” oprócz ps

17

Czy ktoś mógłby mi wyjaśnić różnicę między killi killall? Dlaczego nie killallwidzi tego ps, co pokazuje?

# 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

System to SuSe 11.3 (64-bitowy); jądro 2.6.34-12; procps wersja 3.2.8; killall z PSmisc 22.7; zabij z GNU coreutils 7.1

Radek
źródło
Nigdy nie zabijaj procesów za pomocą SIGKILL (-9).
vonbrand
Co zrobić, gdy proces musi zostać zakończony?
Radek
To jest ostatnia deska ratunku.
vonbrand

Odpowiedzi:

19

Czy to na Linuksie?

Istnieje rzeczywiście mało subtelnie różne wersje nazwy poleceń, które są wykorzystywane przez ps, killallitd

Dwa główne warianty to: 1) długa nazwa polecenia, którą otrzymujesz po uruchomieniu ps u; oraz 2) krótka nazwa polecenia, którą otrzymujesz, gdy biegniesz psbez żadnych flag.

Prawdopodobnie największa różnica zdarza się, jeśli twój program jest skryptem powłoki lub czymkolwiek wymagającym interpretera, np. Python, Java itp.

Oto naprawdę trywialny skrypt, który pokazuje różnicę. Nazwałem to mycat:

#!/bin/sh
cat

Po uruchomieniu, oto dwa różne typy ps.

Po pierwsze bez u:

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

Po drugie, z u:

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

Zauważ, jak zaczyna się druga wersja /bin/sh?

Teraz, o ile mogę powiedzieć, killallfaktycznie czyta /proc/<pid>/stati chwyta drugie słowo pomiędzy parens jako nazwę polecenia, więc tak naprawdę musisz określić, kiedy biegniesz killall. Logicznie rzecz biorąc, powinno to być to samo, co napisane psbez uflagi, ale dobrze byłoby sprawdzić.

Rzeczy do sprawdzenia:

  1. co oznacza cat /proc/<pid>/statnazwa polecenia?
  2. co oznacza ps -e | grep db2nazwa polecenia?
  3. zrobić ps -e | grep db2i ps au | grep db2pokazać tę samą nazwę polecenia?

Notatki

Jeśli używasz także innych flag ps, możesz łatwiej użyć ps -o commkrótkiej nazwy i ps -o cmddługiej nazwy.

Możesz także znaleźć pkilllepszą alternatywę. W szczególności pkill -fpróbuje dopasować przy użyciu pełnej nazwy polecenia, tj. Nazwy polecenia wydrukowanej przez ps ulub ps -o cmd.

Mikel
źródło
bardzo dobre wytłumaczenie. I myślę, że miałeś rację za pierwszym razem. ps -e |grep db2 gives me 3084? 00:00:00 db2syscr` i ps aux | grep db2 daje mi root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd. Mógłby to skomentować. Jestem trochę zagubiony.
Radek
Nie jestem pewny. Możliwe, że program zmienia nazwę. Czy wiesz jak to działa? Co ls -l /proc/3084/exemówi Co whichlub whencelub type, aby znaleźć plik, a następnie lsi typezobaczyć czy jest to dowiązanie lub skrypt lub binarny?
Mikel
ls -l / proc / 3084 / exe daje namlrwxrwxrwx 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 daje mi-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Radek
typ daje mi / var / lib / db2 / db2inst1 / sqllib / adm / db2syscraper/var/lib/db2/db2inst1/sqllib/adm/db2syscr is /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek
6

killall próbuje dopasować nazwę procesu (ale nie jest tak dobra w dopasowywanej części).

A ponieważ „ps | grep” i „ps | grep | kill” wykonują znacznie lepszą robotę, ktoś uprościł to i stworzył pgrep i pkill. Przeczytaj te polecenia, takie jak „ps grep” i „ps kill”, ponieważ to polecenie ps najpierw grep, a jeśli chcesz zabija.

Johan
źródło
2

Miałem podobny problem, ale /proc/<pid>/statzawierałem oczekiwany ciąg. Korzystając ze strace, mogłem zobaczyć, że killall również miał dostęp /proc/<pid>/cmdline.

Kontynuowałem badanie za pomocą gdb, aby stwierdzić, że w moim przypadku nie udało się sprawdzić mojej komendy do pełnej komendy, w tym wszystkich znalezionych argumentów /proc/<pid>/cmdline. Wyglądało na to, że ta ścieżka kodu została uruchomiona, ponieważ nazwa pliku jest dłuższa niż 15 znaków (co jest zakodowaną wartością w źródle killall). Nie w pełni zbadałem, czy uda mi się w jakiś sposób zmusić go do współpracy z killall.

Ale jak wspomniano w innych komentarzach, pkill jest lepszą alternatywą, która nie ma tych samych problemów.

Kod źródłowy pkillmożna znaleźć tutaj https://github.com/acg/psmisc dla zainteresowanych.

Zitrax
źródło
0

W systemach Ubuntu 16 / proc / pid / stat będzie zawierał nazwę wątku (który program może wykonać poprzez wywołanie systemowe pthread_setname_np .

gerardw
źródło