perl-скрипт для мониторинга и перезапуска прослушивателя зависает на nohup в ожидании возврата каретки

У меня есть прослушиватель tcp/ip, написанный на java, который запускается для нескольких «сайтов», каждый со своим собственным портом. Разработчик, написавший этот слушатель, сделал это отдельно, поэтому мне приходится управлять каждым через скрипт start_comtrol.sh, что довольно утомительно. Я новичок в Perl, но сегодня я написал быстрый скрипт для проверки каждого сравнения pid-файлов, чтобы убедиться, что процесс запущен, и попытаться перезапустить его, если это не так, как показано ниже.

use strict;
use warnings;

my @sites = qw / FOO BAR FOO2 /;

foreach (@sites) {
    my $pidfile = "/usr/local/sbin/listener/$_/pid.file";
    my $start_comtrol = "/usr/local/sbin/listener/$_/start_comtrol.sh";
    open my $file, '<', $pidfile or die 'Could not open file:  ' . $!;
    my $pid = do { local $/; <$file> };
    close $file;
    my $exists = kill 0, $pid;
        if ( $exists ) {
            print "The running process for $_ is $pid\n"; #temp print to screen for debugging
            # Do Nothing
        }
        else {
            exec $start_comtrol;
    }
}

Каждый скрипт start_comtrol.sh идентичен по своему содержанию:

#!/bin/ksh
export CLASSPATH=.:ojdbc6.jar:Base.jar:ojdbc14.jar:log4j.jar
#export CLASSPATH=/home/aspira/controller/ojdbc6.jar:/home/aspira/controller/Base.jar:/home/aspira/controller/ojdbc14.jar
nohup java com.aspira.comtrol.listener.BaseListener  &
echo "$!" > pid.file

Сценарий работает нормально, когда процесс найден запущенным, однако, если процесс не запущен и он пытается запустить его с помощью exec $start_comtrol.sh, он обнаруживает nohup, ожидающий возврата каретки, и не переходит к следующей переменной. в массиве сайтов.

The running process for FOO is 19401

The running process for BAR is 1228

[root@isildur]# nohup: appending output to `nohup.out'

Как лучше всего справиться с этим, чтобы он не зависал из-за неуместной подсказки от nohup?


person Jchieppa    schedule 10.07.2013    source источник


Ответы (1)


Вы ищете функцию system(), а не exec()

Из документа для exec():

Функция exec выполняет системную команду и никогда не возвращается; используйте system вместо exec, если вы хотите, чтобы он вернулся.

Попробуйте вместо этого сделать system( $start_comtrol ).

person Christopher Neylan    schedule 10.07.2013
comment
Переход на систему — это шаг в правильном направлении. Что я замечаю сейчас, так это то, что если только один слушатель не работает, он перезапустится правильно, однако, если несколько не работают, он попытается перезапустить первый отключенный, кажется, X количество $ сайтов, которые не работают. т.е. если и FOO, и BAR не работают и он сначала видит FOO, в журналах FOO вы увидите `Baselistener [2013-07-10 15:09:38,067] — сервер запущен на порту 4000 [2013-07-10 15:09: 40,156] — Не удалось инициализировать приложение. Проверьте свойства приложения, настройки базы данных или порт сокета. Адрес уже используется `был ли Foreach неправильным выбором, вызывающим этот цикл? - person Jchieppa; 11.07.2013
comment
адрес, который уже используется, звучит так, как будто прослушиватель уже запущен, что означает, что содержимое вашего pid-файла устарело. выполните ps -ef и убейте всех работающих прослушивателей, а затем вручную очистите файлы pid и попробуйте перезапустить. также (не связанное, но важное), имейте в виду, что выполнение kill -0 $pid скажет вам, есть ли процесс с запущенным $pid, но только потому, что есть процесс с этим $pid, не обязательно означает, что это ваш слушатель. - person Christopher Neylan; 11.07.2013