我有一个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"
我该怎么做?
答案 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