bug-bash
[Top][All Lists]
Advanced

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

Re: Please advise on programming tactics/strategy


From: cga2000
Subject: Re: Please advise on programming tactics/strategy
Date: Tue, 18 Dec 2007 23:09:54 -0500
User-agent: Mutt/1.5.13 (2006-08-11)

On Tue, Dec 18, 2007 at 09:57:44PM EST, Matthew Woehlke wrote:
> cga2000 wrote:
> >I was wondering if there is any way I can convince netstat to return
> >its output to bash variables for processing.
> >
> >Pretty simple logic:
> >
> >Do forever:
> >
> >  Call netstat to obtain RX & TX byte counts Print delta {current ..
> >  minus previous .. byte counts} Save current byte counts Wait for a
> >  second or so ..
> >
> >I initially thought I could just pipe the "netstat -in" command to
> >the invocation of a bash function.
> >
> >The function would have taken care of the gory details of parsing &
> >formatting the output of the netstat command and would then have
> >stored the current byte counts where they would be available for the
> >next time the function is invoked.
> >
> >The trouble is that I haven't been able to find anything like a
> >"static" local variable that is not reinitialized every time the
> >function is invoked.
> 
> Pipes run as seperate processes, e.g. in 'somecommand | function',
> 'function' is run as a subshell, so anything done in 'function' does
> not propagate up to the parent. 

Never does.  That's why I was looking for a way to do it via global
variables, static local variables, or .. more natural where I'm
concerned, a pointer.

> You might want to look at bash's command redirection instead.

?

> Alternatively, something like 'foo=$(netstat | extract)' where
> 'extract' filters the netstat output and condenses it down to
> something more easily parsed in the parent, e.g. 'TX:RX'. Then you can
> do something like 'tx=${foo%:*}; rx=${foo#*:}'.

Pretty much what I found.

Here's what I eventually came up with:

#!/bin/bash
interface=eth0
get_data()
{
  netstat -ni | awk '/^'"$interface"'/{print$4,$8}'                   
}
read rxp txp <<< $(get_data)                                          
while sleep 1; do                                                     
  read rx tx <<< $(get_data)                                          
  echo $((rx - rxp)) $((tx - txp)) |                                  
  awk '{printf "%4.1f k/s %4.1f k/s\n",$1*576/1024,$2*567/1024}'      
  rxp=$rx txp=$tx                                                     
done
exit 0

Someone on another mailing list showed me how to use the "<<<" Here
String technique to split the output of function "get_data" into two
variables. Kinda like it better than the classic shell foo%:* etc.
Mainly because the syntax is a lot easier to remember, I guess.. the
downside is that <<< appears to be a bash-only extension and not
portable to regular Bourne sh.  Not that this matters much in this
particular case.

All in all, I'm fairly happy with this current version .. Fairly compact
and yet quite readable. 

I'm no sure about the logic of it ..  how accurate its results are.

Also, I'm definitely not too happy about the overhead .. there are idle
times on my system when this short script seems to eat up more cpu
cycles than everything else .. :-)

Maybe the next step would be to rewrite it in C.

Thanks much for your comments.





reply via email to

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