code snippet
#!/usr/local/bin/bash
IPADDR=192.168.10.1
echo "IP address variable is: $IPADDR"
#
awk '{ ip=$IPADDR; split (ip,quad,".");
for (i=1;i<5;i++)
if (quad[i] !~ /[0-9]*/)
printf "wrong ip address\n"
else
printf "correct ip address"}'
or is this a better approach?
IPADDR=192.168.10.1
echo "IP address variable is: $IPADDR"
#
if [ awk '{/^([0-9]\.[0-9]\.[0-9]\.[0-9]/}' "${NEW_IPADDR}" ]; then
#hopefully this evaluates to true
printf "correct ip address"
else
printf "wrong ip address\n"
fi
Thanks for any help w/ this, Tom
>I'm not worried about IP addresses in the form: 127.0
>I can't figure out two things: 1. How to get the variable into the awk
>split command; & 2. what the correct awk (I don't have gawk) regex is
>
There are 2 wayz to get the variable into the 'awk' script,
one is to interpolate it directly by dropping out of single
quotes, going in to double ones (just to be on the safe side,
leaving IPADDR unquoted in this case should also work thou`)
putting your variable there (so the shell replaces that part)
and then going back,eg;
echo "IP address variable is: $IPADDR"
#
# the shell will interpolate the variable value of IPADDR
# here since it's only in double quotes
# vvvvvvvvv
awk '{ ip='"$IPADDR"'; split (ip,quad,".");
for (i=1;i<5;i++)
if (quad[i] !~ /[0-9]*/)
The other way is to use the '-v' option of 'awk' to set the variable;
awk -v ip="$IPADDR" '{ split (ip,quad,".");
for (i=1;i<5;i++)
if (quad[i] !~ /[0-9]*/)
For your regular expression formulation it's a good idea to
read the relevant man page, 'awk' uses extended regular expressions
which are the same like 'egrep' uses. The 'awk' man page will
give you a pointer to where that documentation is if it isnot
on the 'awk' man page, it's probably on the 'egrep' man page.
Some systems might have a regular expression syntax man page,
for example 'regex' with complete documentation on both
basic and extended RE's.
In any case you'll want to match the entire string so anchor
the expression to the start of the line with ^ and the end
of the line with '$'. [0-9]* matches 0 or more digits and
you want to match 1 or more (otherwise you'll match a null
string as well) digits. So you might end up with something
like this;
if (quad[i] !~ /^[0-9][0-9]*$/)
Also, since the decimal values should be between 0 and 255
you might add an additional check for that;
if (quad[i] !~ /^[0-9][0-9]*$/ || quad[i]<0 || quad[i]>255)
Another VERY important thing isto check the number of fields that
split() gives you is exactly 4, otherwise you could be
checking any old data (in the fields outside those returned).
So, adding in that you might get something like the following
(untested) ;
echo "IP address variable is: $IPADDR"
#
awk -v ip="$IPADDR" '{
#
# verify that 'ip' is a valid ip address
#
valid=1
if(split (ip,quad,".") != 4) valid=0
for (i=1;valid==1 && i<5;i++)
if(quad[i] !~ /^[0-9][0-9]*$/ || quad[i]<0 || quad[i]>255)
valid=0
#
#
if(!valid)
printf "wrong ip address\n"
else
printf "correct ip address"
}'
>code snippet
>#!/usr/local/bin/bash
>
>IPADDR=192.168.10.1
>echo "IP address variable is: $IPADDR"
>#
>awk '{ ip=$IPADDR; split (ip,quad,".");
> for (i=1;i<5;i++)
> if (quad[i] !~ /[0-9]*/)
> printf "wrong ip address\n"
> else
> printf "correct ip address"}'
>
>or is this a better approach?
>
>IPADDR=192.168.10.1
>echo "IP address variable is: $IPADDR"
>#
>if [ awk '{/^([0-9]\.[0-9]\.[0-9]\.[0-9]/}' "${NEW_IPADDR}" ]; then
>#hopefully this evaluates to true
> printf "correct ip address"
> else
> printf "wrong ip address\n"
> fi
It would be pretty difficult to form only 1 regular expression
to completely validate an IP address (although maybe a fun exercise)
so I think your other approach is better.
>
>Thanks for any help w/ this, Tom
wishes
--
laura fairhead # la...@madonnaweb.com http://lf.8k.com
# if you are bored crack my sig.
1F8B0808CABB793C0000666667002D8E410E83300C04EF91F2877D00CA138A7A
EAA98F30C494480157B623C4EF1B508FDED1CEFA9152A23DE35D661593C5318E
630C313CD701BE92E390563326EE17A3CA818F5266E4C2461547F1F5267659CA
8EE2092F76C329ED02CA430C5373CC62FF94BAC6210B36D9F9BC4AB53378D978
80F2978A1A6E5D6F5133B67B6113178DC1059526698AFE5C17A5187E7D930492
>On Tue, 09 Apr 2002 14:46:28 GMT, Tom Porter <spammers...@krumpli.com> wrote:
>
>>I'm not worried about IP addresses in the form: 127.0
>>I can't figure out two things: 1. How to get the variable into the awk
>>split command; & 2. what the correct awk (I don't have gawk) regex is
>>
[]
>
>awk -v ip="$IPADDR" '{ split (ip,quad,".");
> for (i=1;i<5;i++)
> if (quad[i] !~ /[0-9]*/)
>
>For your regular expression formulation it's a good idea to
>read the relevant man page, 'awk' uses extended regular expressions
>which are the same like 'egrep' uses. The 'awk' man page will
>give you a pointer to where that documentation is if it isnot
>on the 'awk' man page, it's probably on the 'egrep' man page.
>Some systems might have a regular expression syntax man page,
>for example 'regex' with complete documentation on both
>basic and extended RE's.
>
Another source of documentation on regular expressions;
http://www.opengroup.org/onlinepubs/7908799/xbd/re.html
This is a formal standards document so it's extremely
detailed, however maybe you find it useful.
regardsfrom
> I'm not worried about IP addresses in the form: 127.0
> I can't figure out two things: 1. How to get the variable into the awk
> split command; & 2. what the correct awk (I don't have gawk) regex is
What are you trying to validate, just that the input is a potentially
valid IP address? Are you attached to awk, or will perl do?
if perl -MSocket -e '$addr=unpack("B*",inet_aton(shift));
exit 1 unless ($addr =~ /1/)' $IPADDR; then
echo good address
else
echo bad address
fi
This has the advantage that things like 192.168.10.400 will fail.
--
Jeremy | jer...@exit109.com
So does this shell function, without using any external command:
is_ip() {
case "$*" in
""|*[!0-9.]*) return 1 ;;
esac
oldIFS=$IFS
IFS='.'
set -- $*
IFS=$oldIFS
[ $# -eq 4 ] || return 1
for ipseg in $1 $2 $3 $4
do
case $ipseg in
*[!0-9]*) return 1 ;;
esac
[ $ipseg -le 255 ] || return 1
done
}
if is_ip $addr
then
echo "OK"
else
echo "BAD"
fi
--
Chris F.A. Johnson bq...@torfree.net
=================================================================
c.f.a....@rogers.com http://cfaj.freeshell.org
cf...@freeshell.org http://members.rogers.com/c.f.a.johnson
That is some butifull code. Do you know of any documenation that
focuses explisitly on programing with only builtins?
--
+-(faux@fugozi)-(0.08|0.26|0.37)-(00:47|Wed Apr 10)-+ cat ~/.{sig,uin}
It's a damn poor mind that can only think of one way to spell a word.
- Andrew Jackson
UIN=66618055
This case catches invalid characters, something like
an IP of "1a.12.13.14" or "xxx" is caught here.
> oldIFS=$IFS
> IFS='.'
> set -- $*
> IFS=$oldIFS
> [ $# -eq 4 ] || return 1
> for ipseg in $1 $2 $3 $4
> do
> case $ipseg in
> *[!0-9]*) return 1 ;;
> esac
So, isn't this 2nd case above redundant?
> [ $ipseg -le 255 ] || return 1
> done
> }
>
> if is_ip $addr
> then
> echo "OK"
> else
> echo "BAD"
> fi
Very nice!
--
David Thompson
dat...@yahoo.com
>Do you know of any documenation that
>focuses explisitly on programing with only builtins?
``man ${shell_of_interest}'' seriously. if you don't use anything other
than what is documented therein you will have pure shell code. the main
effort with shell code programming is, as with all other programming,
defining the problem well and good familiarity with the language. a
typical way to increase the later is through repetition -- do this: try to
solve every request you see here without using external commands.
several shells come with example programs, which are typically fairly pure,
e.g., <http://kornshell.com/examples>, and the examples often contained in
the man page are likewise typically pure.
there are also fine examples elsewhere, e.g., <http://www.shelldorado.com>
or books like `learning the korn shell' (which contains a ksh script
debugger, which contains only two external commands (cat and rm, one
instance of each) one of which (cat) could be eliminated with ease).
--
bringing you boring signatures for 17 years
Quite right.
For use in bash, I can boil it down to:
is_ip() {
case "$*" in
""|*[!0-9.]*|*[!0-9]) return 1 ;;
esac
local IFS=.
set -- $*
[ $# -eq 4 ] &&
[ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
[ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
}
>> [ $ipseg -le 255 ] || return 1
>> done
>> }
>>
>> if is_ip $addr
>> then
>> echo "OK"
>> else
>> echo "BAD"
>> fi
>
> Very nice!
Thank you.
> The other way is to use the '-v' option of 'awk' to set the variable;
>
> awk -v ip="$IPADDR" '{ split (ip,quad,".");
> for (i=1;i<5;i++)
> if (quad[i] !~ /[0-9]*/)
>
There is a third way, that has always been in awk, but not always well
documented: There was an awk supplement that covered this.
awk '{script}' var1=3 var2=5 ......
Example:
% echo a | awk '{print v}' v=3
3
%
--
Sending unsolicited commercial e-mail to this account incurs a fee of
$500 per message, and acknowledges the legality of this contract.
Just remember that variables passed this way are not available until
awk starts reading lines:
$ echo a | awk -v q=666 '
BEGIN {print "q = " q ", v = " v}
{print "q = " q ", v = " v}' v=3
q = 666, v =
q = 666, v = 3
$
I will look a little more carefully
latter. I know that the man page is the best place for the nitty
gritties I was just looking for something that maybe got more into
examples of how to pull it off in the phylosophy or had more
examples. Thanks for the shelldorado link. Hopefully it will have
some examples I can use.
If not it looks like I am going to have to boot to the windows
install i have never used, install the printer that hasn't been
touched in 2 years and hope that the ink still works and then print
out the man page and sleep with it under my pellow.
Whatever it takes to get the job done.
--
+-(faux@fugozi)-(0.21|0.29|0.83)-(21:08|Wed Apr 10)-+ cat ~/.{sig,uin}
An absolute perfect example of using bash's "local"
builtin command! Use of "local" allows a solution
more elegant than would be otherwise possible.
> set -- $*
> [ $# -eq 4 ] &&
> [ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
> [ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
> }
Sweet! I love it, stand by as I cut & paste this one
into my personal bag o' tricks ... very nice ...
Some teacher/professer somewhere could have a field day
explaining all the concepts/advantages at play in this
shell function!
Thanks!
--
David Thompson
dat...@yahoo.com
is 666 a random number greater than 254 (to make the condition
fail)? or, am i missing a deeper meaning there?
> Just remember that variables passed this way are not available until
> awk starts reading lines:
Cool. Didn't know that. Thanks!
Thanks very much to Laura & Chris for their help. Would someone mind
briefly commenting Chris's solution? Thanks...
Tom
The last -le should have been 255 along with the rest. (Unless the
maximum IS 254; I think I copied the numbers from someone else's
script, so they might have been right. Does any one know?)
> is 666 a random number greater than 254 (to make the condition
> fail)? or, am i missing a deeper meaning there?
The devil made me do it!
case "$*" in
"" | -- If there is no argument, or
*[!0-9.]* | -- the argument contains any character other
-- than a digit or a period, or
*[!0-9] -- the argument does not end with a digit
) return 1 ;; -- then it is not a valid IP address; FAIL
esac
local IFS=. -- set the field separator to a period,
-- but only in this function [in ksh use typeset]
set -- $* -- convert the argument to positional parameters
-- split at the periods
-- in the following block, if any condition fails, the
-- remainder of the tests are not made, and the function
-- returns with the result of the last command (FAIL); if
-- all the conditions are met, the function succeeds.
[ $# -eq 4 ] && -- check that there are four segments
-- each segment must be from 0 to 255 (they cannot be negative,
-- as we eliminated any minus signs in the case statement)
-- each segment
[ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
[ ${3:-666} -le 255 ] && [ ${4:-666} -le 255 ]
As usual, there are other ways this can be done.
An obvious improvement is to remove the need for the ${1:-666} etc..
And while we're at it, we can remove the assignment to IFS.
[Note: this is specific to bash2 and ksh93 (and maybe zsh?)]
is_ip() {
## reject if argument:
## contains any character other than digits or period
## begins with a period
## ends with a period
## contains 2 (or more) adjacent periods
case "$*" in
*[!0-9.]*|\
.*|\
*.|\
*..* ) return 1 ;;
esac
## convert periods to spaces and set as positional parameters
set -- ${*//./ }
## check that there are four segments
[ $# -eq 4 ] &&
## check that each segment is no greater than 255
[ $1 -le 255 ] && [ $2 -le 255 ] &&
[ $3 -le 255 ] && [ $4 -le 255 ]
How about a lot of comments? ;)
Here's a listing with line numbers,
1 is_ip() {
2 case "$*" in
3 ""|*[!0-9.]*|*[!0-9]) return 1 ;;
4 esac
5 local IFS=.
6 set -- $*
7 [ $# -eq 4 ] &&
8 [ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
9 [ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
10 }
I will try to provide my $.02 explanation.
These 3 lines below are doing validation by matching illegal
characters,
2 case "$*" in
3 ""|*[!0-9.]*|*[!0-9]) return 1 ;;
4 esac
The "$*" means all arguments to the function, and the DQ
form "$*" expands to a single string "$1c$2c$3c..." where
c is the first character of the IFS global variable, which
is a space.
The pattern match in line 3 uses pipe bar | to separate 3
patterns, (shell patterns only, no regular expressions),
which are,
"" match empty string
*[!0-9.]* match any character not in range 0-9 or a .
Note how this 2nd pattern has * on both sides; it's trying
to match a single (unwanted) character anywhere in the string.
*[!0-9] match any character not in range 0-9
This 3rd pattern is probably not necessary; it's trying to match
an (unwanted) numeric character at the end of the string only.
But the 2nd pattern matches (most) of that except for when . is
the last character, which is matched by this 3rd pattern. The
reason this 3rd pattern is not necessary is because lines 7-8
would catch the same error as caught by this 3rd pattern.
The return 1 is the return code of the function; which is interpreted
by callers the same as exit status of commands: 0 for success and
non-zero for failure.
The next line,
5 local IFS=.
is a bit of magic, mostly designed to alleviate extra lines. In
bash, variables local to the function may be declared with the
local builtin command. Note how the old value of IFS is not
saved, ie, using local means that this classic technique below
is not needed,
OLDIFS="$IFS"
IFS=.
... do something here ...
IFS="$OLDIFS"
because bash will use the local version of IFS inside the
function. After the function returns, the global IFS variable
is again in scope. The original value of global IFS is not
changed. Sweet.
The reason for line 5 above is because of set in line 6,
6 set -- $*
Realize that -- is actually the - flag to set. Observe,
set -f
^
The second letter f is the option name
set --
^
The second letter - is the option name
If no arguments follow the - flag to set then the positional
parameters are unset. But we want to set the positional
parameters, and split them at the same time. IFS specifies
how to split, the set -- does the splitting.
Specifically, line 6 will reset the positional parameters
to the components of an IP address. Ie, we want,
set -- "10.20.30.40"
to reset the positional parameters to this,
$1 = "10"
$2 = "20"
$3 = "30"
$4 = "40"
So, the IFS variable (Input Field Separator) specifies the
characters that are used when "word splitting" is performed;
and the 'set --' does word splitting on its arguments and
assigns the results to the positional parameters.
So, at the start of line 7, we have the positional parameters
set to the different components of an IP address. $# is reset
too, it contains the number of parameters, so that these lines
of code,
7 [ $# -eq 4 ] &&
8 [ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
9 [ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
perform final validation on each component.
Line 7 validates that we have 4 components in the IP address.
Line 8 and 9 validate each of the 4 components as integers
less than or equal to 255 (or 254 in case of $4). The -lt
implies an integer comparison.
To make sure that these lines (because arguments on either
side of -lt cannot be empty) don't fail, ${1:-666} et al is
used to force a known value which produces a desired comparison.
The form ${1:-666} provides a default value for $1 if $1 is
empty. Ie, just in case $1 is empty, ${1:-666} resolves to
non-empty string "666" instead.
However, this nicety is (probably) not necessary, because
the test at line 7 already validates that we have 4 non-empty
positional parameters, so this alternative should work,
8 [ $1 -le 255 ] && [ $2 -le 255 ] &&
9 [ $3 -le 255 ] && [ $4 -le 254 ]
But a better choice might be to use [[ ]] form,
8 [[ $1 -le 255 ]] && [[ $2 -le 255 ]] &&
9 [[ $3 -le 255 ]] && [[ $4 -le 254 ]]
Because [[ ]] has advantage over [ ] by allowing parameters to
be empty. Ie, when using [ ] form, empty args around -lt cause
syntax errors, but using [[ ]] prevents that.
Finally, the result of a function (if not explicitly specified via
a call to return) is the status of the last command executed. The
return code of this function depends upon this feature. Neat.
Very well written and elegant example of shell programming.
I can't believe I typed all this! :)
--
David Thompson
dat...@yahoo.com
>la...@madonnaweb.com (laura fairhead) writes:
>
>> The other way is to use the '-v' option of 'awk' to set the variable;
>>
>> awk -v ip="$IPADDR" '{ split (ip,quad,".");
>> for (i=1;i<5;i++)
>> if (quad[i] !~ /[0-9]*/)
>>
>
>There is a third way, that has always been in awk, but not always well
>documented: There was an awk supplement that covered this.
>
>awk '{script}' var1=3 var2=5 ......
>
>Example:
>
>% echo a | awk '{print v}' v=3
>3
>%
>
Great :) I vaguely remember this one from somewhere but I got so used to
either using '-v' or interpolating the variable into the program.
I've just done some research and found out that '-v' is not actually
present in either old awk (1978 version which I think's the default
on SunOS), OR new awk (1989 ?). However both versions and everything
else including POSIX1003.2 support this form of assignement, so it
lookz good, I'm going to use this always now when I can instead of -v :-)
Also there's a subtle pitfall that could happen if the first filename
argument contains an equals sign, so if the filename was selected
by user data that could be a security risk if you weren't careful...
>
>--
>Sending unsolicited commercial e-mail to this account incurs a fee of
>$500 per message, and acknowledges the legality of this contract.
byefrom
>>> [ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
>>> [ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
>>> }
>
> The last -le should have been 255 along with the rest. (Unless the
> maximum IS 254; I think I copied the numbers from someone else's
> script, so they might have been right. Does any one know?)
A last octet of 255 would be a broadcast address on a /24 subnet, and
thus is valid.
The problem with this solution is that it will reject perfectly valid
IP addresses. It is based upon the assuption that an IP address is
"a sequence of four numbers less than 256, separated by dots", which
of course is not the case.
It will reject 127.1, which is perfectly valid, as is 216.239.10085 (try
it), and 3639551845 for that matter.
--
Jeremy | jer...@exit109.com
Shush! That's a secret! Even though the perl solution from a
previous poster is better (because, yeah, it checks for this),
this thread is trying to train the next generation of gurus
about, er, shell programming.
;)
--
David Thompson
dat...@yahoo.com
So (I think I have the numbers right):
is_ip() {
case "$*" in
*[!0-9.]*|\
.*|\
*.|\
*..* ) return 1 ;;
esac
set -- ${*//./ } ## bash2, ksh93
case $# in
4) [ $1 -le 255 ] && [ $2 -le 255 ] &&
[ $3 -le 255 ] && [ $4 -le 255 ]
;;
3) [ $1 -le 255 ] && [ $2 -le 255 ] &&
[ $3 -le 65535 ] ;;
2) [ $1 -le 255 ] && [ $2 -le 16777215 ] ;;
1) [ $1 -le 4294967295 ] ;;
*) return 1 ;;
esac
Geez, and I really proofed this puppy, too. Oh well ...
--
David Thompson
dat...@yahoo.com
Why don't you want -ge there?
> for ipseg in $1 $2 $3 $4
> do
> case $ipseg in
> *[!0-9]*) return 1 ;;
> esac
> [ $ipseg -le 255 ] || return 1
> done
> }
>
> if is_ip $addr
> then
> echo "OK"
> else
> echo "BAD"
> fi
--
-eben eQbW...@gTaYtUeI.nOePt home.tampabay.rr.com/hactar
He who will not reason is a bigot; he who cannot is a fool;
and he who dares not is a slave. -Sir William Drummond
Never mind, I see; "||", not "&&".
I wrote it for ksh, but in such a way that it should work with
bash too, at least without major changes. I haven't tested it
with bash though.
------------------------------------------------------------------------
#!/bin/ksh
#
# NAME
#
# ipv4norm - syntax check and normalize an IPv4 address
#
# SYNOPSIS
#
# ipv4norm IPV4ADDR [IPV4ADDR ...]
#
# DESCRIPTION
#
# `ipv4norm' syntax checks and normalizes an IPv4 address, and prints the
# result on standard output. Here, normalize means that the address is
# converted to the form `d.d.d.d' where each integer `d' is between 0 and
# 255, inclusive.
#
# If an IP address is invalid, a message is written on standard error. If
# more than one IP address is given, the original IP address is written at
# the beginning of each output line.
#
# EXAMPLES
#
# % ipv4norm 3231385208
# 192.155.6.120
#
# % ipv4norm 192.10159736 192.155.1656 192.155.6.120
# 192.10159736: 192.155.6.120
# 192.155.1656: 192.155.6.120
# 192.155.6.120: 192.155.6.120
#
# ENVIRONMENT VARIABLES
#
# No environment variables are used.
#
# EXIT STATUS
#
# The following exit values are returned:
#
# 0 All IP addresses are valid.
#
# >0 At least one IP address is invalid.
nargs=$# # number of input arguments
nerrs=0 # accumulated number of errors
if (( nargs < 1 )); then
echo "$0: missing argument" 1>&2
fi
ipv4norm () {
IP_ADDR="$1"
case "$IP_ADDR" in
*[!0-9.]* | *.*.*.*. | .*.*.*.* | *.*.*.*.* )
if (( nargs > 1 )); then
echo "$IP_ADDR: \c" 1>&2
fi
echo "Not a valid IPv4 address." 1>&2
nerrs=$(( nerrs + 1 ))
;;
*.*.*.*) # "192.155.6.120"
OLDIFS="$IFS"
IFS="."
set -- $IP_ADDR
n1=$1 # (1st)
n2=$2 # (2nd)
n3=$3 # (3rd)
n4=$4 # (4th)
IFS="$OLDIFS"
;;
*.*.*) # "192.155.1656"
OLDIFS="$IFS"
IFS="."
set -- $IP_ADDR
n1=$1 # (1st)
n2=$2 # (2nd)
n4=$3 # = 1656
n3=$(( n4 / 256 )) # = 6 (3rd)
n4=$(( n4 - 256 * n3 )) # = 120 (4th)
IFS="$OLDIFS"
;;
*.*) # "192.10159736"
OLDIFS="$IFS"
IFS="."
set -- $IP_ADDR
n1=$1 # (1st)
n4=$2 # = 10159736
n2=$(( n4 / 65536 )) # = 155 (2nd)
n4=$(( n4 - 65536 * n2 )) # = 1656
n3=$(( n4 / 256 )) # = 6 (3rd)
n4=$(( n4 - 256 * n3 )) # = 120 (4th)
IFS="$OLDIFS"
;;
*) # "3231385208"
OLDIFS="$IFS"
IFS="."
set -- $IP_ADDR
n4=$1 # = 10159736
n1=$(( n4 / 16777216 )) # = 192 (1st)
n4=$(( n4 - 16777216 * n1 )) # = 10159736
n2=$(( n4 / 65536 )) # = 155 (2nd)
n4=$(( n4 - 65536 * n2 )) # = 1656
n3=$(( n4 / 256 )) # = 6 (3rd)
n4=$(( n4 - 256 * n3 )) # = 120 (4th)
IFS="$OLDIFS"
;;
esac
if (( n1 <= 255 && n2 <= 255 && n3 <= 255 && n4 <= 255 )); then
if (( nargs > 1 )); then
echo "$IP_ADDR: \c"
fi
echo "$n1.$n2.$n3.$n4"
else
if (( nargs > 1 )); then
echo "$IP_ADDR: \c" 1>&2
fi
echo "Not a valid IPv4 address." 1>&2
fi
}
for IP_ADDR in $@; do
ipv4norm $IP_ADDR
done
if (( nerrs == 0 )); then
exit 0
else
exit 1
fi
------------------------------------------------------------------------
Peter
--
Where do bit streams end? In bit rivers?