Изящный способ убить процесс

12

После того, как мой bash-скрипт сделан с сервером selenium, скрипт убивает его так:

kill `ps -ef | grep selenium | awk '{ print $2 }'`

Несмотря на то, что это работает и он уничтожает сценарий селена, он также пытается уничтожить процесс, grep seleniumпоэтому к тому моменту, когда номер процесса возвращается к команде kill, процесс завершается, и в итоге он генерирует сообщение об ошибке. (Другими словами: это приводит к уничтожению двух процессов, один из которых - настоящий сервер селена, а другой - мимолетный процесс, который является побочным эффектом от выполнения этой команды.)

Есть ли более изящный способ убить процесс, у которого нет этого непреднамеренного побочного эффекта?

(У меня есть одна идея: этот же сценарий запускает селен ранее в сценарии, так что, возможно, если бы был способ, которым я мог бы захватить PID, когда я запускаю селен, я мог бы просто сохранить это и убить его напрямую, вместо того, чтобы искать для ID процесса. Проблема в том, что я не знаю, как получить этот PID, как использовать переменную, чтобы сохранить его и как ссылаться на него позже в скрипте. Но разве это лучший способ сделать это?)

Эрик
источник

Ответы:

12

Попробуйте использовать, pkill seleniumесли ни то, ни другое не работает, вы можете продолжать использовать свой метод с другой последовательностью каналов, такой как

kill `ps -ef|grep -i selenium| grep -v grep| awk '{print $2}'`
Момо
источник
pkill не работает на моем сервере для этого, но ваша улучшенная полоса grep очень помогает.
Эрик
20

Попробуйте pgrepкоманду, которая выведет PID интересующей вас команды.

pgrep selenium

Чтобы фактически убить процесс, используйте команду companion pkill.

pkill selenium
mills013
источник
Мне нравится элегантность этого, но процесс выглядит так: "root 26401 11997 2 23:20 pts / 1 00:00:00 java -jar /home/lm/cron/selenium-server-standalone-2.19.0. jar ", так что я просто изменил его, pgrep javaи он работает :-) спасибо!
Эрик
2
Если вы дадите pgrep флаг '-f', он будет соответствовать шаблону всей командной строки. Таким образом, в этом случае убийство pgrep -f seleniumдолжно сработать
mills013
7
использовать pkillнамного проще. pkillиспользует те же критерии соответствия pgrep, что и вы, так что вы можете сделать это в 1 команде вместо 2 (и полагаться на вывод одной).
Патрик
7

Попробуйте использовать grep [s]elenium. Это не найдет процесс grep.

BillThor
источник
Это действительно удобный трюк. Почему это работает?
2
@hesse - grepпо умолчанию использует BRE. То есть, [и ]появляются в argvтечение grep, но это не соответствует, потому что [и ]не используются буквально grep.
Крис Даун
Я часто использовал | grep -v grepкомпонент в трубе. Но это довольно элегантно, и мне это нравится!
Алексиос
Этого (часто) недостаточно, если в текущем рабочем каталоге есть файл с тем же именем, что и процесс, к которому вы относитесь. Таким образом, решение , которое я обычно использую: ps -ef | grep \[s]elenium. Хотя я нашел lsofгораздо лучшую альтернативу использованию psи grep.
Мореаки
2

Команда killallне упоминалась, и я чувствую, что это полезное дополнение к репертуару.

$ killall selenium

Вы также можете использовать -r regexопцию, чтобы указать регулярное выражение для соответствия имени процесса и даже значение времени:

$ killall -o 5m selenium 

Убивает все процессы селена старше 5 минут.

kwarrick
источник
Это, кажется, уникально для не-RHEL / CentOS версийkillall
ewwhite
0

Используйте -m 1переключатель с командой grep, чтобы получить только первый найденный процесс. Пока вы сортируете свои процессы по PID, по возрастанию это будет работать.

hellodanylo
источник
1
Вы не можете быть уверены, что процесс селена использует более низкий PID.
FJRA
FJRA, процесс, начатый ранее, всегда получает более низкий PID. Поскольку сервер селен запускается до «grep selenium», он получит более низкий PID.
hellodanylo