somethingelse
somethingelse

Reputation: 59

bash regex works on linux but not solaris

The following shell script works in Linux, but won't on Solaris,

#!/usr/bin/bash
while getopts ":s:" opt; do
  case $opt in
    s)
      # Check IP against regex
      if [[ "$OPTARG" =~ "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" ]]; then
        IP=$OPTARG
      else
        echo "Invalid"
        exit 1
      fi
      ;;
  esac
done

Linux:

GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) Copyright (C) 2005 Free Software Foundation, Inc.

$ ./regextest.sh -s 10.2.4.3
$


$ ./regextest.sh -s 10.notaIP.10
Invalid

That is the expected result.

However on Solaris,

GNU bash, version 3.00.16(1)-release (sparc-sun-solaris2.10) Copyright (C) 2004 Free Software Foundation, Inc.

./regextest.sh -s 10.2.4.3
Invalid

GNU bash, version 3.2.51(1)-release (sparc-sun-solaris2.10) Copyright (C) 2007 Free Software Foundation, Inc.

./regextest.sh -s 10.2.4.3
Invalid

Thanks

Upvotes: 4

Views: 902

Answers (2)

CSᵠ
CSᵠ

Reputation: 10169

There's a difference between RegEx implementations (GNU vs. POSIX).
POSIX doesn't understand \b but GNU treats it as you would expect a word boundary.

Since you're testing a single IP at a time, try changing your expression from using word boundary \b to using start of ^ and end of $ string/line, which are both recognized in most RegEx flavors.

"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"

Upvotes: 4

chepner
chepner

Reputation: 531215

Rather than wrestle with that monstrosity of a regular expression, just check each octet separately:

 IFS=. read a b c d extra <<< "$OPTARG"
 [[ -n $extra ]] && { echo "Too many octets"; exit 1; }
 for octet in "$a" "$b" "$c" "$d"; do
     [[ $octet =~ [[:digit:]]+ ]] &&
     (( octet <= 255 )) || {
       echo "Octet '$octet' must be a single byte"; exit 1
     }
 }
 IP="$a.$b.$c.$d"

Possibly slower, sure, but argument checking shouldn't be a bottleneck in your program.

Upvotes: 2

Related Questions