Найти и убить процесс в одной строке, используя bash и regex


650

Мне часто нужно убивать процесс во время программирования.

То, как я делаю это сейчас:

[~]$ ps aux | grep 'python csp_build.py'
user    5124  1.0  0.3 214588 13852 pts/4    Sl+  11:19   0:00 python csp_build.py
user    5373  0.0  0.0   8096   960 pts/6    S+   11:20   0:00 grep python csp_build.py
[~]$ kill 5124

Как я могу автоматически извлечь идентификатор процесса и уничтожить его в одной строке?

Нравится:

[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>

3
Поверь мне! : 'D Первый выбранный вами ответ намного сложнее, чем решение, которое вы сказали в своем ответе. Я предпочел бы выбрать свой путь.
Сантош Кумар

лучший способ проверить, существует ли процесс: stackoverflow.com/questions/3043978/…
Тревор Бойд Смит

Ответы:


1400

В bash, вы должны быть в состоянии сделать:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

Подробности его работы следующие:

  • Это psдает вам список всех процессов.
  • В grepфильтры , которые основаны на поисковой строке, [p]это трюк , чтобы остановить вас собирание фактического grepсамого процесса.
  • Право awkпросто дает вам второе поле каждой строки, которое является PID.
  • В $(x)средстве конструкта выполнить xзатем принять свой вывод и положить его в командной строке. Вывод этого psконвейера внутри вышеупомянутой конструкции представляет собой список идентификаторов процессов, поэтому вы получите команду вроде kill 1234 1122 7654.

Вот расшифровка, показывающая это в действии:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+  Terminated              sleep 3600
[1]   Terminated              sleep 3600
[2]   Terminated              sleep 3600
[3]-  Terminated              sleep 3600
[4]+  Terminated              sleep 3600

и вы можете видеть, что это прекращает все шпалы.


Объясняя grep '[p]ython csp_build.py'немного более подробно:

Когда вы выполняете sleep 3600 &последующее ps -ef | grep sleep, вы, как правило, получаете два процесса с sleepним, sleep 3600и и grep sleep(потому что они оба имеют sleepв них, это не ракетостроение).

Однако, ps -ef | grep '[s]leep'не будет создавать процесс с sleepним, он вместо этого создаст grep '[s]leep'и вот хитрый момент: grepон не находит его, потому что ищет регулярное выражение «любой символ из класса символов [s](который s), за которым следует» leep.

Другими словами, он ищет, sleepно процесс grep - это то, grep '[s]leep'чего нет sleepв нем.

Когда мне показали это (кто-то здесь на SO), я сразу начал использовать его, потому что

  • это на один процесс меньше, чем добавление | grep -v grep; а также
  • это элегантно и подлый, редкое сочетание :-)

2
@paxdiablo, можете ли вы предоставить ссылку для этого? Я сбит с толку, почему это работает.
Гленн Джекман

58
Вы можете использовать только awk - ps aux | awk '/ [b] eam / {print $ 2}' , grep не требуется
Yola

20
Лучше использовать только pgrep или pkill
NGix

2
Есть одна небольшая проблема - если процесс уже завершен, эта строка killбудет работать со стандартным выводомkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Lionel Chan

5
Вместо того , grep '[p]ython csp_build.py'вы также можете использовать: kill $(ps aux | grep 'python csp_build.py' | grep -v grep | awk '{print $2}'). grep -vвозвращает несопоставленные строки.
usandfriends

138

если у вас есть pkill,

pkill -f csp_build.py

Если вы хотите использовать только имя процесса (вместо полного списка аргументов), то не используйте -f.


1
Ничего не случилось, когда я проверял это.
Orjanp

8
сначала используйте pgrep, чтобы убедиться, что вы выбрали правильный процесс. затем снова используйте pkill на правильном шаблоне.
ghostdog74

18
+1. pgrepи pkillработайте, пока вы заботитесь, чтобы правильно определить процесс. По умолчанию сопоставляется только имя процесса , которое в данном случае почти наверняка является просто «python». Используйте, pgrep -f "python csp_build.py"чтобы соответствовать полной команде.
спуратик

3
Возможно, вам придется заставить убить с помощьюpkill -9 -f csp_build.py
studgeek

1
Это действительно должен быть принятый и получивший наибольшее количество голосов ответ; эти другие, со всеми способностями, не нужны. Я надеюсь, что люди, которые находят эту страницу, прочитают этот первый ответ.
Джейсон С

89

Один лайнер:

ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9

  • Распечатать колонку 2: awk '{print $2}'
  • sudo необязательно
  • Запустить kill -9 5124 и kill -9 5373т. Д. (Kill -15 более изящен, но немного медленнее)

