それは、Bourneシェルのハックとして始まりました。Bourneシェルでは、リストコンテキスト内のすべての単語(コマンドライン引数またはforループがループする単語)に対してIFS単語分割が行われました(トークン化後)。持っていた場合:
IFS=i var=file2.txt
edit file.txt $var
二行目は3つのワードでトークン化されることは、$var拡大されるだろう、とあなたが実行して終わるだろうので、スプリット+グロブは、すべての3つの単語で行われることになるedとt、f、le.txt、f、le2.txt引数として。
その一部を引用すると、split + globが妨げられます。Bourneシェルは、最初に8ビット目を内部に設定することで、引用された文字を記憶しました(Unixが8ビットクリーンになったときに変更されましたが、シェルは引用されたバイトを記憶するのと同じようなことをしました)。
両方$*と$@インとの間の空間との位置パラメータを連結しました。しかし、$@二重引用符の内側にあるときの特別な処理がありました。$1包含foo barおよび$2包含の場合baz、次の"$@"ように展開されます。
foo bar baz
^^^^^^^ ^^^
(^上記のsは、どの文字に8番目のビットが設定されているかを示します)。最初のスペースが引用された(8番目のビットが設定されていた)が、2番目のスペース(単語の間に追加されたもの)は引用されていません。
そして、引数の分離を処理するのはIFS分割です(スペース文字が$IFSデフォルトのままであると仮定)。これ$*は、前身のMasheyシェル(それ自体がThomsonシェルに基づいており、Bourneシェルはゼロから作成された)で拡張された方法に似ています。
これは、Bourneシェル"$@"で、位置パラメーターのリストが空のときに何もではなく空の文字列に最初に展開する理由(を使用して回避する必要がありました${1+"$@"})、空の位置パラメーターを保持しない理由"$@"、$IFSスペース文字が含まれていないと機能しません。
引数のリストを別のコマンドに逐語的に渡すことができるようにすることでしたが、それは空のリスト、空の要素、または$IFSスペースが含まれていない場合には正常に機能しませんでした(最初の2つの問題は後のバージョンで修正されました) )。
POSIX仕様のベースであるKornシェルは、いくつかの方法でその動作を変更しました。
- IFS分割のみ(ないような文字通りの言葉に引用符で囲まれていない拡張の結果で行われる
editか、file.txt上記の例では)
$*そして、空の場合は$@最初の文字$IFSまたはスペースで結合$IFSされますが"$@"、quoterの場合はジョイナーはBourneシェルのように引用されず、引用された"$*"場合IFSは空の場合、位置パラメーターはセパレータなしで追加されます。
- それはアレイのサポートを追加し、そしてと
${array[@]} ${array[*]}ボーンのを連想させる$*と$@が、その手段indice 0の代わりに1、および(より連想配列のような)の疎始まる$@と比較kshのアレイ(として実際に処理することができませんcsh/ rc/ zsh/ fish/ yashここで、$argv/は$*正常です配列)。
- 空の要素は保持されます。
"$@"when $#is 0は空の文字列の代わりに何も展開せず、when が空の場合を除いてスペースが含まれていない"$@"場合に$IFS機能しIFSます。$*ワイルドカードなしの引用符なし$IFSは、空の場合、1つの引数(位置パラメーターがスペースで結合されている)に展開されます。
ksh93は、上記の残りのいくつかの問題を修正しました。ksh93、内$*及び$@位置パラメータのリストに展開さの値にかかわらず分離$IFSし、その後さらに分割+グロビングされ+ブレース展開、リストコンテキストで$*最初に接合バイトの(ない文字)$IFS、"$@"リストにリストコンテキストの拡大に位置パラメータのかかわらず、の値$IFS。非リストコンテキストでは、のようにvar=$@、$@の値にかかわらず空間と接合されています$IFS。
bashの配列は、ksh配列の後に設計されています。違いは次のとおりです。
- 引用符で囲まれていない展開時のブレース展開なし
$IFSバイトではなくの最初の文字
$*when $IFSが空の場合の非リストコンテキストでの非引用時の拡張など、いくつかのコーナーケースの違い。
POSIX仕様は以前はかなり曖昧でしたが、現在では多かれ少なかれbashの動作を指定しています。
それはで、通常の配列と異なるのですkshかbashという点で:
- インデックスは0ではなく1から始まります(ただし、
"${@:0}"インクルード$0(位置パラメータではなく、関数内では関数の名前を提供するか、シェルおよび関数の定義方法に依存しない)を除く)。
- 要素を個別に割り当てることはできません
- スパースではなく、要素を個別に設定解除することはできません
shift に使える。
zshまたはyashアレイが正常アレイである場合(ないスパース、インデックスが他のすべてのシェルが、kshの/ bashでのようなもので開始)、$*通常の配列として扱われます。zshの$argvエイリアスとして使用します(との互換性のためcsh)。or $*と同じです(引数はリストコンテキストの最初の文字と結合されていますが、まだ分離されています)。Kornスタイルの特別な処理を好む、または受けます。$argv${argv[*]}$IFS"$@""${argv[@]}""${*[@]}"}