Знайдіть і вбийте процес в одному рядку, використовуючи bash та regex


647

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

Я це роблю зараз:

[~]$ 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/…
Тревор Бойд Сміт

Відповіді:


1397

В 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, чи можете ви надати посилання на це? Мене бентежить, чому це працює.
glenn jackman

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

20
Краще використовувати лише pgrep або pkill
NGix

2
Є одне невелике питання - якщо процес уже припинено, ця лінія killбуде витіснятися зі стандартним результатомkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Ліонель Чан

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
Нічого не сталося, коли я тестував це.
Ор’янп

8
спочатку використовуйте pgrep, щоб переконатися, що ви виконали правильний процес. потім знову використовуйте pkill за правильною схемою.
ghostdog74

18
+1. pgrepі pkillпрацюйте, поки ви подбаєте про те, щоб правильно вказати процес. За замовчуванням узгоджується лише ім'я процесу , що майже напевно просто "python". Використовуйте, pgrep -f "python csp_build.py"щоб відповідати повній команді.
mr.spuratic

3
Можливо, вам доведеться змусити вбитиpkill -9 -f csp_build.py
studgeek

1
Це дійсно повинно бути прийнятою і найголоснішою відповіддю; ці інші зі всім дивним враженням ніби не потрібні. Я сподіваюся, що люди, які знайшли цю сторінку, прочитали за межі першої відповіді.
Джейсон C

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т. Д. (Убивати -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
}
  1. ка ключове слово
    • До бід процеси Л.Л. , які мають це ключове слово
    • використання , наприклад: 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 shell (термінал) для завантаження нових функцій. АБО запустіть source ~/.bash_profileу поточній оболонці, щоб імпортувати нові функції (саме це я вважаю за краще).
a20

Як і багато інших відповідей тут, це монументально страждає від марного використанняgrep . Пам'ятайте, що все, що виглядає, як grep x | awk '{ y }'правило, краще і частіше надійніше, якщо ви заміните йогоawk '/x/ { y }'
триплея

1
@tripleee веб-сайт, на який ви посилаєтесь, належить вам правильно? Я помічаю, що ви пов'язуєте це в різних розділах коментарів. Ви намагаєтесь створити SEO?
a20

Ні, мене не цікавить SEO. Я сподіваюсь розвинути обізнаність.
трійка

1
.. посилаючись на ваш веб-сайт, ніби це створений орган влади. Приємно. Крім того, греп відбувається швидше .
a20


15

Спробуйте використовувати

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

Довелося це трохи змінити. Це спрацювало. Дякую. :) ps aux | grep 'python csp_build.py' | голова -1 | вирізати -d "" -f 5 | xargs kill
Orjanp

3
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs killпрацював на мене. thanx
Расіка Перера

Пам’ятайте, діти, Awk може зробити все, що grepможна, і більшість це просто та елегантно. Тривіальний випадок grep x y | awk '{ z }'завжди краще писати awk '/x/ { z }' y- див. Також марне використанняgrep .
трійчатка

11

Ви можете використовувати тільки 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 У цьому випадку вбивати -9 - це саме те, що я хочу - виправдайте всіх злочинців з надзвичайними упередженнями. Більше того, я використовував kill -9 протягом багатьох років без проблем. На мою думку, завжди буде табір пуристів проти табору реалістів, що виконують справи, і я належу до останніх (в цьому питанні).
a20

Ви пропустили частину "якщо ви не знаєте чому"? Я все для того, щоб все зробити, але це один із поширених способів стріляти в ногу, поки ви не зрозумієте, що -9насправді означає.
трійка

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

6

Це поверне лише під

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, а в задній панелі виконується надрукований оператор.

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


Хіба ви не будете вбивати обидва процеси 5124 і 5373 тоді? Я думаю, це не проблема.
Ор’янп

це не повинно бути проблемою, але ви завжди можете додати ще одну греп, щоб виключити процес grep: "grep -v grep" між grep та awk
Alexander Kjäll

Тестується з трохи зміненою командою. Але це не вбило процес, лише надруковано kill <pid>. ps auxf | grep '[p] ython csp_build.py' | awk '{print "kill" $ 2}'
Orjanp

Потрібно лише замінити на друк операцію print "kill" $ 2 системою ("kill" $ 2). Тоді це працює. :)
Ор’янп

5

Моєю задачею було вбити все, що відповідає regexp, яке розміщується у певному каталозі (після тестів на селен не все зупинилося). Це працювало для мене:

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.
трійка

видалити -9 - це не велика справа, навіщо знижувати. Ви краще відредагуйте відповідь.
Серж

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". Але "пітон" один хіт.
Ор’янп

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 балів / 6 00:00:00 пс 29112 балів / 6 00:00:00 баш
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

У деяких випадках я хотів би вбити процеси одночасно так:

➜ ~ сон 1000 &
[1] 25410
➜ ~ сон 1000 &
[2] 25415
➜ ~ сон 1000 &
[3] 25421
➜ ~ пiдоф сон
25421 25415 25410
➜ ~ вбити `pidof сон`
[2] - 25415 припиненого сну 1000                                                             
[1] - 25410 припиненого сну 1000
[3] + 25421 припинений сон 1000

Але я вважаю, що це трохи недоречно у вашому випадку. (Можливо, на задньому плані працюють пітон a, python b, python x ...)


1

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


1

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

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 - Вбивство (невловимий, неігнорований вбивство)

Приклад :

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 Дарвін.

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).
трійчатка

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" для жорсткого вбивства таким чином:

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.
  • Потім за допомогою awkотримайте ідентифікатор процесу самостійно.
  • Потім утримуйте цю команду всередині $(...)і передайте її killкоманді, щоб вбити весь процес.

-1

Ви можете скористатися командою нижче, щоб перерахувати pid команди. Використовуйте верхню або кращу версію 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.