Zabij wiele instancji uruchomionego procesu za pomocą jednego polecenia

75

Załóżmy, że mam uruchomionych tysiąc lub więcej instancji dowolnego procesu (na przykład vi). Jak zabić ich wszystkich za pomocą jednego strzału / jednej linii / jednej komendy?

Mroczny rycerz
źródło
3
Nie jest jasne, jakie systemy mają działać. Na przykład w systemie Linux używam pkillz procpspakietu.
Deer Hunter
Pytanie zostało zadane z ogólnego punktu widzenia. Znałem tylko dwa procesy, takie jak killall i przez awk / sed. Chciałem jednak wiedzieć, czy istnieją inne sposoby osiągnięcia tego celu. Jeśli robi się inaczej w różnych systemach, chcę wiedzieć, w którym. Google jest bardzo kłopotliwy, zamiast tego pomyślałem o rozmowie ze wszystkimi doświadczonymi facetami.
Mroczny rycerz

Odpowiedzi:

97

Co jest nie tak z dobrym starym

for pid in $(ps -ef | grep "some search" | awk '{print $2}'); do kill -9 $pid; done

Istnieją sposoby na zwiększenie wydajności,

for pid in $(ps -ef | awk '/some search/ {print $2}'); do kill -9 $pid; done

i inne odmiany, ale na poziomie podstawowym zawsze mi się to udawało.

EightBitTony
źródło
1
Up głosował, wiedział tylko o pierwszej odmianie. Drugi wygląda bardziej wydajnie, dziękuję.
Mroczny rycerz
5
@TheDarkKnight Problem z tą metodą polega na tym, że często zabijasz więcej, niż zamierzałeś. Pisanie wiarygodnego „jakiegoś wyszukiwania” jest trudne. W systemie Linux użyj pkill , który obsługuje większość subtelności.
Gilles,
Nie jestem pewien, czy to takie trudne, jeśli szukasz konkretnego pliku binarnego, może być całkiem niezawodny. Zawsze uruchamiam go jako echo kill -9 $pidpierwszy, więc wiem, co otrzymuję. Nie jestem pewien, czy AIX ma pkill, czyli mój unikatowy chleb i masło. I czy naprawdę jest wystarczająco źle, aby zostać odrzuconym - dziwne.
EightBitTony
1
O ile nie jest to absolutnie konieczne, należy wysłać proces SIGTERM zamiast SIGKILL.
Powinienem dodać, że te 2 metody nie będą działały we wszystkich powłokach, na przykład nie będą działaćcsh
non-sequitor
38

Użyj killall,

killall vi

To zabije wszystkie polecenia o nazwie „vi”

Możesz również dodać sygnał, np. SIGKILL

killall -9 vi

stokrotka
źródło
Zgadza się, możesz również dodać żądany sygnał, na przykładkillall -9 vi
Hola Soy Edu Feliz Navidad,
1
Nie sądzę, że killall jest do tego namacalny: zabijanie przez plik działa tylko dla plików wykonywalnych, które są otwarte podczas wykonywania, tj. Nieczyste pliki wykonywalne nie mogą zostać zabite w ten sposób. Wpisanie nazwy killall może nie przynieść pożądanego efektu w systemach innych niż Linux, zwłaszcza gdy jest wykonywane przez uprzywilejowanego użytkownika. Co zrobić, jeśli próbuję usunąć wiele instancji niektórych procesów innych niż Linux? killall -w nie wykrywa, czy proces znika i jest zastępowany nowym procesem z tym samym PID między skanami. Jeśli procesy zmienią swoją nazwę, killall może nie być w stanie dopasować ich poprawnie.
The Dark Knight
13
Należy pamiętać, że działa to tylko w systemach Linux i BSD. W systemie Solaris i niektórych innych systemach killallrobi dokładnie to, co sugeruje nazwa ... zabija proces inicjowania.
Bobby,
2
W systemie AIX „anuluje wszystkie uruchomione procesy, z wyjątkiem tych, które powodują proces killall”.
EightBitTony
31

pkillpolecam, jeśli jest dostępny ( Linux , FreeBSD , NetBSD , OpenBSD , Solaris ). Można określić procesy według nazwy polecenia, pełnego wiersza polecenia lub innych kryteriów. Na przykład pkill vizabija wszystkie programy, których nazwa polecenia zawiera podłańcuch vi. Aby zabić tylko wywoływane procesy vi, użyj pkill -x vi. Aby zabić tylko procesy wywoływane viz ostatnim argumentem kończącym się na .conf, użyj pkill -fx 'vi.*\.conf'.

Aby zobaczyć listę PID, na pkillktóre wysyłany byłby sygnał, użyj pgrep, który ma dokładnie taką samą składnię, z tym wyjątkiem, że nie przyjmuje nazwy lub numeru sygnału. Aby zobaczyć więcej informacji o tych procesach, uruchom

ps -p "$(pgrep …)"

Pod Linuksem potrzebujesz ps -p $(pgrep -d, …)zamiast tego (to błąd: Linux psnie jest zgodny z POSIX).

