Вбийте багато екземплярів запущеного процесу за допомогою однієї команди


75

Припустимо, у мене є тисяча або більше примірників будь-якого процесу (наприклад, vi), що працює. Як я вбиваю їх усіх за один постріл / одну команду рядка / одну команду?


3
Незрозуміло, для яких систем ви плануєте це працювати. Наприклад, на Linux я використовую pkillз procpsпакету.
Мисливець на оленів

Питання було задано із загальної точки зору. Я знав лише два процеси, такі як киллалл і через awk / sed. Але мені хотілося знати, чи існують інші способи досягнення цього. Якщо це по-різному робиться в різних системах, то я хочу знати, що в чому. Google дуже громіздкий, натомість я думав обговорювати з усіма вами досвідчені хлопці.
Темний лицар

Відповіді:


97

Що не так з добрим старим,

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

Є способи зробити це більш ефективним,

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

та інші варіанти, але на базовому рівні це завжди працює для мене.


1
Вгору проголосували, знали лише першу варіацію. Друга виглядає більш ефективно, дякую.
Темний лицар

5
@TheDarkKnight Проблема цього методу полягає в тому, що ви часто в кінці вбиваєте більше, ніж ви планували. Написати надійний "деякий пошук" - складне. У Linux використовуйте pkill , який обробляє більшість тонкощів.
Жиль

Я не впевнений, що це так складно, якщо ви користуєтеся певним бінарним файлом, це може бути досить надійним. Я завжди запускаю це як echo kill -9 $pidперше, так що я знаю, що отримую. Я не впевнений, що AIX має pkill, це мій хліб і масло UNIX. І чи справді це досить погано, щоб бути голосованим - дивним.
EightBitTony

1
Якщо це абсолютно не потрібно, вам слід надіслати процес SIGTERM замість SIGKILL.

Додам, що ці 2 методи не працюватимуть у всіх оболонках, наприклад, він не працюватимеcsh
не послідовник,

38

Використовуйте killall,

killall vi

Це вб'є всю команду під назвою "vi"

Ви також можете додати сигнал, наприклад, SIGKILL

killall -9 vi


Правильно, ви також можете додати потрібний сигнал, як-отkillall -9 vi
Hola Soy Edu Feliz Navidad

1
Я не думаю, що killall є його значущим: Killing by file працює лише для виконуваних файлів, які залишаються відкритими під час виконання, тобто нечисті виконавчі файли не можуть бути вбиті таким чином. Введення імені killall може не мати бажаного ефекту для не-Linux систем, особливо коли це робиться привілейованим користувачем. Що робити, якщо я намагаюся видалити безліч примірників якогось нелінукс-процесу? killall -w не визначає, чи зникає процес, і замінюється новим процесом з тим самим PID між скануваннями. Якщо процеси змінять свою назву, killall може не вдаватися до них правильно.
Темний лицар

13
Зауважте, що це працює лише на Linux та BSD. У Solaris та деяких інших системах killallвідбувається саме те, що підказує назва ... це вбиває init-процес.
Боббі

2
У AIX він "скасовує всі запущені процеси, крім тих, що виробляють процес killall."
EightBitTony

31

pkillце те, що я рекомендую, якщо він доступний ( Linux , FreeBSD , NetBSD , OpenBSD , Solaris ). Ви можете вказати процеси за назвою команди, повним командним рядком або іншими критеріями. Наприклад, pkill viвбиває всі програми, ім'я команди яких містить підрядку vi. Щоб вбити лише викликані процеси vi, використовуйте pkill -x vi. Щоб вбити лише процеси, викликані viостаннім аргументом, що закінчується .conf, використовуйте pkill -fx 'vi.*\.conf'.

Щоб побачити список PID, на які pkillбуде відправлено сигнал, використовуйте pgrep, який має абсолютно той самий синтаксис, за винятком того, що він не приймає ім'я або номер сигналу. Щоб побачити більше інформації про ці процеси, запустіть

ps -p "$(pgrep …)"

Під Linux вам потрібно ps -p $(pgrep -d, …)замість цього (це помилка: Linux psне підтримує POSIX).

