简体   繁体   English

bash正则表达式适用于Linux但不适用于solaris

[英]bash regex works on linux but not solaris

The following shell script works in Linux, but won't on Solaris, 以下shell脚本适用于Linux,但不适用于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: Linux的:

GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) Copyright (C) 2005 Free Software Foundation, Inc. GNU bash,版本3.2.25(1)-release(x86_64-redhat-linux-gnu)版权所有(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, 但是在Solaris上

GNU bash, version 3.00.16(1)-release (sparc-sun-solaris2.10) Copyright (C) 2004 Free Software Foundation, Inc. GNU bash,版本3.00.16(1)-release(sparc-sun-solaris2.10)版权所有(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. GNU bash,版本3.2.51(1)-release(sparc-sun-solaris2.10)版权所有(C)2007 Free Software Foundation,Inc。

./regextest.sh -s 10.2.4.3
Invalid

Thanks 谢谢

There's a difference between RegEx implementations (GNU vs. POSIX). RegEx实现(GNU与POSIX)之间存在差异。
POSIX doesn't understand \\b but GNU treats it as you would expect a word boundary . POSIX不明白\\b但GNU把它当作你所期望的一个字边界

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. 由于您一次只测试一个IP,尝试将表达式从使用word boundary \\b更改为使用start of ^$ string / line 结尾 ,这些都在大多数RegEx风格中都被识别。

"^(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]?)$"

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. 可能更慢,当然,但参数检查不应该是你的程序的瓶颈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM