Найти и убить процесс в одной строке, используя bash и regex - PullRequest
564 голосов
/ 18 августа 2010

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

Способ, которым я делаю это сейчас:

[~]$ 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>

Ответы [ 23 ]

1252 голосов
/ 18 августа 2010

В 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; и
  • это элегантно и подлый, редкое сочетание: -)
118 голосов
/ 18 августа 2010

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

pkill -f csp_build.py

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

79 голосов
/ 27 мая 2015

Один вкладыш:

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 ключевое слово
    • перечисляет все процессы P , содержащие ключевое слово
    • , например: p csp_build, p python и т. Д.

bash_profile код:

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

bash_profile code:

# 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"
}
14 голосов
/ 18 августа 2010

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

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
13 голосов
/ 28 ноября 2013
killall -r regexp

-r, --regexp

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

9 голосов
/ 20 ноября 2012

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

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

pgrep '^python*' | xargs kill

6 голосов
/ 22 ноября 2015

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

kill -9 `pgrep -f cps_build`

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

5 голосов
/ 18 августа 2010

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

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

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

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

5 голосов
/ 16 марта 2017

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

kill -SIGTERM $(pgrep -i midori)

4 голосов
/ 10 октября 2013

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

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