Bash 如何使用netcat等待开放端口?
我想做一个有詹金斯在上面的自定义dockerfile。我希望等到端口8080打开,而不是用netcat做一个丑陋的“睡眠60”,但我对bash脚本和netcat不是很有信心 下面是我尝试做的一个例子:Bash 如何使用netcat等待开放端口?,bash,shell,netcat,Bash,Shell,Netcat,我想做一个有詹金斯在上面的自定义dockerfile。我希望等到端口8080打开,而不是用netcat做一个丑陋的“睡眠60”,但我对bash脚本和netcat不是很有信心 下面是我尝试做的一个例子: #!/bin/bash opened=0 while [ "$opened" == "0" ]; do echo "Waiting jenkins to launch on 8080..." nc -vz localho
#!/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"
我发现这是一个非常常见的问题,可以编写一个实用程序来等待端口打开,并有一个可选的超时:
# without timeout
wait-port localhost:8080
# timeout after a minute
wait-port -t 60000 localhost:8080
它是开源的,可在以下站点获得。希望其他人会发现它有用 根据建议,如果您没有安装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"
要扩展user987339的答案,下面介绍如何在终端中轻松等待端口: waitport函数 将此函数添加到~/.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
选项
## 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:无效选项--“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
再加上上面的优秀答案,如果这是经常使用的东西,那么为此目的使用工具可能是值得的。我一直在编写和使用这个用例
在您的示例中,要运行的命令是:
uup localhost:8080 -r
提供如下输出:
我编写了一个等待端口打开的实用程序,它还可以检查MySQL、PostgreSQL、Redis等的可用性
# Checking TCP port
wait4x tcp localhost:8080
# Checking TCP port with specific timeout (5 Minutes)
wait4x tcp localhost:8080 -t 5m
它是开源的,可在以下站点获得。希望其他人会发现它有用 这里是一个有超时的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
最后,我使用了一个curl脚本来完成它:while!curl--output/dev/null--silent--head--failhttp://localhost:8080; 执行睡眠1&&echo-n。;完成作为建议,您还可以减少netcat命令中的连接超时,以便在Jenkins起床时获得更快的响应。它是,nc-g1-zlocalhost 8000
。nc:invalid选项--'z'如果使用man,您将看到它不是无效选项:“-z指定nc只扫描侦听守护程序,而不向它们发送任何数据。将此选项与-l选项结合使用是错误的。”在CentOS 7上的netcat存储库版本中,没有-z选项。我认为软呢帽也是如此。我需要从源代码处安装netcat以获得-z选项。纯bash版本很棒!可以使用很多场景。非常感谢。我想知道为什么>
,而不是
。>
更安全,因为它不会创建新文件或覆盖现有文件。我想知道,echo>。
是否曾经阻止过?在什么情况下?