[英]How to wait for an open port with netcat?
我正在尝试使用 jenkins 进行自定义 dockerfile。 我会等到 8080 端口打开,而不是用 .netcat 做一个丑陋的“睡眠 60”,但我对 bash 脚本和 .netcat 不是很有信心。
这是我正在尝试做的一个例子:
#!/bin/bash
opened=0
while [ "$opened" == "0" ]; do
echo "Waiting jenkins to launch on 8080..."
nc -vz localhost 8080
done
echo "Jenkins launched"
您不能将 netcat 设置为等到某个端口打开,因此您必须在下一次检查之前添加等待部分。 尝试这个:
#!/bin/bash
echo "Waiting jenkins to launch on 8080..."
while ! nc -z localhost 8080; do
sleep 0.1 # wait for 1/10 of the second before check again
done
echo "Jenkins launched"
我建议使用以下一种衬垫:
## netcat version:
timeout 22 sh -c 'until nc -z $0 $1; do sleep 1; done' stackoverflow.com 443
## pure bash version:
timeout 22 bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/$0/$1; do sleep 1; done' stackoverflow.com 443
一旦建立连接,这两个命令都会退出,每秒尝试一次,最多 22 秒。
请注意,由于timeout
命令,当端口可访问时退出代码为0
,否则为124
(如果在给定时间内未建立连接)。
正如这里所建议的,如果您没有安装nc
而只有bash
和coreutils
,您也可以执行以下操作:
#!/bin/bash
echo "Waiting jenkins to launch on 8080..."
while ! timeout 1 bash -c "echo > /dev/tcp/localhost/8080"; do
sleep 1
done
echo "Jenkins launched"
我发现这是一个足够常见的问题,可以编写一个实用程序来等待端口打开,并带有可选的超时:
# without timeout
wait-port localhost:8080
# timeout after a minute
wait-port -t 60000 localhost:8080
它是开源的,可从github.com/dwmkerr/wait-port 获得。 希望其他人会发现它有用!
要扩展 user987339 的回答,以下是在终端中轻松等待端口的方法:
将此函数添加到您的 ~/.bashrc 安装文件中:
waitport() {
while ! nc -z localhost $1 ; do sleep 1 ; done
}
注销然后重新登录以加载 ~/.bashrc。 然后,运行此命令以验证端口 3000 是否有服务器侦听它:
$ waitport 3000
Connection to localhost port 3000 [tcp/hbci] succeeded!
这已在 macOS 上得到验证。 它可能不适用于 Fedora/CentOS,因为它们缺少netcat
的-z
选项。
对于那些遇到nc: invalid option -- 'z'
我试图在 docker 镜像中设置它。 令人惊讶的是,该图像中的nc
中没有-z
选项。
图像是 - Linux elasticsearch 4.4.0-101-generic #124~14.04.1-Ubuntu SMP Fri Nov 10 19:05:36 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
我使用以下循环等待端口打开。
#!/bin/bash
echo "Waiting elastic search to launch on 9200..."
open=0;
while [ $open -eq 0 ]
do
check_port=`nc -v -w 1 -i 1 127.0.0.1 9200 &> /dev/stdout`
echo $check_port
if [[ "$check_port" == *"Connected to"* ]]
then
break
fi
sleep 1
done
echo "Elastic Search launched"
以下是上述脚本的一行代码:
open=0;while [ $open -eq 0 ]; do check_port=`nc -v -w 1 -i 1 127.0.0.1 9200 &> /dev/stdout`; echo $check_port; if [[ "$check_port" == *"Connected to"* ]]; then break; fi; sleep 1; done
这是一个具有超时的 for 循环示例,因此它尝试了例如 10 次,指数退避(2、4、8、16 秒等),但最终放弃。 Netcat 也有 1 秒超时。
for EXPONENTIAL_BACKOFF in {1..10}; do
nc -w 1 -z db.local 3306 && break;
DELAY=$((2**$EXPONENTIAL_BACKOFF))
echo "db not yet available, sleeping for $DELAY seconds"
sleep $DELAY
done
输出是:
db not yet available, sleeping for 2 seconds
db not yet available, sleeping for 4 seconds
db not yet available, sleeping for 8 seconds
db not yet available, sleeping for 16 seconds
我编写了一个实用程序来等待端口打开,它还可以检查 MySQL、PostgreSQL、Redis 等可用性。
# Checking TCP port
wait4x tcp localhost:8080
# Checking TCP port with specific timeout (5 Minutes)
wait4x tcp localhost:8080 -t 5m
它是开源的,可从https://github.com/atkrad/wait4x 获得。 希望其他人会发现它有用!
在 CI 上运行测试之前,我使用此脚本检查端口。
#!/bin/bash
for _ in `seq 1 20`; do
echo -n .
if nc -z localhost $1; then
exit 0
fi
sleep 0.5
done
exit 1
$ bin/wait-port 3306
这是我的单行 Bash 解决方案(使用 netcat),它等待 TCP 连接 10 秒,并在等待时向您反馈是否成功,如果端口打开则返回退出
0<\/code>代码,否则返回
1<\/code> :
bash -c 'echo -n "Waiting port 8080 .."; for _ in `seq 1 40`; do echo -n .; sleep 0.25; nc -z localhost 8080 && echo " Open." && exit ; done; echo " Timeout!" >&2; exit 1'
我用它来等待几个端口打开,没有 netcat:
while (! (: </dev/tcp/localhost/27017) &> /dev/null || ! (: </dev/tcp/localhost/9200) &> /dev/null); do
sleep 2;
done
根据需要更改localhost
和端口。
如果您正在寻找 docker-run-one-liner,请查看我基于 .netcat 循环的Docker 图像:
$ docker run --rm igops/wait-for-port HOST PORT
例如,
$ docker run --rm igops/wait-for-port 172.17.0.1 80
将每0.1s
查询172.17.0.1:80
并在建立连接时退出:
Waiting for 172.17.0.1:80...
OK
等待另一个容器响应:
$ docker network create my-bridge
$ docker run --rm -d --net my-bridge --net-alias my-mongo mongo
$ docker run --rm --net my-bridge igops/wait-for-port my-mongo 27017
$ echo "Mongo is up at this point, do some useful stuff here"
等待 docker 主机上的一些服务:
$ docker run --rm --add-host="docker-host:host-gateway" igops/wait-for-port docker-host 22
$ echo "SSH server is running"
等待另一个发布了一些端口的容器:
$ docker run --rm -d -p 27017:27107 mongo
$ docker run --rm --add-host="docker-host:host-gateway" igops/wait-for-port docker-host 27017
$ echo "Mongo is up"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.