1

Bash の変数展開に苦労しています。次のコードを参照してください。

~/tmp 689$ a=~/Library/Application\ *; echo $a
/Users/foo/Library/Application *

~/tmp 690$ echo ~/Library/Application\ *
/Users/foo/Library/Application Scripts /Users/foo/Library/Application Support

展開の順序は中かっこ->チルダ->パラメータ->....->パス名$aですが、2番目のコマンドと同じようにパス名展開が適用されないのはなぜですか?

[追加した]

空白のエスケープには、次の出力に関して隠された動作がありますか?

~/tmp 705$ a=~/Library/Application*; echo $a
/Users/foo/Library/Application Scripts /Users/foo/Library/Application Support
4

1 に答える 1

8

意図したことを行うには、次を使用する必要があります。

a=(~/Library/Application\ *)  # use an *array* to capture the pathname-expanded results
echo "${a[@]}"                # output all array elements (without further expansion)

コードが機能しなかった理由について:

リテラルまたは文字列補間(他の変数への参照)のみを含む変数割り当てのコンテキストでは、引用符で囲まれていない文字列(たとえば、a=*a="*"およびa='*'すべての割り当てリテラル *) [1]であっても、パス名の展開は行われません。

(対照的に、パス名の展開は、配列定義内 (例: a=(*)、またはコマンド置換(例: ))内の引用符で囲まれていない文字列に適用されますa=$(echo *)。)

したがって、の文字通りの内容$a/Users/foo/Library/Application *

実行echo $a- つまり、変数参照を二重引用符で囲まない$a- 次に、単語分割を適用し、次のことを行います。

  • リテラルを出力します'/Users/foo/Library/Application'(最初の単語-その内容により、展開は適用されません)
  • 適用されたパス名展開を出力します*(2 番目の単語 - つまり、現在のディレクトリ内の一致するファイル名に展開されます。)

あなたのケースで後者の結果になるという事実は、*たまたま空のechoディレクトリからコマンドを実行していることを意味します(デフォルト構成を想定して、隠しファイルを保存します)。


[1]ただし、文字列が引用符で囲まれていないかどうかは、チルダ展開に関して重要です。たとえば、ユーザーのホーム ディレクトリにa=~展開されますが、リテラルを割り当てます。~a='~'a="~" ~

于 2014-12-19T02:42:04.287 に答える