如何告诉脚本等待进程开始在端口上接受请求的脚本?


33

我需要一个命令,该命令将等待进程开始在特定端口上接受请求。

linux中有什么可以做到的吗?

while (checkAlive -host localhost -port 13000 == false)
  do some waiting

...

Answers:


52

查看服务器是否接受连接的最佳测试是实际尝试连接。对于服务器使用的协议,请使用常规客户端,然后尝试无操作命令。

如果您需要轻量级的TCP或UDP客户端,则可以从shell轻松驱动,请使用netcat。如何进行对话编程取决于协议。许多协议使服务器在某个输入上关闭连接,然后netcat将退出。

while ! echo exit | nc localhost 13000; do sleep 10; done

您也可以在建立连接后告诉netcat退出。如果没有连接,则返回1,如果没有连接,则返回0,因此我们将其输出取反。根据您的netcat版本,它可能支持以下一个或两个命令:

while ! nc -z localhost 13000 </dev/null; do sleep 10; done
while ! nc -q 1 localhost 13000 </dev/null; do sleep 10; done

另一种方法是等待服务器进程打开监听套接字。

while netstat -lnt | awk '$4 ~ /:13000$/ {exit 1}'; do sleep 10; done

如果您使用的是Mac OS,netstat会使用略有不同的输出格式,因此您需要以下界面:

while netstat -lnt | awk '$4 ~ /\.13000$/ {exit 1}'; do sleep 10; done

或者,您可能要定位特定的进程ID:

while ! lsof -n -Fn -p $pid | grep -q '^n.*:13000$'; do sleep 10; done

我想不出任何方法来对缺少使用的过程做出反应,以开始监听套接字(这将避免轮询方法)ptrace


我认为netcat是答案,所以谢谢。为了澄清,我正在尝试做的是编写脚本作为负载平衡过程的一部分。我需要启动一个进程,等待它接受端口上的请求,然后关闭原始进程。如果有更好的方法来执行此操作,而不是编写自己的脚本,我将不胜枚举。

@Will:这是一个非常不同的问题!我写了一个不同的答案。
吉尔斯(Gillles)“所以-别再邪恶了”

1
我也喜欢netcat解决方案。我有一个脚本在使用nc -w 2 </dev/null >/dev/null-如果连接耗时超过2秒,它将超时并失败-这对于我的使用很方便。
短暂的2011年

仅供参考,我无法获得'while nc -q 1 localhost 13000 </ dev / null; 睡10 完成了一个工作。它只是立即返回。虽然第一个工作正常。谢谢!
Ellis Percival

nc -q 1 localhost 13000 </dev/null如果没有服务器在侦听,@ Flyte 立即返回,但是它返回错误代码,因此循环使它进入睡眠状态,然后在几秒钟后重试。
吉尔斯(Gilles)'所以

17

如果您有bash和coreutils(例如超时,睡眠),但没有nc / lsof / netstat,则可以使用以下使用bash魔术tcp套接字的解决方案:

while ! timeout 1 bash -c "echo > /dev/tcp/localhost/13000"; do sleep 10; done

为了详细说明,Bash有连接到TCP套接字使用“网络重定向”的可选功能- gnu.org/software/bash/manual/html_node/...
johntellsall

7

前一个使用bashtcp sockets magic的示例之后,这是一个增强的版本,它在有限的时间内等待连接。

timeout 15 bash -c 'until echo > /dev/tcp/localhost/13000; do sleep 0.5; done'

区别在于,如果在期间没有可用的连接15s--它不会永远循环,但会返回错误代码。

这在初始化脚本中很有用,可以在启动后等待服务准备就绪/可用性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.