bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Please advise on bash programming tactics/strategy


From: Mike Stroyan
Subject: Re: Please advise on bash programming tactics/strategy
Date: Thu, 13 Dec 2007 10:38:06 -0700
User-agent: Mutt/1.5.15+20070412 (2007-04-11)

On Wed, Dec 12, 2007 at 06:49:25PM -0500, cga2000 wrote:
> On Wed, Dec 12, 2007 at 12:31:47AM EST, Bob Proulx wrote:
> > cga2000 wrote:
> > > I was wondering if there is any way I can convince netstat to return
> > > its output to bash variables for additional processing.
> > 
> > Do you mean like this?
> > 
> >     rxcnt=$(netstat -ni | awk '/^eth0/{print$4}')
> 
>   #!/bin/sh
> 
>   interface=eth0
> 
>   get_data()
>   {
>     netstat -ni | awk '/^'"$interface"'/{print$4,$8}'
>   }
> 
>   init_data()
>   {
>     netdata=$(get_data)
>     prevrxcnt=$(echo $netdata | awk '{print$1}')
>     prevtxcnt=$(echo $netdata | awk '{print$2}')
>   }
> 
>   save_data()
>   {
>     netdata=$(get_data)
>     rxcnt=$(echo $netdata | awk '{print$1}')
>     txcnt=$(echo $netdata | awk '{print$2}')
>     diffrxcnt=$(($rxcnt - $prevrxcnt))
>     difftxcnt=$(($txcnt - $prevtxcnt))
>     prevrxcnt=$rxcnt
>     prevtxcnt=$txcnt
>   }
> 
>   init_data
>   while sleep 1; 
>   do
>     save_data
>     echo $diffrxcnt $difftxcnt | 
>     awk '{printf "%4.1f k/s %4.1f k/s\n",$1*576/1024,$2*567/1024}'
>   done
> 
>   exit 0
> 
> I provides exactly the output I need .. although bash must provide a 
> more elegant (and less expensive) way to split a variable that contains
> two fields separated by a space than invoking awk.

  You can use
     read rxcnt txcnt <<< $netdata
to split out the two values.

  You don't need awk for the splitting of netstat output into words.
The bash read command can do that.
This will split the lines into array a and examine each line.

get_data()
{
    local a
    netstat -ni |
        while read -a a
        do
            if [[ ${a[0]} == $interface ]] 
            then
                echo ${a[3]} ${a[4]}
            fi
        done
}

Or this next version will split the lines into variables and examine them
for matches.  The "d" variable is a dummy placeholder for unused fields.
The last use of "d" variable gets the entire remainder of each line.

get_data()
{
    local int d rxcnt txcnt
    netstat -ni |
        while read int d d rxcnt txcnt d
        do
            if [[ $int == $interface ]] 
            then
                echo $rxcnt $txcnt
            fi
        done
}

  It would be more modular to use an argument to get_data to pass
the interface instead of using the $interface global variable.

get_data()
{
    local int d rxcnt txcnt target
    target=$1
    netstat -ni |
        while read int d d rxcnt txcnt d
        do
            if [[ $int == $target ]] 
            then
                echo $rxcnt $txcnt
            fi
        done
}

Then you would invoke it as netdata=$(get_data $interface)

-- 
Mike Stroyan <mike@stroyan.net>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]