Убить много экземпляров запущенного процесса одной командой


75

Предположим, у меня есть тысяча или более экземпляров любого viзапущенного процесса (например, ). Как убить их всех одним выстрелом / одной строкой / одной командой?


3
Неясно, для каких систем вы намерены это работать. Например, в Linux я использую pkillиз procpsпакета.
Охотник на оленей

Вопрос был задан с общей точки зрения. Я знал только о двух процессах, таких как killall и через 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
не sequitor

38

Используйте killall,

killall vi

Это убьет все команды с именем 'vi'

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

killall -9 vi


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

1
Я не думаю, что killall является насущным для него: уничтожение по файлу работает только для исполняемых файлов, которые остаются открытыми во время выполнения, то есть нечистые исполняемые файлы не могут быть уничтожены таким образом. Ввод имени killall может не иметь желаемого эффекта в системах, отличных от Linux, особенно если это делает привилегированный пользователь. Что, если я пытаюсь удалить много экземпляров какого-либо процесса, отличного от 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(плюс любую опцию, чтобы выбрать, какой процесс (ы) отображать). Если вы решили , что вы хотите , чтобы убить лидера 1234 группы процессов и всех его потомков, запускать 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 еще более проблематичен, потому что есть несколько инструментов с одинаковыми именами, которые выглядят совершенно иначе. Мне тоже не нравятся ответы killall. pkill не существует в AIX или HP-UX, и, несмотря на то, что некоторым нравится верить, в мире все еще существует значительная база не-Linux UNIX.
EightBitTony

1
@EightBitTony, поэтому ваш ответ принят. Но я бы не стал использовать его на Solaris (который тоже Unix).
Нильс

6

Самый простой способ сделать это - сначала проверить, что вы получаете правильные идентификаторы процессов с помощью:

pgrep -f [part_of_a_command]

Если результат соответствует ожиданиям. Идти с:

pkill -f [part_of_a_command]

или используйте:pgrep -f "command name"
Магне

3

Интересно, никто не упомянул этот. pidof выводит разделенные пробелами pids процессов, соответствующих переданному имени процесса. Таким образом, вы можете напрямую использовать его вывод 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? Эти команды не читают со стандартного ввода.
Кусалананда

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.