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: cga2000
Subject: Re: Please advise on bash programming tactics/strategy
Date: Thu, 13 Dec 2007 22:15:42 -0500
User-agent: Mutt/1.5.13 (2006-08-11)

On Thu, Dec 13, 2007 at 12:38:06PM EST, Mike Stroyan wrote:
> On Wed, Dec 12, 2007 at 06:49:25PM -0500, cga2000 wrote:
[..]
> > 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.

Very elegant indeed.

And I would never have figured it out from the man page, which states:

"Here Strings

    A variant of here documents, the format is:

          <<<word

    The word is expanded and supplied to the command on its standard input."

Thank you very much for introducing me to this remarkable feature!

>   You don't need awk for the splitting of netstat output into words.

:-)

Just kidding ..

.. and sincerely hoping someone knowledgeable would show me the right
way to do this.

Needless to say, the solution provided goes way beyond what I hoped.

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

This is very nice!

So I could write in "main" ..

read netdata[0] netdata[1] <<< $(get_data) 

and retrieve my RX/TX packet counts in the netdata array for further
processing!

... not that I need an array in this particular case .. plain
one-dimensional variables would do just as well.

read rxcnt txcnt <<< $(get_data)

> 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.

nice ..

> The last use of "d" variable gets the entire remainder of each line.

That I figured, when, while testing, I noticed that my last variable was
polluted by all the orphans/leftovers ..

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

... bash feels like such a "jungle" with its countless features (as
compared with C, which has so few it only takes a couple of days to
learn them all..) it's so difficult to figure out a decent way to do
stuff .. 

... or in other words for a beginner like myself, jumping from pseudo
code to actual scripts feels like another quantum leap.

>   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)

Thank you very much for this mini-tutorial.






reply via email to

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