Как отложить процесс в фоновом режиме, пока он не будет готов к работе, в оболочке - PullRequest
0 голосов
/ 20 мая 2010

У меня есть два процесса: сервер, который должен работать в фоновом режиме, но начинает обслуживать запросы после задержки, и клиент, который должен быть запущен, когда сервер готов.Сервер печатает строку, связывающуюся с «Acceptin connections», на свой stderr, когда он готов (сервер stderr перенаправляется в файл при запуске его в фоновом режиме).

Как отложить перевод сервера в фоновый режим, пока сервер не будет готов обслуживать запросы?Кроме того, как отложить запуск клиента до готовности сервера?

Язык: сценарий оболочки (или дополнительно Perl).


Добавлено 2010-05-19 22:34 + 0000 :

Заранее известно, какой TCP-порт сервер будет прослушивать для запросов.

Примечание: сервер - это веб-сервер (запущено выполнениеHTTP :: Server :: PSGI), клиент является веб-браузером, например, lynx.

Ответы [ 4 ]

2 голосов
/ 20 мая 2010

У вас может быть цикл while, который продолжает проверять файл журнала сервера для этой строки. grep вернет 1, если совпадений не найдено:

false
while [ $? != 0 ]; do
    grep 'Accepting connections' server.log
done
run-client
0 голосов
/ 28 мая 2010

Ниже приведено текущее решение, которое я использую, которое использует shell + Perl. Он использует занятый цикл , но универсален (должен быть независимым от операционной системы).

# any untaken local port will do...
port=1234

#...

httpd_is_ready () {
    "$PERL" -MIO::Socket::INET -e "
local \$| = 1; # turn on autoflush
exit if (IO::Socket::INET->new('127.0.0.1:$port'));
print 'Waiting for \'$httpd\' to start ..';
do {
    print '.';
    sleep(1);
} until (IO::Socket::INET->new('127.0.0.1:$port'));
print qq! (done)\n!;
"
}

#...

start_httpd
url=http://127.0.0.1:$port
httpd_is_ready && "$BROWSER" "$url" || echo $url

IO :: Socket :: INET в ядре Perl с 5.006 (perl v5.6.0).

0 голосов
/ 20 мая 2010

Чтобы отложить процесс сервера в фоновом режиме до тех пор, пока сервер не будет готов обслуживать запросы, у вас может быть сценарий, который запускается на переднем плане, выполняет настройку и / или взаимодействие с пользователем, а затем, когда он будет готов, он может запустить дочерний сценарий в фон с доступом к экспортированным родительским переменным и функциям, а затем выйти. Или он может запустить подоболочку в фоновом режиме с доступом к всем родительским переменным и функциям.

Вот простой демонстрационный скрипт версии subshell:

#!/bin/bash
reps=6                # vars in the parent are available in the subshell
var=123

f() { echo "$@"; }    # a function in the parent is available in the subshell

f "starting"

# this read represents a startup delay for setup, etc., and/or user interaction
read -p "continue now? "

(       # start the subshell
    for ((i=1; i<=reps; i++))
    do
        f "$var" > "/tmp/bg.$$.$i"
        # $$ will be meaningless when the parent script exits
        # because, though it will have the value of the PID of the parent script
        # the parent script will have exited leaving PID=1 (init) as the PPID of the subshell
        # However $BASHPID will be the PID of the backgrounded subshell
        sleep 10    # busy work
    done
) &     # put it in the background

f "process running in background"
f "ending parent"

Кстати, если подоболочка не была отправлена ​​в фоновый режим, ее изменения в ее окружении не будут доступны его родителю (что в любом случае также верно в вышеприведенном примере).

0 голосов
/ 20 мая 2010

Используйте цикл while:

while :
do
    if ssh root@127.0.0.1 -p 1202 echo > /dev/null 2>&1
    then
        echo Server is ready!
        exit 0
    else
        echo Waiting for server ...
        sleep 1
    fi
done

Вместо ssh вам нужно подключиться к серверу через telnet или что-то еще, что возвращает успех.

...