[解決済み] bash補完における${array[*]}と${array[@]}の混同について
質問
初めてbash補完を書こうとしているのですが、bash配列の2つの参照方法について少し混乱しています(
${array[@]}
と
${array[*]}
).
ここにコードの関連する塊があります(ちなみに、それは動作しますが、私はそれをよりよく理解したいと思います)。
_switch()
{
local cur perls
local ROOT=${PERLBREW_ROOT:-$HOME/perl5/perlbrew}
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
perls=($ROOT/perls/perl-*)
# remove all but the final part of the name
perls=(${perls[*]##*/})
COMPREPLY=( $( compgen -W "${perls[*]} /usr/bin/perl" -- ${cur} ) )
}
バッシュの のドキュメントによると :
配列のどの要素も ${name[subscript]} を使って参照することができます。中括弧は、シェルのファイル名展開演算子との衝突を避けるために必要です。添え字が '@' または '*' の場合、単語は配列名のすべてのメンバに展開されます。これらの添え字は、単語が二重引用符で囲まれている場合のみ異なります。単語が二重引用符で囲まれている場合、${name[*]} は、各配列メンバの値を IFS 変数の最初の文字で区切った 1 つの単語に展開し、${name[@]} は name の各要素を別の単語として展開します。
今、私は理解したつもりですが
compgen -W
が可能な選択肢の単語リストを含む文字列を期待することは理解できたと思いますが、この文脈では "${name[@]} expands each element of name to a separate word" が何を意味するのか理解できていません。
長い話になりますが
${array[*]}
が動作します。
${array[@]}
は動作しません。私はその理由を知りたいと思いますし、また、具体的にどのような
${array[@]}
は何に展開するのか、もっとよく理解したいと思います。
どのように解決するのですか?
(これはKaleb Pedersonの回答に対する私のコメントの拡張です。
[@]
対
[*]
.)
bash (または類似のシェル) がコマンドラインを解析するとき、それは一連の "単語" (後で混乱を避けるために "shell-words" と呼ぶことにします) に分割されます。 一般に、シェルワードはスペース(または他の空白文字)で区切られますが、スペースをエスケープするか引用符で囲めば、シェルワードに含めることができます。 以下の違いは
[@]
と
[*]
-二重引用符で囲まれた展開された配列は
"${myarray[@]}"
では配列の各要素が個別のシェルワードとして扱われるのに対し
"${myarray[*]}"
では配列のすべての要素が空白で区切られた一つのシェルワードになります (あるいは
IFS
の最初の文字が何であれ)。
通常は
[@]
の動作が必要です。 例えば
perls=(perl-one perl-two)
を使用し
ls "${perls[*]}"
-- と同じです。
ls "perl-one perl-two"
という名前のファイルを探しますが、これは
perl-one perl-two
という名前のファイルを探しますが、これはおそらくあなたが望んだものではありません。
ls "${perls[@]}"
と同じです。
ls "perl-one" "perl-two"
と同じであり、その方が何か役に立つことをする可能性が高いです。
補完語のリスト (シェル語と混同しないように comp-words と呼ぶことにします) を
compgen
は異なります。
-W
オプションは comp-words のリストを取りますが、 comp-words を空白で区切った一つのシェルワードの形式でなければなりません。 そうでなければ、オプションへの引数がいつ終わり、通常のコマンド引数 (/other オプションフラグ) がいつ始まるかを見分ける方法がありません。
より詳細には
perls=(perl-one perl-two)
compgen -W "${perls[*]} /usr/bin/perl" -- ${cur}
とは等価である。
compgen -W "perl-one perl-two /usr/bin/perl" -- ${cur}
...これは、あなたが望むことをします。 一方
perls=(perl-one perl-two)
compgen -W "${perls[@]} /usr/bin/perl" -- ${cur}
とは等価である。
compgen -W "perl-one" "perl-two /usr/bin/perl" -- ${cur}
...これは完全にナンセンスです: "perl-one" は -W フラグに付けられた唯一の comp-word で、最初の本当の引数は -- compgen が補完する文字列として受け取るもの -- "perl-two /usr/bin/perl" です。 私は compgen が余分な引数 ("--" と $cur にあるもの) を与えられたと文句を言うと思っていましたが、どうやらそれは無視されるだけでした。
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Java の配列を表示する最も簡単な方法は何ですか?
-
[解決済み] Bashでコマンドの出力に変数を設定するにはどうすればよいですか?
-
[解決済み] JavaScriptで配列の先頭に新しい配列要素を追加するにはどうすればよいですか?
-
[解決済み] Bashで文字列の配列をループする?
-
[解決済み] Bashでファイルの中身をループする
-
[解決済み] 配列の最後の項目を取得する
-
[解決済み] 好ましいBashのシェバングとは?
-
[解決済み] Bashでインデックスを指定せずに配列に新しい要素を追加する
-
[解決済み] Bashで文字列を配列に分割する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】アセンブリ言語での配列のバブルソート
-
[解決済み】IndexError: Index 10 is out of bounds for axis 0 with size 10
-
[解決済み] MIPSで配列を作る(アクセスする)方法
-
[解決済み] MATLABで動的配列を作成する方法
-
[解決済み] Rで3D行列をセットアップし、特定の要素にアクセスする
-
[解決済み] MASMアセンブリの配列 (非常に混乱している初級者)
-
[解決済み] SwiftでUInt8バイト配列を文字列に変換する方法
-
[解決済み] GCCです。配列型に不完全な要素型がある
-
[解決済み] 配列はトップレベルのJSON-textになり得るか?
-
[解決済み] 配列全体のダンプ:console.log と console.dir の出力は "... NUM more items "です。]