Бонус:

У меня также есть две функции быстрого доступа, определенные в моем .bash_profile (~ / .bash_profile для osx, вы должны увидеть, что работает на вашем * nix-компьютере).

  1. п ключевое слово
    • перечисляет все P rocesses содержащих ключевое слово
    • использование, например: p csp_buildи p pythonт. д.

bash_profile код:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. ка ключевых слов
    • K бед процессы Л.Л. , которые имеют это ключевое слово
    • использование, например: ka csp_buildи ka pythonт. д.
    • необязательный уровень убийств , например: ka csp_build 15,ka python 9

bash_profile код:

# KILL ALL
function ka(){

    cnt=$( p $1 | wc -l)  # total count of processes found
    klevel=${2:-15}       # kill level, defaults to 15 if argument 2 is empty

    echo -e "\nSearching for '$1' -- Found" $cnt "Running Processes .. "
    p $1

    echo -e '\nTerminating' $cnt 'processes .. '

    ps aux  |  grep -i $1 |  grep -v grep   | awk '{print $2}' | xargs sudo kill -klevel
    echo -e "Done!\n"

    echo "Running search again:"
    p "$1"
    echo -e "\n"
}

Напоминание - не забудьте перезапустить оболочку bash (терминал) для загрузки новых функций. ИЛИ запустить source ~/.bash_profileв текущей оболочке, чтобы импортировать новые функции (это то, что я предпочитаю).
a20

Как и многие другие ответы здесь, это страдает от бесполезного использованияgrep . Помните, что все, что выглядит, как grep x | awk '{ y }'правило, лучше и часто более awk '/x/ { y }'
надежно,

1
@tripleee веб-сайт, на который вы ссылаетесь, принадлежит вам, верно? Я заметил, что вы связываете это со всеми разделами комментариев. Вы пытаетесь построить SEO?
а20

Нет, я не заинтересован в SEO. Я надеюсь повысить осведомленность.
tripleee

1
.. путем ссылки на ваш сайт, как если бы это был авторитетный сайт. Ницца. Кроме того, grep быстрее .
а20

16
killall -r regexp

-r, --regexp

Интерпретировать шаблон имени процесса как расширенное регулярное выражение.


15

Попробуйте использовать

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill

Пришлось немного его изменить. Это сработало. Спасибо. :) ps aux | grep 'python csp_build.py' | голова -1 | cut -d "" -f 5 | xargs kill
Orjanp

3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killработал на меня. спасибо
Расика Перера

Помните, дети, Awk может сделать все grep, и большинство из них просто и элегантно. Тривиальный случай grep x y | awk '{ z }'всегда лучше написан awk '/x/ { z }' y- см. Также бесполезное использованиеgrep .
tripleee

12

Вы можете использовать только pkill '^python*'для регулярного уничтожения процесса.

Если вы хотите увидеть, что вы собираетесь убить или найти перед тем, как убить, просто используйте pgrep -l '^python*'где -l выводит также имя процесса. Если вы не хотите использовать pkill, используйте просто:

pgrep '^python*' | xargs kill


8

Используйте pgrep - доступно на многих платформах:

kill -9 `pgrep -f cps_build`

pgrep -f вернет все PID с совпадением "cps_build"


2
Если у вас есть pgrep, у вас также будет pkill. Как всегда, не используйте,kill -9 если вы не знаете, почему kill -15(по умолчанию) или kill -2не будет работать.
tripleee

Это выглядит как худший парафраз ответа @ nathanael, в котором пропущено неверное направление -9и используется правильный современный синтаксис подстановки команд. Подтвердите это вместо этого; хотя, конечно, pkillответ еще лучше.
tripleee

@tripleee В этом случае я хочу убить -9 - уничтожить всех нарушителей с предубеждением. Более того, я много лет использовал kill -9 без проблем. По моему мнению, всегда будет лагерь пуристов против лагеря реалистов, добивающихся успеха, и я принадлежу к последнему (в этом вопросе).
а20

Вы пропустили часть "если не знаете почему"? Я все для того, чтобы добиться цели, но это один из распространенных способов выстрелить себе в ногу, пока вы не поймете, что на -9самом деле означает.
tripleee

@tripleee Эй, tripleee, я недавно обнаружил, что ты прав, kill -15 - лучший выбор, потому что он дает приложению шанс убить себя изящно. Я изменил свой код соответственно: stackoverflow.com/a/30486159/163382
a20

7

Это вернет только PID

pgrep -f 'process_name'

Итак, чтобы убить любой процесс в одну строку:

kill -9 $(pgrep -f 'process_name')

