bash检查给定的端口范围(如果正在使用),并告知是否全部在使用中

时间:2019-02-02 00:59:53

标签: bash

我有一个bash脚本,该脚本检查给定的端口范围,查看是否有任何端口在使用中,然后选择一个未使用的端口;

starting_port=5550
ending_port=5650

function check_port {
        echo "I'm going to find an open port to use"
        for i in $(seq $starting_port $ending_port); do
                if ! lsof -Pi :$i -sTCP:LISTEN -t >/dev/null; then
                        echo "$i not in use, I'm going to choose this one"
                        port_to_use=$i
                fi
        done
}

check_port

但是,我想进一步检查一下所有端口是否都在使用中,返回类似以下内容;

echo "I couldn't find a port to use, all given ports are in use"

我该怎么做?

2 个答案:

答案 0 :(得分:2)

如果我从您的最后一条评论中了解到,您正在使用数千个端口,并且希望能够设置一些起始端口号,并遍历该端口号,直到找到可用的port_to_use,那么您可以使用如上所述的netstat,并使用GNU awk(例如gawk)来找到第一个可用的文件,而不会带来很多麻烦。

例如,调用上述的netstat命令,然后使用awk首先设置port_to_use = minimum_port并使用所有正在使用的 ports ,然后使用END规则对使用中的端口进行排序和迭代,每次迭代将port_to_use递增1,直到使用中的端口,例如(a[i] > port_to_use),您可以找到第一个可用端口。

一个短调用gawk应该这样做:

#!/bin/bash

netstat --numeric --numeric-ports | 
awk -F'[ \t:]*' -v port_to_use=32000 '/[:]/ {
    a[i++] = $5
}
END {
    n = asort (a)
    for (i = 1; i <= n; i++)
        if (a[i] == port_to_use)
            port_to_use++
        else
            break;
    print "port to use:", port_to_use
}'

只要保存它,并调用它:

$ bash nameyousaveditin
port to use: 32000

(或仅仅设置最小端口号和复制/粘贴到终端而不#!/bin/bash

示例

在我的情况下在使用中的端口是:

36226
36998
38728
46894
49756
52194
54686
...

最初设定port_to_use=36226,得到:

$ bash find_port_to_use
port to use: 36227

添加 end_port

您可以添加end_port限制要考虑提供给END规则的端口数量。下面将只能从最小的到考虑端口end_port。 (你也能重新来,只是添加了一些考虑,比如150,只是从最小做数学题)

#!/bin/bash

netstat --numeric --numeric-ports | 
awk -F'[ \t:]*' -v port_to_use=32000 -v end_port=32050 '/[:]/ {
    a[i++] = $5
}
END {
    n = asort (a)
    for (i = 1; i <= n && a[i] <= end_port; i++)
        if (a[i] == port_to_use)
            port_to_use++
        else
            break;
    if (port_to_use > end_port)
        print "no ports available in range"
    else
        print "port to use:", port_to_use
}'

end_port只是作为附加变量添加到awk命令的开头,并在END规则中使用。

是`netstat的--listening

要让netstat报告本地listening端口,请在--listening命令中添加netstat选项,并进行额外的检查以确保该端口是数字端口,并且不只是'*'。进行更改,可以按如下方式改变第一部分:

netstat --numeric --numeric-ports --listening | 
awk -F'[ \t:]*' -v port_to_use=32000 -v end_port=32050 '/[:]/ {
    if ($5 ~ '/[0-9][0-9]*/')
        a[i++] = $5
}
## rest is the same

将其与本地端口一起使用,它将我正在使用的端口列出为:

22
25
25
68
123
123
123
123
631
631
2677
5353
51310

(似乎更接近您要查找的范围)

试一下,如果您还有其他问题,请告诉我。

答案 1 :(得分:0)

我自己设法找到了解决方案,这确实比我想象的要容易。

#!/bin/bash

starting_port=5550
ending_port=5650

function check_port {
    echo "I'm going to find an open port to use"
    for i in $(seq $starting_port $ending_port); do
        if ! lsof -Pi :$i -sTCP:LISTEN -t >/dev/null; then
            echo "$i not in use, I'm going to choose this one"
            port_to_use=$i
        elif [ "$i" == "$ending_port" ]; then < I've simply added this part.
            echo "no port to use"
        fi
    done
}

check_port

使用netstat而不是lsof的快速解决方案;

#!/bin/bash

starting_port=5550
ending_port=5650

for i in $(seq $starting_port $ending_port); do
    if ! [[ $(sudo netstat -plnt | grep ":$i") ]]; then
        echo "$i not in use, I'm going to choose this one"
        port_to_use=$i
        break
    elif [ "$i" == "$ending_port" ]; then
        echo "no ports to use"
    fi
done