1

我正在使用以下脚本来计算已建立的连接数,以及特定 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 秒才能完成。

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

4

3 回答 3

2

您运行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我示例中的逻辑。

于 2012-10-10T21:25:23.760 回答
1

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}'

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

其余的都差不多。

谢谢你的榜样!

于 2012-10-12T15:55:53.490 回答
1

单程:

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 ); 
    }
'
于 2012-10-10T21:26:06.867 回答