my lame attempt at a shell script...

Timothy Luoma lists at tntluoma.com
Mon Jan 3 22:52:34 PST 2005


On Jan 3, 2005, at 11:22 PM, Eric F Crist wrote:

>
> On Jan 3, 2005, at 8:21 PM, Timothy Luoma wrote:
>
>> On Jan 3, 2005, at 6:28 PM, Eric F Crist wrote:
>>
>>> A couple more questions, then I'm done. Promise.
>>>
>>> I need to verify whether or not there is an entry for 
>>> grog_firewall_oif and grog_firewall_iif in /etc/rc.conf.  If not, I 
>>> want to exit with an error.
>>
>> You want to check for either "grog_firewall_oif" or
>> "grog_firewall_iif" in /etc/rc.conf
>>
>> egrep -v "^#" /etc/rc.conf |\
>> egrep -q "grog_firewall_oif | grog_firewall_iif" || (echo "$0" ; exit
>> 1)
>>
>> The first line says "skips the comment lines" (the ones that begin
>> with #)
>>
>
> What does the second line do?  I tried, apparently, to accomplish the
> same thing with some different syntax, yet unsuccessfully.

OOps, sorry.  The 2nd line was the more important.  I must have gotten 
distracted while writing the explanation.

egrep -q says "run egrep, but don't tell me anything except an exit 
code"

egrep is 'extended grep' which can match patterns.  See 'man grep' for 
the difference between grep, egrep, and fgrep, all of which have 
specific uses.  egrep "a|b" means "look for either 'a' or 'b'

egrep -q "grog_firewall_oif | grog_firewall_iif" means "look for either 
of those grog_firewall_oif or grog_firewall_iif

NOTE: I made a mistake in that there should be NO WHITESPACE around the 
"|" when doing that match. The corrected version would be

egrep -v "^#" /etc/rc.conf |\
egrep -q "grog_firewall_oif|grog_firewall_iif" || (echo "$0" ; exit 1)

the "||" means "If what happened on the left hand side didn't exit = 0, 
then do the stuff on the right hand side

ARGH.  Another mistake, but at least a minor one.  No error message 
given there.  It should look more like:

(echo "$0 did not find grog_firewall settings"; exit 1)

> I can assume everything, since grog_firewall_oif *should* be a value
> such as above.  On my system, grog_firewall_oif will be ath0.  This
> isn't assumed, but rather defined for me.  I would write the above line
> as follows (please verify syntax):
>
> ifconfig $grog_firewall_oif |\
> 	tr '\012' ' ' |\
> 	sed 's#.*inet ##; s# netmask.*##'
>
> oif_ip=`ifconfig $grog_firewall_oif |\
> 	tr '\012' ' ' |\
> 	sed 's#.*inet ##; s# netmask.*##'`
>

yes, that looks good.  Do verify that you get the results you expect 
when you run the commands at the commandline before putting them in a 
script.

> This is a lot of help, however, if you read:
>
>>> I don't actually need my own address, I need to be able to figure out
>>> that the system, based on the above output, is on the 192.168.1.0/24
>>> network.
>
> I need my NETWORK address, in this case 192.168.1.0 (with netmask),
> which would be 192.168.1.0/24

Ah, ok, so you need the 192.168.1. part and the netmask.

Ok, here's where someone who is better at pattern matching could come 
up with something elegant, where I end up getting really hacky

(NOTE: i'm using 'en1' here because that's what it is on my system 
here, adjust for your own setting)

IFCONFIG=`ifconfig en1|tr '\012' ' ' |sed 's#.*inet ##; s#broadcast 
.*##; s# netmask # #' |tr '.' ' '`

which says, get all the ifconfig information, and trim it down to just 
the IP and the netmask.  Oh, and change any periods for spaces (the 
reason why will become evident in a moment).  At this point, $IFCONFIG 
on my system would look like this:

192 168 2 102 0xffffff00

then I'd put the netmask in its own variable like this

NETMASK=`echo $IPCONFIG | awk '{print $NF}'`

which says "take the $IPCONFIG information and give me the last field.  
Since we know there will be 5 fields, we could also use this:

NETMASK=`echo $IPCONFIG | awk '{print $5}'`

SUBNET=`echo $IPCONFIG | awk '{print $1"."$2"."$3}'`

that will make $SUBNET = 192.168.2

(the awk statement says "take the $IPCONFIG information and give me the 
1st, 2nd, and 3rd fields and put periods in between them when you print 
them)

ASIDE: It would be easy to get several different levels of specificity 
here (i.e. do you want 192.168.2 or just 192.168 or just 192)

Then I would make use of a case statement like this:

case $SUBNET in

		192.168.2)
					echo "I'm on the office network"
		;;

		10.0.1)
					echo "I'm on my home network"
		;;
esac

The same would be true for whatever you want to do with $NETMASK

Does that get at it?

TjL



More information about the freebsd-questions mailing list