Innym powszechnym sposobem identyfikacji procesów do zabicia są procesy, które mają otwarty plik (który może być wykonywalny). Możesz je wymienić za pomocą fuser; użyj, fuser -kaby wysłać im sygnał. Na przykład fuser -k /usr/bin/findzabija wszystkie uruchomione liczby find.

Jeśli istnieje niekontrolowany proces, który wciąż się rozwidla, być może trzeba zabić całą grupę procesów naraz. Grupa procesów jest identyfikowana przez negatyw jej lidera, który jest procesem przodka wszystkich procesów w grupie. Aby zobaczyć grupę procesów, do której należy proces, uruchom ps -o pgid(plus dowolną opcję, aby wybrać proces (y) do wyświetlenia). Jeśli stwierdzisz, że chcesz zabić lidera grupy procesowej 1234 i wszystkie jego elementy potomne, uruchom kill -1234lub kill -HUP -1234inny sygnał.

Jeśli nie możesz znaleźć lepszego sposobu, użyj psz odpowiednimi opcjami, aby wyświetlić listę wszystkich procesów i przefiltrować go za pomocą grepinnego polecenia filtrowania tekstu. Uważaj, aby przypadkowo nie dopasować innych procesów uruchamiających polecenie o podobnej nazwie lub z argumentem zawierającym tę nazwę. Na przykład:

kill $(ps -o pid -o comm | awk '$2 == "vi" {print $1}')

Pamiętaj, że twoje polecenie greplub awksamo polecenie może być wymienione w danych pswyjściowych ( psa polecenie filtrowania jest uruchamiane równolegle, więc to, czy się pojawi, zależy od czasu). Jest to szczególnie ważne, jeśli argumenty polecenia są zawarte w danych pswyjściowych.

Gilles
źródło
Wielkie dzięki, to jest naprawdę niesamowite. To, co dałeś, jest rodzajem samouczka. Dzięki jeszcze raz . W głosowaniu
The Dark Knight
6

pkilljest tu bardzo miło. Możesz podać wiele parametrów w celu dopracowania wzoru.

Nils
źródło
Nie jest dostępny we wszystkich systemach UNIX i nie wspomina o konkretnym systemie UNIX ani systemie podobnym do UNIX w pytaniu.
EightBitTony
@EightBitTony pkilljest dostępny na Linux, BSD i Solaris - afaik. Ma więc większy zasięg niż killall.
Nils,
Zgadzam się, ale killall jest jeszcze bardziej problematyczny, ponieważ istnieje wiele narzędzi o tej samej nazwie, które wyglądają zupełnie inaczej. Nie lubię też odpowiedzi typu killall. pkill nie istnieje w systemie AIX lub HP-UX i pomimo tego, co niektórzy lubią wierzyć, nadal istnieje znaczna część systemu UNIX innego niż Linux na świecie.
EightBitTony,
1
@EightBitTony, dlatego twoja odpowiedź jest zaakceptowana. Ale nie używałbym tego na Solarisie (który także jest Uniksem).
Nils
6

Najłatwiejszym sposobem jest sprawdzenie, czy otrzymujesz właściwe identyfikatory procesów za pomocą:

pgrep -f [part_of_a_command]

Jeśli wynik jest zgodny z oczekiwaniami. Iść z:

pkill -f [part_of_a_command]
Tahsin Turkoz
źródło
lub użyj:pgrep -f "command name"
Magne
3

Ciekawe, nikt o tym nie wspominał. pidof generuje oddzielone spacjami pidy procesów pasujące do nazwy przekazanego procesu. Jako taki, możesz bezpośrednio użyć jego wyjścia killbez orurowania. Na Arch Linux używam

kill -9 $(pidof <proc name>)

Wadą tego rozwiązania jest to, że nie pozwala ono na użycie wyrażeń regularnych.

sherrellbc
źródło
0

Proponuję ci spróbować pkill.

Dawny: ps -ef | pkill -f command

Aby wyświetlić listę wszystkich procesów, które mają zostać zabite, najpierw spróbuj pgrep:

Dawny: ps -ef | pgrep -f command

Ankit Vashistha
źródło
1
Jaki jest cel przesyłania danych wyjściowych ps -efdo pkilllub pgrep? Te polecenia nie odczytują ze standardowego wejścia.
Kusalananda
0

Możesz zabić wiele różnych procesów za pomocą poniższego polecenia

pkill -9 -f "\.\/.+\s\.|process1|process2|process3\[^"

Zauważ, że to zabije proces zgodny z powyższym wzorcem, co oznacza, process1abc process2def process3ghiże również zostanie zabity.

SandPox
źródło
-1

pgrep "name-of-application" | xargs kill -9

Był wystarczająco prosty do zapamiętania i działał dla mnie ładnie.

Horv
źródło
-2
$ ps -eaf  | grep "xyz" | grep -v grep | awk 'print $2' | xargs kill
użytkownik110509
źródło
-2
ps -ef | pgrep -f "search" | xargs kill -9  
Avijit Dhar
źródło