首先,关于术语的说明...
“背景”和“前景”被控制端的概念,即,他们与当你键入CTRL + C,CTRL会发生什么做+ Z等(哪个进程得到信号),进程是否可以从终端设备读取(“后台”进程得到默认使其停止的SIGTTIN
)等等。
看起来很清楚,这与您想要达到的目标无关。相反,你有一个不适合的程序(或程序套件)需要一些特别的窍门:当服务器第一次启动时,它需要一些手持到某个点,然后就可以了。一旦输出一些文本字符串,手持可以停止(请参阅您的相关问题或下面的技术)。
这里有一个很大的潜在的问题:很多程序,当其输出重定向到一个管道或文件,产生没有输出,直到他们已经打印输出的“块”的价值,或者退出。如果是这种情况,一个简单的:
start-server-command | cat
不会打印您正在寻找的线(所以这是一个快速的方法来告诉你是否有解决这个问题,也是)。如果是这样,你需要类似expect,这是一种完全不同的方式来实现你想要的。
尽管这并不是问题,但我们可以尝试一种全面的方法。
你需要的是运行start-server-command
并保存进程ID,这样就可以(最终)发送一个SIGINT
信号(如CTRL + C想,如果过程“在前台”为,但是你是通过脚本来完成这项工作的,而不是通过控制终端进行的,所以脚本没有按键)。幸运的是sh
仅仅为此提供了一种语法。
首先,让我们做一个临时文件:
#! /bin/sh
# myscript - script to run server, check for startup, then run tests
TMPFILE=$(mktemp -t myscript) || exit 1 # create /tmp/myscript.<unique>
trap "rm -f $TMPFILE" 0 1 2 3 15 # arrange to clean up when done
现在启动服务器,并保存其PID:
start-server-command > $TMPFILE & # start server, save output in file
SERVER_PID=$! # and save its PID so we can end it
trap "kill -INT $SERVER_PID; rm -f $TMPFILE" 0 1 2 3 15 # adjust cleanup
现在,你想通过$TMPFILE
扫描直到出现所需的输出,在另一个问题。因为这需要一定数量的轮询,所以应该插入一个延迟。检查服务器是否失败并终止而没有进入“开始”点也可能是明智之举。
while ! grep '^Server started, Press Control+C to exit$' >/dev/null; do
# message has not yet appeared, is server still starting?
if kill -0 $SERVER_PID 2>/dev/null; then
# server is running; let's wait a bit and try grepping again
sleep 1 # or other delay interval
else
echo "ERROR: server terminated without starting properly" 1>&2
exit 1
fi
done
(这里kill -0
用于测试的过程中是否仍然存在;如果没有,它已经退出了“清理” kill -INT
会产生错误信息,但是这可能OK如果没有,要么重定向kill
命令的错误输出,或者调整清理或手动执行,如下所示。)
此时,服务器正在运行,您可以执行测试。当你想让它退出,就好像用户点击了ctrl + C,发送一个SIGINT
与kill -INT
。
由于有一个在trap
集,用于当脚本退出kill -INT
(0)时以及当它是由SIGHUP
终止(1),SIGINT
(2),SIGQUIT
(3),和SIGTERM
(15) - 这就是在:
trap "do some stuff" 0 1 2 3 15
部分你可以简单地让你的脚本在此时退出,除非你要专门等待服务器退出了。如果你想,也许:
kill -INT $SERVER_PID; rm -f $TMPFILE # do the pre-arranged cleanup now
trap - 0 1 2 3 15 # don't need it arranged anymore
wait $SERVER_PID # wait for server to finish exit
将是适当的。
(显然没有上面的测试,但是这是总体框架。)
这应该工作过,并避免与我的方法轮询问题。尽管隐藏服务器的输出可能会更好,就像临时文件方法一样。 (但我认为我们都同意,“最好”的方法是修复服务器:-)) – torek
绝对修复服务器是正确的方法。正如你在答案中提到的那样,缓冲也是一个问题,我可怕的黑客根本就没有处理这个问题。 –