Ошибка команды kill

У нас есть скрипт, который извлекает все активные процессы и убивает их. Но по какой-то причине я получаю следующую ошибку:

:: INFO :: /AA/AAA/AAA/AAA/AAA/AAA/AAA/AAA\ Servers.sh :: 2016-06-26:04:00:04 : ПРИНУДИТЕЛЬНОЕ УБИЙСТВО ОСТАВШИХСЯ ПРОЦЕССОВ СЕРВЕРА

:: ИНФОРМАЦИЯ :: /AA/AAA/AAA/AAA/AAA/AAA/AAA/AAA\ Servers.sh :: 2016-06-26:04:00:04 :force_stop_managed_servers вызвал kill: использование\ : kill [-s sigspec | -n сигнум | -sigspec] pid | спецификация задания ... или kill -l [sigspe\ c]

Мой сценарий имеет функцию ниже, чтобы принудительно убить процессы.

function force_stop_managed_servers () {

        printf "\n\n:: INFO :: $0 :: `date +%Y-%m-%d:%H:%M:%S` :force_stop_managed_servers called"
        cd $SCRIPT_DIR
        kill -9 $(ps -ef | grep SONARPOTY | grep $USER | grep -v "grep" | grep -v "StopManagedServers" | grep -v "controller"| awk '{ print $2 }')
        printf "\n\n:: INFO :: $0 :: `date +%Y-%m-%d:%H:%M:%S` :force_stop_managed_servers done"
}

Пожалуйста, дайте мне знать, почему я получаю эту ошибку.


person MAHESH KUMAR    schedule 27.06.2016    source источник
comment
Попробуйте это с set -x, и вы, вероятно, увидите, что kill вызывается неправильно. (Кроме того, shellcheck.net покажет, что у вас есть другие потенциальные ошибки.)   -  person Biffen    schedule 27.06.2016
comment
Убедитесь, что $USER не пусто, а также что в результате выполнения большой команды возвращается только один pid.   -  person Fazlin    schedule 27.06.2016
comment
@Fazlin: длинная команда НЕ вернет ни одного идентификатора процесса. Он вернет несколько процессов. Не могли бы вы предложить, в чем недостаток, если он возвращает несколько процессов, а также возможное решение для преодоления этого?   -  person MAHESH KUMAR    schedule 27.06.2016
comment
Я не хочу использовать цикл for, потому что цикл for убивает процессы один за другим, и возможно, что как только я получу список и уничтожу их один за другим, процесс может завершиться, и тогда команда kill выдаст ошибку сообщает Нет такого процесса.   -  person MAHESH KUMAR    schedule 27.06.2016
comment
Насколько я знаю, команда kill не работает с несколькими pid.s в качестве аргумента. Возможно, вам придется использовать цикл.   -  person Fazlin    schedule 28.06.2016
comment
@Fazlin: он работает с несколькими PID. Как я упоминал выше, цикл for имеет указанный выше недостаток. Более того, проблема носит периодический характер. Это не всегда приходит. один иногда я вижу проблему, а в остальном все работает нормально. Итак, вопрос в том, что является тем крайним случаем, когда я получаю эту проблему.   -  person MAHESH KUMAR    schedule 28.06.2016
comment
Почему бы не использовать pkill -9 -u $USER 'pattern1|pattern2|pattern3'?   -  person alvits    schedule 11.07.2017
comment
@Fazlin — вот справочная страница kill(1).   -  person alvits    schedule 11.07.2017


Ответы (2)


Эта ошибка возможна, если команда kill -9 вызывается без аргумента. Вы можете выполнить команду длинной строки и назначить вывод переменной. Позже проверьте, не является ли эта переменная пустой, и передайте эту переменную в качестве аргумента для команды kill.

person JP Bose    schedule 27.06.2016

Пакет procps лучше справляется с выбором процессов и посылает сигналы выбранным процессам, чем пакет util-linux-ng в сочетании с grep.

Очень часто можно увидеть сценарии, которые используют grep для выбора идентификатора процесса из списка процессов.

ps -ef | grep pattern | grep -v grep | awk '{print $2}'

Однако это можно сократить до:

pgrep pattern

В обоих случаях будет напечатано PID процесса с именем pattern. Однако есть одно предостережение: вторая версия сопоставляет шаблон только с именами процессов. Если вам нужно сопоставить аргументы команды, вам нужно что-то вроде:

pgrep -f pattern

Ограничение поиска процессов, принадлежащих пользователю. Некоторые попытки grep имени пользователя. И pgrep, и ps принимают -u username для перечисления только процессов, принадлежащих пользователю username.

Вместо того, чтобы писать:

ps -ef | grep username | grep -v grep | awk '{print $2}'

Пытаться:

pgrep -u username

Если вам нужно убить эти выбранные PID, вам не нужно запускать kill против результатов. Все, что вам нужно, это использовать pkill вместо pgrep.

pkill -u username pattern

Если вы действительно ограничены использованием ps и kill по какой-либо причине, ps позволяет форматировать вывод. Таким образом, вы можете использовать grep для шаблона, не получая непреднамеренно PID самого grep.

kill -9 $(ps -u username -opid=.comm= | grep pattern | awk '{print $1}')

Единственным недостатком использования kill $() является то, что $() может вернуться пустым, и вы получите сообщение об ошибке. Решение состоит в том, чтобы отправить сообщение об ошибке на /dev/null. pkill не будет жаловаться, даже когда нечего убивать.

Наконец, если вам нужно сопоставить аргумент команды вместо самой команды, используйте -opid=,args= для вывода аргументов вместо вывода команды.

person alvits    schedule 11.07.2017