или, если вы знаете точное название процесса, вы также можете попробовать pidof:

kill -9 $(pidof 'process_name')

Но, если вы не знаете точное название процесса, pgrepбудет лучше.

Если несколько процессов запущены с одним и тем же именем и вы хотите убить первый, то:

kill -9 $(pgrep -f 'process_name' | head -1)

Также отметим, что если вас беспокоит чувствительность к регистру, вы можете добавить опцию -i, как в grep. Например:

kill -9 $(pgrep -fi chrome)

Больше информации о сигналах и pgrep на man 7 signalили man signalиman pgrep


5

Вы можете сделать это с помощью awk и backtics

ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`

$ 2 в awk печатает столбец 2, а backtics запускает напечатанный оператор.

Но гораздо более чистым решением было бы для процесса python сохранить его идентификатор процесса в / var / run, а затем вы можете просто прочитать этот файл и уничтожить его.


Разве вы не убьете оба процесса 5124 и 5373 тогда? Я думаю, это не проблема.
Orjanp

это не должно быть проблемой, но вы всегда можете добавить другой grep, чтобы исключить процесс grep: «grep -v grep» между grep и awk
Александр Кьялл

Протестировано с немного измененной командой. Но это не остановило процесс, только напечатало kill <pid>. пс auxf | grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}'
Orjanp

Требуется только обменять оператор print «kill» $ 2 с системой («kill» $ 2). Тогда это работает. :)
Orjanp

5

Моей задачей было уничтожить все, что соответствует регулярному выражению, помещенному в конкретную директорию (после тестов на селен не все останавливалось). Это сработало для меня:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done

Возможно, -9вариант killслишком агрессивен. Это не позволяет им освободить свои ресурсы.
Бирей

Ницца! Единственный, который учитывает тот факт, что может быть более одного процесса сопоставления! Небольшое примечание: возможно, вы захотите добавить «grep -v grep» или что-то подобное в каналы, чтобы сам процесс grep не отображался в вашем списке процессов.
Брэд Паркс

killпринимает несколько процессов, поэтому цикл в основном бесполезен; и, как отмечено в другом месте на этой странице, вы не должны использовать, kill -9если вы не знаете, что процесс не будет отвечать просто kill.
tripleee

удалить -9 не имеет большого значения, почему downvote. Ты бы лучше отредактировал ответ.
Серж

5

Чтобы убить процесс по ключевому слову midori, например:

kill -SIGTERM $(pgrep -i midori)


3

Метод, использующий только awkps):

ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'

Используя проверку на равенство строк, я предотвращаю сопоставление самого процесса.


По какой-то причине я не получаю «python csp_build.py». Но "питон" один бьет.
Orjanp

3
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15

Не может +1 из-за суточного лимита, но стоит использовать опцию psс -oопцией.
П Швед

ps не дают мне много. [~] $ ps PID TTY TIME CMD 6365 pts / 6 00:00:00 ps 29112 pts / 6 00:00:00 bash
Orjanp

3

Дать -f pkill

pkill -f /usr/local/bin/fritzcap.py

Точный путь к файлу .py

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m


1

Убивать наши собственные процессы, запускаемые из общего PPID довольно часто, pkill, связанный с –Pфлагом, является для меня победителем. Используя пример @ ghostdog74:

# sleep 30 &                                                                                                      
[1] 68849
# sleep 30 &
[2] 68879
# sleep 30 &
[3] 68897
# sleep 30 &
[4] 68900
# pkill -P $$                                                                                                         
[1]   Terminated              sleep 30
[2]   Terminated              sleep 30
[3]-  Terminated              sleep 30
[4]+  Terminated              sleep 30

1

Вам не нужен пользовательский переключатель для PS.

kill `ps ax | grep 'python csp_build.py' | awk '{print $1}'`

1

В некоторых случаях я хотел бы уничтожить процессы одновременно следующим образом:

Sleep ~ спать 1000 &
[1] 25410
Sleep ~ спать 1000 &
[2] 25415
Sleep ~ спать 1000 &
[3] 25421
Sleep ~ пидоф сна
25421 25415 25410
Kill ~ убей `пидоф сна`
[2] - 25415 прервали сон 1000                                                             
[1] - 25410 прервали сон 1000
[3] + 25421 прервал сон 1000

Но я думаю, что это немного неуместно в вашем случае (может быть, там работают python a, python b, python x ... на заднем плане).


1

Если pkill -f csp_build.pyне уничтожить процесс, вы можете добавить, -9чтобы отправить сигнал уничтожения, который не будет проигнорирован. т.е.pkill -9 -f csp_build.py


1

Решением будет фильтрация процессов с точным шаблоном, разбор pid и создание списка аргументов для выполнения процессов kill:

ps -ef  | grep -e <serviceNameA> -e <serviceNameB> -e <serviceNameC> |
awk '{print $2}' | xargs sudo kill -9

Пояснения из документации:

Утилита ps отображает строку заголовка, за которой следуют строки, содержащие информацию обо всех ваших процессах, которые имеют управляющие терминалы.

-e Вывести информацию о процессах других пользователей, в том числе

-f Показать uid, pid, родительский pid, недавнее использование процессора, запуск процесса

В GREP поиск утилиты любых данных входных файлов, выбирая строки , которые

-e pattern, --regexp = pattern Указать шаблон, используемый при поиске входных данных: строка ввода выбирается, если она соответствует любому из указанных шаблонов. Этот параметр наиболее полезен, когда несколько опций -e используются для указания нескольких шаблонов или когда шаблон начинается с тире (`- ').

