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

我想做一个有詹金斯在上面的自定义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"

我发现这是一个非常常见的问题,可以编写一个实用程序来等待端口打开,并有一个可选的超时:

# 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。;完成nc-g1-zlocalhost 8000
。nc:invalid选项--'z'如果使用man,您将看到它不是无效选项:“-z指定nc只扫描侦听守护程序,而不向它们发送任何数据。将此选项与-l选项结合使用是错误的。”在CentOS 7上的netcat存储库版本中,没有-z选项。我认为软呢帽也是如此。我需要从源代码处安装netcat以获得-z选项。纯bash版本很棒!可以使用很多场景。非常感谢。我想知道为什么
>
,而不是
>
更安全,因为它不会创建新文件或覆盖现有文件。我想知道,
echo>。
是否曾经阻止过?在什么情况下?