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