xargs - создать список аргументов и выполнить утилиту

убить - завершить или дать сигнал процессу

сигнал № 9 - KILL (неуловимое, невосполнимое убийство)

Пример :

ps -ef  | grep -e node -e loggerUploadService.sh - -e applicationService.js |
awk '{print $2}' | xargs sudo kill -9

0

Я использую это, чтобы убить Firefox, когда его сценарий захлопывается и процессор избивает :) Замените «Firefox» на приложение, которое вы хотите умереть. Я использую оболочку Bash - OS X 10.9.3 Darwin.

kill -Hup $(ps ux | grep Firefox | awk 'NR == 1 {next} {print $2}' | uniq | sort)


Замена grep Firefox | awk 'NR == 1 { next } ...'с awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'не только экономит процесс, но и повышает точность. Это не трудно избавиться sort | uniqв чистом Awk либо ( в то время, конечно , uniq | sortэто просто неправильно - это будет не хватать каких - либо дубликаты , которые не являются смежными, и скрыть ошибку, без необходимости сортировки выход из uniq).
tripleee

0

Я использую gkill processname, где gkill это следующий скрипт:

cnt=`ps aux|grep $1| grep -v "grep" -c`
if [ "$cnt" -gt 0 ]
then
    echo "Found $cnt processes - killing them"
    ps aux|grep $1| grep -v "grep"| awk '{print $2}'| xargs kill
else
    echo "No processes found"
fi

ПРИМЕЧАНИЕ: это НЕ убьет процессы, которые имеют "grep" в своих командных строках.


1
Как и многие, многие другие изобретения якского сарая, это изобилует бесполезным использованиемgrep и другими распространенными антипаттернами сценариев оболочки.
tripleee

-1

Следующая команда пригодится:

kill $(ps -elf | grep <process_regex>| awk {'print $4'})

например., ps -elf | grep top

    0 T ubuntu    6558  6535  0  80   0 -  4001 signal 11:32 pts/1    00:00:00 top
    0 S ubuntu    6562  6535  0  80   0 -  2939 pipe_w 11:33 pts/1    00:00:00 grep --color=auto top

kill -$(ps -elf | grep top| awk {'print $4'})

    -bash: kill: (6572) - No such process
    [1]+  Killed                  top

Если процесс все еще застрял, используйте расширение -9 для hardkill, как показано ниже:

kill -9 $(ps -elf | grep top| awk {'print $4'})

Надеюсь, это поможет...!


-1

Найти и убить все процессы в одной строке в bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>'- Предоставляет список деталей запущенного процесса (uname, pid и т. Д.), Который соответствует шаблону. Выходной список включает в себя и эту grepкоманду, которая ищет ее. Теперь для убийства нам нужно игнорировать этот grepкомандный процесс.
  • ps -ef | grep '<exec_name>' | grep -v 'grep'- Добавление еще одного grep с -v 'grep'удаляет текущий процесс grep.
  • Затем с помощью awkget get id процесса.
  • Затем сохраните эту команду внутри $(...)и передайте ее killкоманде, чтобы убить весь процесс.

-1

Вы можете использовать приведенную ниже команду для вывода списка команд. Используйте top или лучше используйте htop для просмотра всех процессов в linux. Здесь я хочу убить процесс с именем

ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'

И проверь пид. Это должно быть правильно. Чтобы убить их, используйте команду kill.

sudo kill -9 `ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'`

Например: - из списка процессов htop.

sudo kill -9 `ps -ef | grep '<process>'  | grep -v grep | awk '{print $2}'`

Это решает мои проблемы. Всегда будьте готовы перезапустить процесс, если вы случайно убили процесс.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.