割り当て前にチルダプレフィックスは拡張されますが、中かっこが拡張されないのはなぜですか?

割り当て前にチルダプレフィックスは拡張されますが、中かっこが拡張されないのはなぜですか?

tl;ディレクトリ

Bashでは、チルダ拡張の前に中括弧拡張が行われます。しかし、チルダプレフィックスは変数の割り当て前に拡張されているように見えますが、中括弧の拡張はそうではありません。なぜ?

詳細と例

サポート拡張Bashでは、以下で発生したものとして記録されます。チルダ拡張:

中括弧の拡張は、他の拡張の前に実行されます。

私が理解したのは、次の例のように、チルダ拡張が変数の割り当て前に発生します。

# UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
tilde=~
echo "$tilde"
# /Users/DeNovo
[[ $tilde == "$HOME" ]] && echo "literal match"
# literal match

# QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
lit_tilde='~'
echo "$lit_tilde"
# ~
# UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
# AS EXPECTED
eval echo "$lit_tilde"
# /Users/DeNovo
[[ $lit_tilde == "~" ]] && echo "literal match"
# literal match

これらの例は、右オペランドがleft=right左オペランドに値にバインドされる前にチルダ拡張を受けることを示すようです。

ただし、中括弧拡張は変数の割り当て前には行われず、リテラルチルダを変数にバインドするのと同様に機能します(拡張特殊文字/プレフィックスと比較して)。

# UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
brace={a..c}
echo "$brace"
# {a..c}
[[ $brace = "a b c" ]] || echo "doesn't match"
# doesn't match
[[ $brace = "{a..c}" ]] && echo "literal match"
# literal match

# SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE 
# RESULTS IN BRACE EXPANSION
eval echo "$brace"
# a b c

両方の拡張を単一の例にまとめると、チルダ拡張が発生しますが、中かっこ拡張は発生しないことがわかります。

combined=~/dir_{a..c}
echo "$combined"
# /Users/DeNovo/dir_{a..c}

中括弧は、割り当て中に内部チルダが拡張されるのを防ぎます。

internal_tilde={~,~+}/new_dir
echo "$internal_tilde"
# {~,~+}/new_dir

# vs the same output, not in a variable
echo {~,~+}/new_dir
/Users/DeNovo/new_dir /Your/Working/Directory/new_dir

明確にするために、中括弧拡張の結果を含む変数を取得する方法を尋ねるのではなく、チルダ拡張の前に発生したにもかかわらず、変数の割り当て前に中括弧拡張が発生しない理由を尋ねることです。希望する動作を取得する方法はいくつかあります。これは:

# PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
brace_exp="$(echo {a..c})"
echo "$brace_exp"
a b c
[[ $brace_exp = "a b c" ]] && echo "literal match"
# literal match

繰り返しますが、チルダ拡張はなぜ変数割り当ての前に発生しますが、中括弧拡張(チルダ拡張の前に発生する必要がある)は、変数割り当て前には発生しません。おそらくその使命は私が知らない何らかの点で特別なようです。

ベストアンサー1

テストでは、{a..c}拡張は変数の割り当ての一部であり、処理されるため、拡張はありません。それぞれ:

  1. パーサによって変数割り当てとしてマークされた単語(コマンド名の前の単語)とリダイレクトは、後で処理するために保存されます。
  2. 変数の割り当てやリダイレクトではない単語は拡張されます。シェル拡張)。拡張後に残りの単語がある場合、最初の単語はコマンド名として扱われ、残りの単語は引数として扱われます。

割り当てられた値は中括弧で拡張されません。

  1. 各変数の割り当てでは、 ""の後=に続くテキストは、変数に割り当てられる前にチルダ拡張、パラメータ拡張、コマンド置換、算術拡張、および引用符の削除を経ます。

おすすめ記事