Хотя мне все еще хотелось бы решение, которое делает языки сценариев кроссплатформенными и простыми для мониторинга из командной строки, если вы просто ищете альтернативу killall <scriptname>
для остановки пользовательских служб, вот как я решил это:
kill `ps -fC <interpreterName> | sed -n '/<scriptName>/s/^[^0-9]*\([0-9]*\).*$/\1/gp'`
Для тех, кто не слишком знаком с ps и регулярными выражениями, модификатор ps
-f
имеет список «полного» набора информации о процессе, включая аргументы командной строки, а -C
сообщает ему фильтровать список только по командам, которые соответствуют следующему аргументу командной строки. Замените <interpreterName>
на python
или node
или что-либо еще.
Аргумент
sed
-n
говорит, что по умолчанию он ничего не печатает, а сценарий регулярного выражения должен явно указывать, что вы хотите что-то напечатать.
В регулярном выражении первый /<scriptName>/
говорит ему отфильтровать результаты только по строкам, содержащим внутреннее регулярное выражение. Вы можете заменить <scriptName>
на envtest
, например.
s
указывает на то, что последует регулярное выражение подстановки. /^[^0-9]*\([0-9]*\).*$/
является частью совпадения строк и /\1/
является частью замещения. В части совпадения строк ^
в самом начале и $
в самом конце означают, что совпадение должно начинаться с начала строки и заканчиваться в конце строки - всей проверяемой строки подлежит замене.
[^0-9]*
включает в себя несколько вещей: []
используются для определения набора допустимых символов. В этой части регулярного выражения тире -
означает диапазон символов, поэтому он расширяется до 0123456789
. ^
здесь означает «не» и сразу означает «соответствует любому символу, который НЕ является числом». Звездочка *
впоследствии означает сохранение соответствующих символов в этом наборе, пока не встретится несовпадающий символ, в данном случае число.
У \([0-9]*\)
есть две части, \(\)
и [0-9]*
. Последнее должно легко следовать из предыдущего объяснения: оно соответствует только числам и захватывает столько, сколько может. \(\)
означает сохранение содержимого того, что соответствует временной переменной. (В других версиях RegEx, включая Javascript и Perl, вместо этого используется ()
.)
Наконец, .*
означает соответствие каждому оставшемуся символу, так как .
означает любой возможный символ.
Часть /\1/
говорит о замене совпавшей части строки (в данном случае это целая строка) на \1
, которая является ссылкой на сохраненную временную переменную (если их было два \(\)
) разделы, первый в RegEx будет \1
, а второй \2
).
g
впоследствии означает «жадность» и запускать этот соответствующий код на каждой встреченной строке, а p
означает печать любой строки, которая достигла этой точки.
Технически, это взорвется, если у вас будет запущено несколько копий скрипта, и вы действительно захотите немного тяжелее:
ps -fC <interpreterName> | sed -n '/<scriptName>/s/^[^0-9]*\([0-9]*\).$/kill \1/gp' | bash
Если вы хотите по-настоящему копировать функциональность kill * all *, но при этом создается отдельная оболочка bash для каждого сценария, который вы хотите уничтожить.