подпроцесс перезапуска bash с использованием trap-сообщения SIGCHLD? - PullRequest
6 голосов
/ 21 июля 2011

Я видел программы мониторинга либо в скриптах, которые периодически проверяют состояние процесса с помощью 'ps' или 'status (в Linux)' ', либо в C / C ++, который разветвляется и ждет процесса ...

Интересно, можно ли использовать bash с trap и перезапустить подпроцесс при получении SIGCLD?

Я протестировал базовый пакет на RedHat Linux со следующей идеей (и, конечно, он не работал ...)

#!/bin/bash
set -o monitor # can someone explain this? discussion on Internet say this is needed
trap startProcess SIGCHLD
startProcess() { 
  /path/to/another/bash/script.sh & # the one to restart
  while [ 1 ]
  do
    sleep 60
  done
}
startProcess

что запускается скрипт bash, просто поспите несколько секунд и выйдите из него.

обнаружено несколько проблем:

  • когда оболочка запускается на переднем плане, SIGCHLD будет обрабатываться только один раз. обработка сигнала сброса ловушки похожа на signal ()?
  • сценарий и его дочерний элемент кажутся невосприимчивыми к SIGINT, что означает, что они не могут быть остановлены ^ C
  • так как не может быть закрыт, я закрыл терминал. Сценарий, кажется, HUP и многие дети-зомби остались.
  • при запуске в фоновом режиме, скрипт вызывал смерть терминала

... во всяком случае, это не работает вообще. Я должен сказать, что слишком мало знаю об этой теме. Может кто-нибудь предложить или привести несколько рабочих примеров? Есть ли сценарии для такого использования?

как насчет использования wait в bash, тогда?

Спасибо

1 Ответ

7 голосов
/ 21 июля 2011

Я могу попытаться ответить на некоторые ваши вопросы, но не все, основываясь на том, что я знаю.

  1. Строка set -o monitor (или, что эквивалентно, set -m) включает работу контроль, который включен по умолчанию только для интерактивных оболочек. Это кажется быть обязательным для отправки SIGCHLD. Тем не менее, контроль работы больше интерактивная функция и не предназначена для использования в сценариях оболочки (см. также этот вопрос ).

    Также имейте в виду, что это, вероятно, не то, что вы намеревались сделать потому что как только вы включите управление заданиями, SIGCHLD будет отправляться за каждые внешняя команда, которая существует (например, каждый раз, когда вы запускаете ls или grep или что-нибудь, SIGCHLD сработает, когда эта команда завершится и ваша ловушка будет работать).

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

  3. Кажется, что "невосприимчивость" скрипта к SIGINT является эффектом включения контроль работы (часть монитора). Моя догадка с включенным контролем работы, подэкземпляр bash, который запускает ваш скрипт, больше не завершается сам в ответ на SIGINT, но вместо этого передает SIGINT до его передний план дочерний процесс. В вашем скрипте ^C т.е. SIGINT просто действует как оператор continue в других языках программирования случай, так как SIGINT просто убьет текущую sleep 60, после чего цикл while немедленно запустит новый sleep 60.

  4. Когда я попытался запустить ваш скрипт, а затем убить его (из другого терминал) все, что я закончил, это два случайных спящих процесса.

  5. Фоновая обработка этого скрипта также убивает мою оболочку для меня, хотя поведение не очень последовательное (иногда это случается сразу, в другие времена совсем нет). Кажется, печатать какие-то клавиши, другие чем ввод, EOF как-то отправляется. Даже после терминала Выходит скрипт продолжает работать в фоновом режиме. Я понятия не имею что здесь происходит.

Помочь было бы более конкретно о том, чего вы хотите достичь. Если вы просто хотите, чтобы команда работала непрерывно в течение всего времени жизни вашего Сценарий, вы можете запустить бесконечный цикл в фоновом режиме, как

while true; do
    some-command
    echo some-command finished
    echo restarting some-command ...
done &

Обратите внимание на & после done.

Для других задач, wait, вероятно, лучшая идея, чем использование управления заданиями в сценарии оболочки. Опять же, это будет зависеть от того, что именно вы пытаетесь делать.

...