【问题标题】:Script to count number of connections using a range of TCP ports使用一系列 TCP 端口计算连接数的脚本
【发布时间】:2012-10-10 21:02:56
【问题描述】:

我正在使用以下脚本来计算已建立的连接数,以及特定 TCP 端口范围的时间等待状态。

脚本使用 netstat 和 egrep 来尝试过滤掉有效的连接。该脚本还从文件中读取输入并计算观察到的连接数。

#!/bin/bash
START=121
END=9089

[ -f /tmp/ports.txt ] && rm -f /tmp/ports.txt

for ((a=$START; a <= $END; a++)); do
    netstat -an | nawk '/TIME_WAIT|ESTABLISHED/ && !/127.0.0.1/{split($4,a,".");print a[5]}' | egrep -c ^${a}$ | \
    awk -v x=$a '\
    $0 != 0 {printf("%d %d\n",x,$0)}' | tee -a /tmp/ports.txt
done

awk -v s=$START -v e=$END '\
    BEGIN{t=0}
    {t=t+$2}
    END{printf("\nTotal Connections on ports %d-%d: %d\n",s,e,t)}' /tmp/ports.txt

rm -f /tmp/ports.txt

我正在寻找提高脚本性能的方法。使用当前的端口范围 (121-9089) 大约需要 77 秒才能完成。

我正在寻找提高性能的建议以及示例脚本。

【问题讨论】:

    标签: tcp awk grep ports connection


    【解决方案1】:

    您正在运行 netstat -an 超过 8000 次,并且一次只提取一个端口。

    我会用不同的逻辑改变你的主循环:

    netstat -na | grep -E "TIME_WAIT|ESTABLISHED" | while read line; do
        port=`echo $line | awk -F":" ' { print $2 }' | awk ' { print $1 }'` #<--- get here your port
        [ $port -ge $START ] && [ $port -le $END ] && echo $line | tee -a /tmp/ports.txt #<---- put only the selected range
     done
    

    这样您将只netstat 一次。

    请注意,在我的示例中,您需要更改 awk 逻辑。

    【讨论】:

    • 谢谢你的例子。现在脚本在不到一秒的时间内完成。您关于不调用 netstat 8000 次的建议非常有帮助。 +1
    【解决方案2】:

    一种方式:

    netstat -an | 
    awk -v start=121 -v end=9089 '
        $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ { 
            split( $4, a, /:/ ); 
            if ( a[2] >= start && a[2] <= end ) { 
                ++connections; 
            } 
        } 
        END { 
            printf("\nTotal Connections on ports %d-%d: %d\n", start, end, connections ); 
        }
    '
    

    【讨论】:

      【解决方案3】:

      Birei,使用你上面的例子,脚本已经稍微改变了。

      #!/bin/bash
      OS=$(uname)
      
      case "$OS" in
          'SunOS')
                  AWK=/usr/bin/nawk
                  ;;
          'Linux')
                  AWK=/bin/awk
                  ;;
          'AIX')
                  AWK=/usr/bin/awk
                  ;;
      esac
      
      netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ {
          if ($1 ~ /\./)
                  {sip=$1}
          else {sip=$4}
      
          if ( sip ~ /:/ )
                  {d=2}
          else {d=5}
      
          split( sip, a, /:|\./ )
      
          if ( a[d] >= start && a[d] <= end ) {
                  ++connections;
                  }
          }
          END {print connections}'
      

      我们将它与我们的网络监控工具一起使用。 (扎比克斯) 我已经使用 solaris 10、Linux 6.3 和 AIX 7 测试了该脚本,该脚本按预期工作,并说明了 netstat 输出其列的方式的差异以及分隔符的差异。 IE。这 。或 : 出现在第 2 列或第 4 列中。它检查第一列是否包含 .并相应地设置变量 sip ,然后确定是 a : 还是 a 。用作端口分隔符。

      其余部分大致相同。

      谢谢你的榜样!

      【讨论】:

      • 我没有考虑 UNIX 风格之间的差异,但很高兴我的部分解决方案对您有所帮助。我将不得不投票赞成这个:-)
      猜你喜欢
      • 2018-04-10
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 2019-01-10
      相关资源
      最近更新 更多