Ще один поширений спосіб ідентифікації процесів вбивства - це процеси, у яких відкритий певний файл (який може бути виконуваним). Ви можете перелічити їх за допомогою fuser; використовувати fuser -kдля надсилання їм сигналу. Наприклад, fuser -k /usr/bin/findвбиває всі запущені випадки find.

Якщо є відвертий процес, який продовжує розвантажувати, можливо, вам потрібно буде вбити всю групу процесу одразу. Процесна група ідентифікується за негативом її лідера, який є процесом предків усіх процесів у групі. Щоб побачити групу процесів, до якої належить процес, запустіть ps -o pgid(плюс будь-яку опцію, щоб вибрати, який процес (и) відображати). Якщо ви вирішили , що ви хочете , щоб вбити лідера тисячі двісті тридцять чотири групи процесів і всіх його нащадків, запускати kill -1234або kill -HUP -1234будь-якої іншої сигнал.

Якщо ви не можете знайти кращого способу, скористайтеся psправильними параметрами, щоб перелічити всі процеси та відфільтрувати їх за допомогою grepбудь-якої іншої команди фільтрації тексту. Слідкуйте за тим, щоб випадково не співставити інші процеси, які, як правило, виконують команду з подібним іменем або з аргументом, який містить це ім'я. Наприклад:

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

Пам'ятайте, що ваша команда grepабо awkсама команда може бути вказана у psвисновку ( psа команда фільтрації запускається паралельно, тож відображатиметься вона чи ні, це залежить від часу). Це особливо важливо, якщо аргументи команд включені у psвисновок.


Велике спасибі, це справді приголомшливо. Те, що ви дали, - це свого роду підручник. Знову дякую . Вгору проголосували
Темний лицар

6

pkillтут дуже приємно. Ви можете надати йому безліч параметрів для вдосконалення структури.


Доступно не для всіх UNIX, і жодна згадка про конкретну UNIX або UNIX-подібну ОС у питанні.
EightBitTony

@EightBitTony pkillдоступний на Linux, BSD та Solaris - afaik. Тож воно має більший розкид, ніж killall.
Нілс

Я погоджуюся, але killall є ще більш проблематичним, оскільки існує кілька інструментів з однаковою назвою, які мають різну поведінку, як би здавалося. Мені також не подобаються відповіді кілла. pkill не існує на AIX або HP-UX, і незважаючи на те, що людям подобається вірити, у світі все ще існує значна історія, що не є Linux Linux.
EightBitTony

1
@EightBitTony, тому ваша відповідь є прийнятою. Але я б не використовував його на Solaris (що теж Unix).
Нілс

6

Найпростіший спосіб - це спочатку перевірити, чи ви отримуєте правильні ідентифікатори процесу за допомогою:

pgrep -f [part_of_a_command]

Якщо результат такий, як очікувалося. Супроводжувати:

pkill -f [part_of_a_command]

або скористайтеся:pgrep -f "command name"
Магне

3

Цікаво про це ніхто не згадував. pidof виводить відокремлені пробілами під-процеси процесів, що відповідають імені переданого процесу. Таким чином, ви можете безпосередньо використовувати його вихід killбез трубопроводів. У Arch Linux я використовую

kill -9 $(pidof <proc name>)

Мінусом цього рішення є те, що він не дозволяє використовувати регулярні вирази.


0

Я б запропонував вам спробувати pkill.

Наприклад: ps -ef | pkill -f command

Щоб показати список усіх процесів, які потрібно вбити, спершу спробуйте pgrep:

Наприклад: ps -ef | pgrep -f command


1
Яка мета трубопроводу виходу ps -efв pkillабо pgrep? Ці команди не читаються зі стандартного вводу.
Kusalananda

0

Можна вбити кілька різних процесів, скориставшись командою нижче

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

Зауважте, що це знищить процес, що відповідає вищевказаній схемі, значить process1abc process2def process3ghi, також буде вбито.


-1

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

Був досить простим, щоб запам'ятати і добре працював для мене.



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