Мне часто нужно убивать процесс во время программирования.
Теперь я делаю это:
[~]$ 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>
В 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
; иесли у вас есть pkill,
pkill -f csp_build.py
Если вы хотите только grep против имени процесса (вместо полного списка аргументов), оставьте -f
.
ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9
awk '{print $2}'
sudo
является необязательнымkill -9 5124
, kill -9 5373
и т.д. (kill -15 более изящный, но немного медленнее)У меня также есть две функции быстрого доступа, определенные в моем .bash_profile (~/.bash_profile для osx, вы должны увидеть, что работает для вашей машины * nix).
p csp_build
, p python
и т.д.Код bash_profile:
# FIND PROCESS
function p(){
ps aux | grep -i $1 | grep -v grep
}
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"
}
source ~/.bash_profile
в текущей оболочке, чтобы импортировать новые функции (это то, что я предпочитаю).
grep
. Помните, все, что выглядит как grep x | awk '{ y }'
обычно лучше и часто более надежен, если заменить его на awk '/x/ { y }'
Попробуйте использовать
ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
killall -r regexp
-r, --regexp
Интерпретировать шаблон имени процесса как расширенное регулярное выражение.
Вы можете использовать только pkill '^python*'
для убийства процесса regex.
Если вы хотите увидеть, что вы собираетесь убить или найти до убийства, просто используйте pgrep -l '^python*'
, где -l выдает также имя процесса. Если вы не хотите использовать
pkill
, используйте только:
pgrep '^python*' | xargs kill
вы можете сделать это с помощью awk и backtics
ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`
$2 в awk печатает столбец 2, а backtics запускает напечатанное выражение.
Но гораздо более чистым решением было бы для процесса python хранить его идентификатор процесса в /var/run, а затем вы можете просто прочитать этот файл и убить его.
Использовать pgrep - доступно на многих платформах:
kill -9 `pgrep -f cps_build`
pgrep -f вернет все PID с совпадением "cps_build"
pgrep
, у вас также будет pkill
. Как всегда, не используйте kill -9
если вы не знаете, почему kill -15
(по умолчанию) или kill -2
не будут работать.
-9
и используется правильный современный синтаксис подстановки команд. Подтвердите это вместо этого; хотя, конечно, ответ pkill
еще лучше.
Моя задача - убить все, что соответствует регулярному выражению, которое помещается в определенную директорию (после тестов селена не все было остановлено). Это сработало для меня:
for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill -9 $i; done
kill
-9
возможно, слишком агрессивен. Это не позволяет им освободить свои ресурсы.
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
ps
с опцией -o
.
Это можно сделать еще быстрее, чем принятое решение (ы).
Если я хочу убить midori
, например:
kill -SIGTERM $(pgrep midori)
Готово!
Я начал использовать что-то вроде этого:
kill $(pgrep 'python csp_build.py')
Метод, использующий только awk
(и ps
):
ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'
При использовании тестирования равенства строк я не могу совместить этот процесс.
В некоторых случаях я хотел бы убивать процессы одновременно так:
➜ ~ sleep 1000 & [1] 25410 ➜ ~ sleep 1000 & [2] 25415 ➜ ~ sleep 1000 & [3] 25421 ➜ ~ pidof sleep 25421 25415 25410 ➜ ~ kill `pidof sleep` [2] - 25415 terminated sleep 1000 [1] - 25410 terminated sleep 1000 [3] + 25421 terminated sleep 1000
Но, я думаю, это немного неуместно в вашем случае. (Возможно, в фоновом режиме запущены python a, python b, python x...)
Дайте -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
Вам не нужен пользовательский переключатель для ps.
kill `ps ax | grep 'python csp_build.py' | awk '{print $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
Пригодится следующая команда:
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'})
Надеюсь, что поможет...!
Я использую gkill processname
, где gkill - это script:
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" в их командных строках.
grep
и других распространенных антипаттернов сценариев оболочки.
Я использую это, чтобы убить Firefox, когда он script захлопнулся и cpu bashing:) Замените "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
).