0

我有两个进程:一个应该在后台运行的服务器,但在延迟后开始为请求提供服务,一个客户端应该在服务器准备好时启动。准备好后,服务器将包含“Acceptin connections”的行打印到其标准错误(服务器标准错误在后台运行时被重定向到文件)。

如何延迟将服务器进程置于后台,直到服务器准备好服务请求?或者,如何延迟运行客户端直到服务器准备好?

语言:shell 脚本(或可选的 Perl)。


添加2010-05-19 22:34 +0000

预先知道服务器将侦听哪个 TCP 端口以获取请求。

注意:服务器是 web 服务器(运行 HTTP::Server::PSGI 的 plackup),客户端是 web 浏览器,例如 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 循环:

尽管 :
做
    如果 ssh root@127.0.0.1 -p 1202 echo > /dev/null 2>&1
    然后
        echo 服务器已准备就绪!
        出口 0
    别的
        echo 等待服务器...
        睡觉 1
    菲
完毕

而不是 ssh,您需要 telnet 或其他返回成功的服务器。

于 2010-05-19T21:53:06.600 回答
0

下面是我使用的当前解决方案,它使用 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自 5.006 (perl v5.6.0) 起就在 Perl 核心中。

于 2010-05-28T10:16:03.673 回答
0

为了将服务器进程置于后台,直到服务器准备好为请求提供服务,您可以有一个在前台启动的脚本,执行设置和/或用户交互,然后当它准备好时,它可以在后台启动一个具有访问权限的子脚本到父级导出的变量和函数,然后退出。或者它可以在后台启动一个子shell,可以访问所有父变量和函数。

下面是 subshel​​l 版本的简单演示脚本:

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

顺便说一句,如果子shell 没有被发送到后台,它对其环境的更改将不会对其父级可用(无论如何,在上面的演示中也是如此)。

于 2010-05-20T03:08:41.540 回答