Здравствуйте, длинная история: я пытаюсь создать скрипт для запуска через CI-сервер, чтобы убить определенный процесс.
Поэтому, просматривая в Интернете, я обнаружил эту команду:
myuser@server:/home/myuser# ps -ef | grep someUniqueText | grep -v grep | awk '{print $2}'
5263
Когда я запускаю его в консоли, он возвращает мне именно то, что мне нужно (5263
), поэтому я создал этот bash:
#!/bin/bash
PROCESSNAME=$1
PID=$(ps -ef | grep $PROCESSNAME | grep -v grep | awk '{print $2}');
echo $PID;
Когда я выполняю его следующим образом:
myuser@server:/home/myuser# ./killProcess.sh somename
5263 4587 1236
Скрипт bash возвращает 3 числа, являющиеся первым процессом, который мне нужен, и я понятия не имею, чем являются другие два, Почему? oO
PS .: Сначала я использую echo
, чтобы проверить его, я изменю его на kill -9
При выполнении ./killProcess.sh somename
затем процесс, подобный
/bin/bash ./killProcess.sh somename
существует и ps | grep | grep | awk
- строка также находит этого, потому что она имеет текст somename
в нем. Я не абсолютно уверен, почему Вы получаете два дополнительных PIDs (и не всего один), но и я считаю, что это - некоторая родительская/дочерняя штука между bash
и killProcess.sh
. В каждый выстраивает в линию шоу PID как PID и в другом как PPID.
Можно избежать этих PIDs путем захвата их далеко на основе названия сценария. Это хранится в $0
, так
PID=$(ps -ef | grep $PROCESSNAME | grep -v grep | grep -v $0 | awk '{print $2}');
или (с меньшим количеством вызовов программы):
PID=$(ps -ef | grep $PROCESSNAME | grep -v -e grep -e $0 | awk '{print $2}');
Другим (более безопасным) путем был бы к grep далеко PID сценария. Это хранится в $$
:
PID=$(ps -ef | grep $PROCESSNAME | grep -v -e grep -e $$ | awk '{print $2}');
Или выполните во всем этом awk
:
PID=$(ps -ef | awk "/$PROCESSNAME/ && !/awk/ && !/$$/ {print \$2}");
Мы должны выйти \$2
здесь, таким образом, это не интерпретируется оболочкой, но awk
. То средство команды:
Если строка содержит $PROCESSNAME
и не содержит awk
и не содержит наш очень собственный PID, затем печатает второй столбец.
Преимущество (в теории), который это выполняет быстрее потому что только одна дополнительная команда (awk
) требуется в противоположность 3 властям и awk.
Все эти власти и awks не прекрасны, и Вы будете всегда находить ситуацию, о которой мы не думали здесь (как частичные соответствия и т.д.) По этой причине, я рекомендую использовать один из уже записанных инструментов:
killall somename
# к предварительному просмотру, первому показу killall -v -s 0 somename
pgrep somename
# просто перечислите PIDspkill somename
# подобный killall
Я когда-то реализовал подобную идею как функция оболочки, которую я вызываю psg
(для "ps|grep")
psg() {
local -a patterns=()
(( $# == 0 )) && set -- $USER
for arg do
patterns+=( "-e" "[${arg:0:1}]${arg:1}" )
done
ps -ef | grep "${patterns[@]}"
}
Это использует прием помещения первого символа шаблона в скобках, таким образом, Вы добираетесь
ps -ef | grep "[s]omename"
Это позволяет Вам отбрасывать grep -v grep
часть конвейера.
Если Вы не передаете аргументов, это использует Ваше имя пользователя для поиска процессов.