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