Фрагмент Bash за убийство процесса до его смерти?


8

Я пытаюсь написать надежный скрипт bash, и в нем я создаю фоновый процесс. В конце сценария я хочу его убить. У меня есть PID.

Я думал о чем-то вроде этого

while [[ ps ef $PID ]] ; do
  kill $PID
  sleep 0.5
done

Любой предлагает что-нибудь лучше? Любые возможные проблемы с этим подходом?


Вы не имели в виду ps -ef?
user1686

1
grawity: Это просто стиль BSD против параметров UNIX, но, похоже, ef лучше подходит для параметров UNIX. Я бы сам пошел с «ps ao pid»
Кайл Брандт

while [[ ps ef $PID ]]это синтаксическая ошибка Я полагаю, вы имели в виду while ps ef $PID.
Деннис

Ответы:


10

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

Почему вы должны неоднократно убивать процесс? Если это происходит из-за того, что процесс завершится, но может пройти некоторое время после получения сигнала, вы можете использовать wait:

 kill $PID
 wait $PID

В идеальной системе вам никогда не придется повторять killили выпускать kill -9 $PID. Если вам нужно, вы можете рассмотреть возможность исправления того, что вы используете, чтобы вам не пришлось это делать. Тем временем вы, вероятно, не попадете в состояние гонки, и вы можете защититься от него, скажем, путем проверки метки времени / proc / $ PID / непосредственно перед тем, как завершить процесс. Это плохое хакерство.


1
Это не работает, если PID не принадлежит дочернему процессу, то есть этот скрипт пытается контролировать выполнение процесса, который возник в другом месте. Я получаю, bash: wait: pid 32137 is not a child of this shellкогда я пытаюсь. :(
Джастин Форс

9

Всем, кто рекомендует переход с kill $PIDна kill -9 $PID, я должен напомнить вам о бесполезном использовании kill -9 .

Нет нет нет. Не используйте kill -9.

Это не дает процессу возможность чисто:

  1. отключить сокет соединения

  2. очистить временные файлы

  3. сообщить своим детям, что он уходит

  4. сбросить свои терминальные характеристики

и так далее, и так далее, и так далее.

Как правило, отправьте 15 и подождите секунду или две, и если это не сработает, отправьте 2, а если это не сработает, отправьте 1. Если это не сработает, УДАЛИТЕ ДВОЙНОЙ, потому что программа плохо себя ведет!

Не используйте kill -9. Не берите комбайн, чтобы убрать цветочный горшок.

Я не согласен с «удалить двоичную часть», но прогресс выглядит менее разрушительным, чем просто kill -9.

Я также согласен с заботой об условиях гонки при создании новых процессов с тем же PID, упомянутым здесь .


0

Сначала сделайте свое обычное убийство, выспитесь x количество секунд, а затем убейте -9, если оно еще осталось. Кроме того, это кажется странной ситуацией, в которую вы попали, возможно, вы захотите объяснить нам более крупную проблему.


Согласовано. Если он не отвечает и не закрывается после одного SIGTERM (сигнал, отправляемый по умолчанию kill), то, вероятно, не будет отвечать на 2-й, 3-й, 4-й, ...., таким образом, следующий ход действий должен быть SIGKILL (kill - 9). Конечно, вы должны убедиться, что X в «секундах ожидания X» достаточно длинен, чтобы процесс мог выполнить обычную операцию очистки вашего рабочего стола и выхода, даже если система сильно загружена - это может занять часть времени. секунда обычно, но десятки секунд, когда система работает.
Дэвид Спиллетт

0

Как правило, вы хотите попробовать в kill $PIDпервую очередь,

затем дайте ему немного поспать, чтобы увидеть, выйдет ли он изящно.

Если нет, то выполните kill -9 $PIDпринудительно, чтобы избавиться от него.


-1

почему не просто

kill -9 $PID


2
Потому что вы хотите дать процессам возможность очиститься и умереть, что и делает сигнал TERM (сигнал по умолчанию). Сигнал KILL ("-9") не дает процессам такой возможности.
ktower

Хороший вопрос, но оригинальный постер сказал, что он просто хотел убить его.
Крис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.