4

次のシェル スクリプトは 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:

GNU bash、バージョン 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

それが期待される結果です。

ただし、Solaris では、

GNU bash、バージョン 3.00.16(1) リリース (sparc-sun-solaris2.10) Copyright (C) 2004 Free Software Foundation, Inc.

./regextest.sh -s 10.2.4.3
Invalid

GNU bash、バージョン 3.2.51(1) リリース (sparc-sun-solaris2.10) Copyright (C) 2007 Free Software Foundation, Inc.

./regextest.sh -s 10.2.4.3
Invalid

ありがとう

4

2 に答える 2

4

RegEx の実装には違いがあります (GNU と POSIX)。
POSIX は理解していませんが、GNU は単語の境界\bとして期待するように扱います。

一度に 1 つの IP をテストしているので、式を単語境界 \bの使用から start of ^end 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]?)$"
于 2013-05-23T16:56:49.063 に答える
2

正規表現の怪物と格闘するのではなく、各オクテットを個別にチェックしてください。

 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"

確かに遅いかもしれませんが、引数のチェックがプログラムのボトルネックになるべきではありません。

于 2013-05-23T16:56:39.793 に答える