0

I have two processes: a server that should be run in background, but starts serving requests after a delay, and a client that should be started when server is ready. The server prints line containg "Acceptin connections" to its stderr when ready (server stderr is redirected to a file when running it in background).

How to delay putting server process in background until server is ready to serve requests? Alternatively, how to delay running client until server is ready?

Language: shell script (or optionally Perl).


Added 2010-05-19 22:34 +0000:

It is known upfront which TCP port the server would listen to for requests.

Note: server is web server (plackup running HTTP::Server::PSGI), client is web browser, e.g. lynx.

4

4 に答える 4

2

サーバーのログファイルでその行をチェックし続けるwhileループを作成できます。grep一致するものが見つからない場合は1を返します。

false
while [ $? != 0 ]; do
    grep 'Accepting connections' server.log
done
run-client
于 2010-05-19T21:52:37.443 に答える
0

whileループを使用します。

その間 :
行う
    if ssh root@127.0.0.1 -p 1202 echo> / dev / null 2>&1
    それから
        echo Serverの準備ができました!
        出口0
    そうしないと
        echoサーバーを待機しています..。
        睡眠1
    fi
終わり

sshの代わりに、サーバーにtelnetまたは何かを送信して成功を返す必要があります。

于 2010-05-19T21:53:06.600 に答える
0

In order to elay putting server process in background until server is ready to serve requests, you can have a script that starts in the foreground, performs setup and/or user interaction then when it's ready it can launch a child script in the background with access to the parent's exported variables and functions and then exit. Or it can launch a subshell in the background with access to all the parents variables and functions.

Here's a simple demo script of the subshell version:

#!/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"

By the way, if the subshell had not been sent to the background, its changes to its environment would not be available to its parent (which is also true in the demo above, in any case).

于 2010-05-20T03:08:41.540 に答える
0

Below there is current solution that I use, which uses shell + Perl. It uses busy loop, but is universal (should be independent on operating system).

# 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 is in Perl core since 5.006 (perl v5.6.0).

于 2010-05-28T10:16:03.673 に答える