zshとksh93がパターンマッチに従わないのはなぜですか?

zshとksh93がパターンマッチに従わないのはなぜですか?

パターンマッチングのためのPOSIXドキュメント説明する:

一般的な文字は自分と一致するパターンです。 NUL、引用する必要があるQuotingの特殊シェル文字、および次の3つの特殊パターン文字を除く、サポートされている文字セットのすべての文字にすることができます。一致は、文字のグラフィック表現ではなく、文字をエンコードするために使用されるビットパターンに基づいている必要があります。文字(一般、シェル特殊、またはパターン特殊)が引用されている場合、パターンは文字自体と一致する必要があります。。シェル特殊文字には常に引用符が必要です。

私が知っている限り、パターンはとのいずれかに["!"a]一致します。これは、以下を除いて私が試したほとんどのシェルの動作でもあります。!azshksh93

$ for shell in /bin/*[^c]sh; do
  printf '=%-17s=\n' "$shell"
  "$shell" -c 'case a in ["!"a]) echo 1;; esac'
done
=/bin/ash         =
1
=/bin/bash        =
1
=/bin/dash        =
1
=/bin/heirloom-sh =
1
=/bin/ksh         =
=/bin/lksh        =
1
=/bin/mksh        =
1
=/bin/pdksh       =
1
=/bin/posh        =
1
=/bin/schily-osh  =
1
=/bin/schily-sh   =
1
=/bin/yash        =
1
=/bin/zsh         =

zshと同じksh93ようです。以下を除くすべての文字と一致します。["!"a][!a]a

$ for shell in ksh93 zsh; do
  printf '=%-6s=\n' "$shell"
  "$shell" -c 'case b in ["!"a]) echo 1;; esac'
done
=ksh93 =
1
=zsh   =
1

zshこれにはどんな理由がありますか(歴史、発展…)ksh93


zshkshエミュレーションとエミュレーションの両方で同じことを行いますsh

busybox sh、Solaris /usr/xpg4/bin/sh、およびFreeBSDshもPOSIXドキュメントと同様に機能します。


ksh88また、他のほとんどのシェルと同様に、動作はkssh88次の間で変わりますksh93

$ ksh88 -c 'case a in ["!a"]) echo yes; esac'
yes
$ ksh88 -c 'case b in ["a-c"]) echo yes; esac' 
$

ベストアンサー1

あなたが引用した詩は、あなたが言ったことを意味しません。

単一文字に一致するパターン

(…) 一般文字は自分と一致するパターンです。 (…)文字(一般、シェル特殊、またはパターン特殊)が引用されている場合、パターンは文字自体と一致する必要があります。

これらすべては、パターン内で自分を表す文字にのみ適用されます。これは、予想されるパターン文字以外のコンテキストに現れる文字には適用されません。特に括弧式内では機能しません。角かっこ式の構文は、次のトピックで説明されています[

括弧が次のように括弧式を導入する場合XBD REブラケット表現、(…)

!(vs.の部分は省略して追加しました^。)RE角括弧式の説明は引用について何も言いません。 (シェルスクリプトのパターンではなく、一般的な角括弧式に関するものであるため、驚くべきことではありません。)角括弧表現)。

["!"a]POSIX.1-2008の厳密な解釈によれば、パターンが何と一致するべきかは明確ではありません。 1つの解釈は、すべての文字と一致する必要があるということです"。文字は角かっこ式では特別な意味を持ちません。仕様では、この解釈を無効にする内容が見つかりません。別の解釈は、引用の動作が維持されるということです。しかし、これは角かっこ式の内容があることを意味し、角かっこ式内の引用符のための特別な処理がないため、セットはall-but-です。 POSIX仕様では、あなたの解釈(そしてダッシュ、bash、および他のシェルの動作)のサポートが見つかりません。もちろんこれは意味がありますが、そうではありません。!a""!aa

POSIXの将来のバージョンでは、いくつかのフレーズを追加して解釈を強制するのが合理的です。たとえば、説明は[次のように変更できます。

括弧が次のように括弧式を導入する場合XBD REブラケット表現ただし、正規表現表記では、\文字()は一致しないリストで\文字()の役割を'!'置き換える必要があり、パターン角括弧式を導入する必要があります。'^'、引用符付き文字は、それ自体を角括弧式、対照要素、またはクラス式の要素として表します。。引用符のない\文字で始まる角括弧式は、未指定の結果を生成します。それ以外の場合は、'['文字自体が一致する必要があります。

POSIXが規範的ではなく主に説明的であることを考えると、ksh(通常は参照シェル)を損なうこのような変更は標準のメジャーアップデートにのみ含まれ、既存のバージョンのすべての欠陥は少なくとも既存のバージョンが許可すると予想します。別に説明してください。

おすすめ記事