
Я пытаюсь избегать kill -9
по причинам, описанным вБесполезное использование убийства -9 бланк письмаДостаточно ли этой функции или мне нужно завершать kill
процессы по истечении времени ожидания или позаботиться о других тонкостях?
soft_kill()
{
# Try to avoid forcing a kill
# @param $1: PID
kill $1 || kill -INT $1 || kill -HUP $1 || \
(echo "Could not kill $1" >&2; kill -KILL $1)
}
Кстати, как лучше назвать эту функцию? Текущее название напоминает мне "Killing Me Softly" и manslaughter
звучит немного сурово. Может быть spoon_kill
(погуглите)?
решение1
У вашего soft_kill есть несколько проблем.
- Уничтожение процесса не происходит мгновенно, но kill завершает работу сразу после отправки сигнала. Вам придется подождать некоторое время, прежде чем определить, была ли команда kill успешной или вам нужно перейти к -INT или -HUP.
- убить возвращается(1)ноль (успех), если разрешено отправить сигнал. Нет, если удалось убить процесс. Таким образом, в вашем коде будет выполнено только первое убийство.
(1)
убийство()
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
В случае успеха kill() возвращает значение 0. В случае неудачи он возвращает значение -1, не отправляет сигнал и устанавливает errno в одно из следующих значений:
ЭИНВАЛ
Значение sig — недопустимый или неподдерживаемый номер сигнала.
ЭПЕРМ
Идентификатор пользователя отправляющего процесса не является привилегированным; его реальный или эффективный идентификатор пользователя не совпадает с реальным или сохраненным идентификатором пользователя принимающего процесса. Или у процесса нет разрешения на отправку сигнала любому принимающему процессу.
ЕСРЧ
Не удалось найти ни один процесс или группу процессов, соответствующих указанному pid.
решение2
terminate () {
# accepts PID as $1, defaults to current process
local signals=(TERM INT QUIT HUP KILL) s=0 process=${1:-$$}
local signal_qty=${#signals[@]}
while pgrep $process >/dev/null
do
signal=${signals[s]}
[[ $signal = KILL ]] && echo "Attempting to force kill it." >&2
kill -$signal $process
(( ++s >= signal_qty )) && { echo "It won't die." >&2; return 1; }
sleep 1
done
}