寻找下一个开放端口

时间:2011-08-04 13:15:43

标签: bash unix shell cygwin

有没有办法,使用基本的Unix命令,找到下一个未使用的端口号,从端口4444开始向上?我是(通过openssh)进入Windows XP机器,运行Cygwin工具并使用bash shell。

谢谢, - 戴夫

3 个答案:

答案 0 :(得分:10)

试试这个:

for port in $(seq 4444 65000); do echo -ne "\035" | telnet 127.0.0.1 $port > /dev/null 2>&1; [ $? -eq 1 ] && echo "unused $port" && break; done

,其中

seq 4444 65000 - port range for check
echo -ne "\035" - escape character to force close telnet session (^])

如果telnet完成,退出代码1表示连接被拒绝:

$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
$ echo $?
1

否则我们决定连接成功,退出代码为0.

修改 特别适用于cygwin:您需要安装包含telnet端口的附加软件包inetutils并使用以下脚本:

for port in $(seq 4444 65000); do echo -ne "\035" | /usr/bin/telnet 127.0.0.1 $port > /dev/null 2>&1; [ $? -eq 1 ] && echo "unused $port" && break; done

答案 1 :(得分:4)

Same as above, but written as a function

function get_unused_port() {
  for port in $(seq 4444 65000);
  do
    echo -ne "\035" | telnet 127.0.0.1 $port > /dev/null 2>&1;
    [ $? -eq 1 ] && echo "$port" && break;
  done
}
FREE_PORT="$(get_unused_port)"
echo $FREE_PORT

答案 2 :(得分:2)

以下函数不依赖于telnet / netcat,因为它在本地端口范围内生成一个随机端口,并将其与运行应用程序当前使用的端口列表进行比较。

应该在任何支持proc文件系统的* nix上运行。生成一个免费的短暂端口供您的应用程序使用。

function EPHEMERAL_PORT(){
    while true; do 
        LISTENING_PORTS=$(cat /proc/net/tcp | awk 'NR >1 {print $2}' | awk -F':' '{print $2}');
        LISTENING_PORTS=$(for PORT in ${LISTENING_PORTS}; do echo $((16#${PORT})); done|sort -g);
        # echo "32768 60999" | read LPORT UPORT
        read LPORT UPORT < /proc/sys/net/ipv4/ip_local_port_range
        MPORT=$[$LPORT + ($RANDOM % $UPORT)];
        if (echo "${LISTENING_PORTS[@]}" | grep -xqv $MPORT); then
            echo $MPORT;
            break;
        fi
    done
}

显然是TCP connections can be used as file descriptors在Linux上。以下函数使用该技术,应该比前一个更快。

function EPHYMERAL_PORT(){
    LPORT=32768;
    UPORT=60999;
    while true; do
        MPORT=$[$LPORT + ($RANDOM % $UPORT)];
        (echo "" >/dev/tcp/127.0.0.1/${MPORT}) >/dev/null 2>&1
        if [ $? -ne 0 ]; then
            echo $MPORT;
            return 0;
        fi
    done
}

这是一个跨平台功能,它使用osquery来获取侦听端口列表。也应该适用于Windows。

function EPHYMERAL_PORT(){
    while true; do 
        echo "32768 60999" | read LPORT UPORT
        MPORT=$[$LPORT + ($RANDOM % $UPORT)];
        LISTENING_PORTS=$(osqueryi --header=false --list "select port from listening_ports order by port");
        if (echo "${LISTENING_PORTS[@]}" | grep -xqv $MPORT); then
            echo $MPORT;
            break;
        fi
    done
}

使用说明。将输出绑定到变量并在脚本中使用。在Ubuntu 16.04上测试

root@ubuntu:~> EPHYMERAL_PORT
59453
root@ubuntu:~> PORT=$(EPHYMERAL_PORT)