Bash脚本检查哪个端口正在侦听,如果正在侦听,则运行命令

Bash脚本检查哪个端口正在侦听,如果正在侦听,则运行命令,bash,port,Bash,Port,我是bash脚本新手,我正在尝试编写一个bash脚本,其中从某个端口开始,检查它是否正在侦听,如果正在侦听,则运行一个命令,如果在找到一个正在侦听的端口之前不增加端口号,将非常感谢任何帮助 PORT=8080 a=$(netstat -plnt | grep $PORT | awk '{print $6}') #echo $a;exit while [ "$a" != "LISTEN" ] do (( PORT=PORT+1 )) printf "Port number is $PORT\n

我是bash脚本新手,我正在尝试编写一个bash脚本,其中从某个端口开始,检查它是否正在侦听,如果正在侦听,则运行一个命令,如果在找到一个正在侦听的端口之前不增加端口号,将非常感谢任何帮助

PORT=8080
a=$(netstat -plnt | grep $PORT | awk '{print $6}')
#echo $a;exit
while [ "$a" != "LISTEN" ]
do
 (( PORT=PORT+1 ))
 printf "Port number is $PORT\n"
done
#run command
  • netstat(nettools)已被弃用,可能您希望使用其他工具(ss、lsof、fuser等)
  • 即使netstat已被弃用,您也可能希望udp使用
    u
  • 您需要使用root权限运行脚本,以便能够检测正在侦听这些端口的进程,而不管其所有者是谁
  • 使用
    lsof
    ,您可能可以保存
    grep
    awk
    进程,例如:
    (root)lsof-i:8080
  • 您可能需要考虑的另一件事:

    您可能希望首先获取所有“已占用”的端口,然后选择一个空闲插槽,而不是
    循环(端口+++->检查)
    。否则,您可能会运行netstat(或其他工具)十几到几百次。

    出现一些问题:
    • 如果任何PID匹配,则在整个
      netstat-tnlp行上搜索$PORT将匹配
      *8080.*
      (进程808018080..58080)
    • grep | awk可以简化
    • 奇怪的循环谁打印每个端口号直到自由端口
    但由于它在基于Linux的服务器上运行 您可以使用
    /proc/net/tcp
    而不是
    netstat
    ,然后

    • /proc/net/tcp*
      中,如果侦听,则第4列显示
      0A
    • IP地址和端口为十六进制
    • /proc/net/tcp*
      将同时引用
      /proc/net/tcp
      /proc/net/tcp6
    因此:

    我必须做这项工作

    可供替代的从列表中保留已占用的端口 准备可用端口列表(从8080到10000):


    我不明白这样做的目的是什么?在docker容器找到可用端口时运行它。为什么netstat被弃用?它只存在于Debian中吗@斯蒂芬:是的。请阅读netstat手册页。也可以在纯bash中完成,而无需生成外部命令,还可以考虑IPv6:
    PORT=8080;虽然[[“$(@LéaGris)我对bash的正则表达式很小心!特别是阅读这样的整个文件,但谁在高负载服务器上会变得非常庞大。@LéaGris Syntax
    。$(printf…
    意味着一个fork!
    printf-v myvar;…“$myvar“…
    可能会阻止它们。但是@LéaGris感谢您提请我注意
    tcp
    tcp6
    !回答正确!或者
    /proc/net/@(tc|ud)p@(6|)
    PORT=8080
    while printf -v regex ':%04X .* 0A ' $PORT;grep -q "$regex" /proc/net/tcp*;do
        ((PORT++))
      done
    echo First free port number: $PORT
    
    freeport() { 
        local allports;
        printf -v allports "[%s]='' " {8080..10000};
        local -a allports="($allports)";
        local pfile sl la lp ra rp st foo;
        for pfile in tcp{,6}; do
          { 
            read foo;
            while IFS=$' :\r\t\n' read sl la lp ra rp st foo; do
                [ "$st" = "0A" ] &&
                    printf -v lp %d 0x$lp &&
                    unset allports[lp]
            done
          } < /proc/net/$pfile;
        done;
        local port=(${!allports[@]});
        echo $port
    }
    
    freeport
    8082