理由はありません
[[ $a = a|b ]]
$ aがa|b文字列かどうかをテストする代わりにエラーを報告する必要がありますが、[[ $a =~ a|b ]]エラーは返されません。
唯一の理由は、|一般的に(外側と内側[[ ... ]])特殊文字であるということです。その[[ $a =位置でbashは、通常のシェルコマンドラインの引数またはリダイレクトのターゲットのような通常のWORDであるトークンのタイプを期待します(ただしextglob、bash 4.1以降でオプションが有効になっているかのように)。
(ここではWORDで、POSIX仕様で説明されているような架空のシェル文法の単語を参照します。これは、シェルが英語のような単語の他の定義ではなく、単純なシェルコマンドラインで1つのトークンとして解析するものです文字または非間隔文字の配列の配列のいずれか。、、二つのそのようなあるWORD)S。foo"bar baz"$(echo x y)
通常のシェルコマンドラインでは:
echo a|b
にecho aパイプされbます。a|bはWORDではなく、3つのトークン:a WORD、|トークン、およびb WORDトークンです。
で使用する場合[[ $a = a|b ]]、取得bashするWORDをa予期し|ますが()、エラーを引き起こす予期しないトークンを検出します。
興味深いことに、bash不満はありません:
[[ $a = a||b ]]
それは今だからa続くトークン||が続くトークンb:それは同じように解析されていますので、
[[ $a = a || b ]]
それがテストで$aあるaか、それともb文字列が空でないことです。
今:
[[ $a =~ a|b ]]
bash同じ解析ルールを持つことはできません。同じ解析ルールを持つことは、上記がエラーを与え、それ|がa|b単一のWORDであることを保証するためにそれを引用する必要があることを意味するでしょう。ただし、bash 3.2以降では、次のようになります。
[[ $a =~ 'a|b' ]]
これは、a|b正規表現ではなく、正規表現と一致しa\|bます。つまり、シェルの引用には、正規表現演算子の特別な意味を削除するという副作用があります。これは機能であるため、動作は[[ $a = "?" ]]1つに似ていますが、ワイルドカードパターン(で使用[[ $a = pattern ]])はシェルWORDS(たとえばglobsで使用)であり、正規表現はそうではありません。
だから、bashそうでない場合は、通常のような特殊なシェル文字であるすべての拡張正規表現の演算子を処理するために持って|、(、)の引数の解析異なったときに=~オペレータを。
それでも、その間
[[ $a =~ (ab)*c ]]
動作します
[[ $a =~ [)}] ]]
しません。必要なもの:
[[ $a =~ [\)}] ]]
[[ $a =~ [')'}] ]]
の以前のバージョンでbashは、バックスラッシュが間違って一致していました。これは修正されましたが、
[[ $a =~ [^]')'] ]]
たとえば、バックスラッシュとは一致しません。かっこ内にあるbashことを認識できないため)、)toをエスケープして、と以外の[^]\)]すべての文字に一致する正規表現を生成します。]\)
ksh93 その前部にはるかに悪いバグがあります。
でzsh、これは通常のシェル単語であり、正規表現演算子を引用しても正規表現演算子の意味には影響しません。
[[ $a =~ 'a|b' ]]
a|b正規表現と照合します。
これは、/ コマンドに=~も追加できることを意味します。[test
[ "$a" '=~' 'a|b' ]
test "$a" '=~' 'a|b'
(でも動作しyashます。特別なシェル演算子と同様=~に引用符で囲む必要があります)。zsh=something
bash 3.1はのように振る舞っていましたzsh。それはおそらくに合わせて、3.2に変更ksh93(たとえbash最初に思いついたことをシェルだった[[ =~ ]]あなたはまだやることができます)が、BASH_COMPAT=31あるいはshopt -s compat31その中には除いて(以前の動作に戻す[[ $a =~ a|b ]]には、エラーが返されますbash、それはもうない、3.1のbash -O compat31新しいバージョンでbash)。
ルールが混乱していると言った理由と、以下を使用する理由が明確になることを願っています。
[[ $a =~ $var ]]
他のシェルへの移植性を含めるのに役立ちます。
|特別な場合)はデフォルトでの右側でオンになっていることに注意してください[[ $var = $pattern ]]。shoptこの動作が見られるバージョンとオプションの構成を分離することは興味深いでしょう。extglobデフォルトまたは明示的な構成のいずれかでオンになっているものだけである場合は、そうです。