代码之家  ›  专栏  ›  技术社区  ›  Bogdan Stoica

Bash循环通过多行netstat命令输出

  •  0
  • Bogdan Stoica  · 技术社区  · 5 年前

    我正在运行此命令(将输出保存到文本文件:

    netstat -ntp | grep tcp | grep EST | grep 34341
    

    tcp      593      0 10.10.1.11:43856       10.10.2.14:3434      ESTABLISHED     146597/daemon-
    tcp      417      0 10.10.1.11:43859       10.10.2.15:3434      ESTABLISHED     146567/daemon-
    tcp      317      0 10.10.1.11:43121       10.10.2.16:3434      ESTABLISHED     146582/daemon-
    

    #! /bin/bash
    
    SLEEP=5
    COUNTER=0
    
    recvq()
    {
        while read -r proto recvq x local remote state x
        do
            if [[ "$proto" == tcp && "$state" == ESTABLISHED && "$remote" =~ .*:3434 ]]
            then
                printf "%d\n" "$recvq"
            fi
        done < "$1"
    }
    
    while true; do
    
            (( COUNTER++ ))
            # measure recvq value
            declare -A first
            while read -r socket recvq
            do
                first[$socket]=$recvq
            done < <(recvq netstat1.txt)
    
            # sleep
            sleep "$SLEEP"
    
            # measure recvq value after sleep
            declare -A second
            while read -r socket recvq
            do
                second[$socket]=$recvq
            done < <(recvq netstat2.txt)
    
            [ ${#first[*]} != ${#second[*]} ] && { echo "Arrays are different size"; }
    
            for ii in ${!first[*]}; do
                [ "${first[$ii]}" == "${second[$ii]}" ] || { echo different element $ii; exit 1; }
            done
            echo "Arrays are identical"
    
    done
    

    现在我需要比较文件中每一行的recvq(睡眠前)和recvq(睡眠后)的值。如果任何初始recvq值与最终recvq值相同,则采取措施。

    0 回复  |  直到 5 年前
        1
  •  1
  •   ceving    5 年前

    我会这样解析:

    #! /bin/bash
    
    while read proto recvq x x port state x
    do
      if [[ "$proto" == tcp && "$state" == ESTABLISHED && "$port" =~ .*:3434$ ]]
      then
        printf "%d\n" "$recvq"
      fi
    done < <(netstat -ntp)
    

    你不需要 grep , cat awk

    请勿进行复制粘贴编程。如果你有代码,你想重用,把它放在一个函数里。

    Bash具有关联数组,您可以使用它来存储每个套接字接收的数据。

    #! /bin/bash
    
    recvq()
    {
      while read proto recvq x local remote state x
      do
        if [[ "$proto" == tcp && "$state" == ESTABLISHED && "$remote" =~ .*:3434$ ]]
        then
          printf "%s/%s %d\n" "$local" "$remote" "$recvq"
        fi
      done < "$1"
    }
    
    # First measure
    
    declare -A first
    while read socket recvq
    do
      first[$socket]=$recvq
    done < <(recvq netstat1.txt)
    
    # Wait
    
    sleep 10
    
    # Second measure
    
    declare -A second
    while read socket recvq
    do
      second[$socket]=$recvq
    done < <(recvq netstat2.txt)
    
    # Compare measures
    
    for socket in "${!first[@]}"
    do
      if [[ "${first[$socket]}" == "${second[$socket]}" ]]
      then
        printf "match for %s: %d\n" "$socket" "${first[$socket]}"
      fi
    done
    
        2
  •  0
  •   Bogdan Stoica    5 年前

    我终于明白了。也许它可以像@ceving所建议的那样,很好地处理关联数组,并提供了一个答案,但它并没有像预期的那样工作。

    不过,我不会把自己的答案标为正确答案。我刚把它贴出来,以防有人觉得有用。

    #/bin/bash
    
    n1="$(cat netstat1.txt | awk '{split($5,a,":"); print a[1]"="$2}')"
    
    sleep 5
    
    n2="$(cat netstat2.txt | awk '{split($5,a,":"); print a[1]"="$2}')"
    
    # check
    for i in $n1; do
        ip1=`echo $i | awk '{split($i,a,"="); print a[1]}'`
        val1=`echo $i | awk '{split($i,a,"="); print a[2]}'`
        #echo $ip1 $val1
    
        for j in $n2; do
    
            ip2=`echo $j | awk '{split($j,a,"="); print a[1]}'`
            val2=`echo $j | awk '{split($j,a,"="); print a[2]}'`
            #echo $ip2 $val2
    
            if [ $ip1 == $ip2 ]; then
                if [ $val1 == $val2 ]; then
                    echo "values: $val1 vs $val2 equal for remote ip: $ip1 => NOK! Do whatever!"
                else
                    echo "values: $val1 vs $val2 dfferent for remote ip: $ip1 => OK"
                fi
            fi
        done
    done
    
    推荐文章