Возвращаемое значение фонового процесса - PullRequest
6 голосов
/ 18 июля 2011

Мне нужно предпринять некоторые действия, основанные на возвращаемом значении фонового процесса, то есть, если он заканчивается в первую очередь.

В частности: при идеальной работе сервер, который я использую в качестве фонового процесса, будет работать вечно. В таких случаях сохранение его в фоновом режиме имеет смысл, поскольку я хочу, чтобы мой сценарий оболочки выполнял другие действия после запуска сервера. Но если сервер завершает работу ненормально, я хочу предпочтительно использовать возвращаемое значение выхода с сервера, чтобы решить, уничтожить ли мой основной скрипт или нет. Если это невозможно, я по крайней мере хочу прервать основной сценарий, а не запускать его на неисправном сервере.

Я ищу что-то вроде асинхронного обратного вызова для сценариев оболочки. Одним из решений является создание процесса мониторинга, который периодически проверяет, не вышел ли сервер из строя или нет. Желательно, чтобы я делал это без основного сценария оболочки.

Ответы [ 3 ]

2 голосов
/ 19 июля 2011

Вы можете использовать ловушки оболочки для вызова функции при выходе из дочернего процесса путем перехвата SIGCHLD.Если запущен только один фоновый процесс, вы можете wait сделать это в обработчике sigchld и получить статус там.Если работает несколько фоновых дочерних элементов, это становится немного сложнее;Вот пример кода (тестируется только с bash):

set -m # enable job control
prtchld() {  
  joblist=$(jobs -l | tr "\n" "^")
  while read -a jl -d "^"; do
    if [ ${jl[2]} == "Exit" ] ; then 
      job=${jl[1]} 
      status=${jl[3]}  
      task=${jl[*]:4}
      break  
    fi  
  done <<< $joblist
  wait $job 
  echo job $task exited: $status
}
trap prtchld SIGCHLD

(sleep 5 ; exit 5) &
(sleep 1 ; exit 7) &

echo stuff is running

wait
0 голосов
/ 20 июля 2011

Мне больше нравится первый для моих целей, я полагаю, что в «сделать что-то здесь, если процесс не удалось», я могу убить скрипт, который вызвал этот скрипт-обертку для foo, используя его имя.

Я думаю, что первое решение хорошо работает для нескольких детей.В любом случае, мне нужно было сделать это быстро, поэтому я использовал хак, который работает для моего приложения:

Я запускаю процесс в фоновом режиме, как обычно, в основном скрипте, затем использую $!чтобы получить его pid (так как $! возвращает последний bg pid), поспите 2 секунды и выполните ps -e |grep pid, чтобы проверить, продолжается ли процесс на основе возвращаемого значения (ps -e | grep pid).Это хорошо работает для меня, потому что, если мой фоновый процесс прерывается, он делает это немедленно (потому что адрес используется).

0 голосов
/ 19 июля 2011

Вы можете вложить фоновый процесс в скрипт. Например, если процесс, который вы хотите отправить в фоновый режим, называется foo:

#!/bin/sh

foo

if [ $? ]
then 
    # do something here if process failed
fi

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

...