tags:

views:

90

answers:

4

hi all

my question is , I want to get some short and smart ideas to verify the IP address then my example

Maybe some perl syntax that I can combine in my ksh script

lidia

+1  A: 

Don't reinvent the wheel.

use strict;
use warnings;
use Regexp::Common qw/net/;
# see http://search.cpan.org/dist/Regexp-Common/lib/Regexp/Common/net.pm

my $Address = '...';
# adapted from the module's synopsis
for ( $Address ) { 
    /$RE{net}{IPv4}/       and print "Dotted decimal IP address";
    /$RE{net}{IPv4}{hex}/  and print "Dotted hexadecimal IP address";
    /$RE{net}{IPv4}{oct}{-sep => ':'}/ and
                           print "Colon separated octal IP address";
    /$RE{net}{IPv4}{bin}/  and print "Dotted binary IP address";
    /$RE{net}{MAC}/        and print "MAC address";
    /$RE{net}{MAC}{oct}{-sep => " "}/ and
                           print "Space separated octal MAC address";
}

Use the one you need.

If you cannot install the module, then just lurk through the module's code and get the correct regexp to use, depending on what kind of IP address you'd like to match.

Or, just use something like the above and call the same sub if the address matches any of the notations you want, or something along those lines.

Using it from your shell script would be along the lines of:

return perl -e'use Regexp::Common qw/net/;$ip=shift;if ($ip =~ /$RE{net}{IPv4}/){exit 0}else{exit 1}' "$Address";

The above would replace your complete "case" block.

Again, if you need to inline the regex in the perl script call you can do so by reading the module's code.

mfontani
not good I need this syntax as part of my shell script
lidia
read the bit "If you cannot install the module...": just read the module's code and use the correct regex for what you want. If you want I'll update it with the regex for IPv4
mfontani
A: 
check(){
  case "$1" in
     [0-9]|[0-9][0-9]|[0-1][0-9][0-9]|2[0-4][0-9]|25[0-5] ) echo "0";;
     *) echo "1";;
  esac
}
ip="$1"
OIFS="$IFS"
IFS="."
set -- $ip
result="$(check $1)$(check $2)$(check $3)$(check $4)"
case "$result" in
  "0000" ) echo "IP $ip Ok";;
  *) echo "IP $ip not ok";;
esac
IFS="$OLDIFS"
ghostdog74
Fails for almost a third of the range 0-255 (for example 106 and 239). Why not do: `check () { case "$1" in [0-9]|[0-9][0-9]|[0-2][0-9][0-9]) (( $1 >= 0 ; *) echo "1";; esac; }` to validate that there are only digits and that they fall within the proper range?
Dennis Williamson
you are right. added more checks. Not going with the integer comparison method.
ghostdog74
A: 

Bash >= version 3.2 (this could be shortened up considerably):

valid () {
    if [[ $1 =~ ^[[:digit:]]+$ ]] && 
       (( $1 >= 0 && $1 <= 255 ))
    then
        echo "0"
        return 0
    else
        echo "1"
        return 1
    fi
}

saveIFS=$IFS
IFS='.'
ip=($1)
IFS=$saveIFS
for octet in ${ip[@]}
do
    if ! valid $octet > /dev/null
    then
        valid=1
    fi
done
[[ $valid != 1 ]] && echo "Good address" || echo "Bad address"
Dennis Williamson
ip=($1) not valid in ksh
lidia
A: 

Split the address without touching IFS and avoid complicated checks by bitwise shift:

declare -a part=( ${ip//\./ } )
declare -i valid=0

for p in ${part[@]}; do
  if [[ $p =~ ^[[:digit:]]+$ ]] ; then
    ((valid += p>>8 ))
  else
    ((valid++))
  fi
done

if [ $valid -eq 0 ] ; then
  echo -e "$ip     OK"
else
  echo -e "$ip NOT OK"
fi
fgm
how this script know if number is over 255 , because 256 num isnt valid number
lidia
this script cant run in ksh
lidia