シェルスクリプトで、ある変数を別の変数に割り当てるときのこれら2つの違いは何ですか:
a=$b
と
a="$b"
また、いつどちらを使用する必要がありますか?
単独でステートメントとして使用される場合、変数代入の RHS を二重引用符にする (正当な) 理由はありません。
代入ステートメントの RHS は単語分割 (またはブレース展開) などの対象にならないため、正しく代入するために引用符は必要ありません。他のすべての展開 (私が知る限り) は RHS で発生しますが、二重引用符でも発生するため、引用符は役に立ちません。
そうは言っても、RHS を引用しない理由があります。つまり、Bashコマンド置換でエラー「bash:!d': event not found」に対処する方法です(具体的には、私の回答とriciの回答を参照してください)。
他の例をいくつか示します: (現在のディレクトリに 2 つのファイルがありt.sh
、file
)
a='$(ls)' # no command substitution
b="$(ls)" # command substitution, no word splitting
c='*' # no filename expansion
d="*" # no filename expansion
e=* # no filename expansion
f=$a # no expansions or splittings
g="$a" # no expansions or splittings
h=$d # no expansions or splittings
echo ---'$a'---
echo $a # no command substitution
echo ---'$b'---
echo $b # word splitting
echo ---'"$b"'---
echo "$b" # no word splitting
echo ---'$c'---
echo $c # filename expansion, word splitting
echo ---'"$c"'---
echo "$c" # no filename expansion, no word splitting
echo ---'$d'---
echo $d # filename expansion, word splitting
echo ---'"$d"'---
echo "$d" # no filename expansion, no word splitting
echo ---'"$e"'---
echo "$e" # no filename expansion, no word splitting
echo ---'$e'---
echo $e # filename expansion, word splitting
echo ---'"$f"'---
echo "$f" # no filename expansion, no word splitting
echo ---'"$g"'---
echo "$g" # no filename expansion, no word splitting
echo ---'$h'---
echo $h # filename expansion, word splitting
echo ---'"$h"'---
echo "$h" # no filename expansion, no word splitting
出力:
---$a---
$(ls)
---$b---
file t.sh
---"$b"---
file
t.sh
---$c---
file t.sh
---"$c"---
*
---$d---
file t.sh
---"$d"---
*
---"$e"---
*
---$e---
file t.sh
---"$f"---
$(ls)
---"$g"---
$(ls)
---$h---
file t.sh
---"$h"---
*
注目すべき興味深い点の 1 つは、変数の代入が二重引用符で囲まれている場合、および RHS が"$(ls)"
暗黙的にではなく明示的に指定されている場合、変数の割り当てでコマンド置換が発生すること"$a"
です。
変数を参照するときは、通常、その名前を二重引用符で囲むことをお勧めします。これにより、引用符で囲まれた文字列内のすべての特殊文字が再解釈されなくなります。単語の分割を防ぐために二重引用符を使用します。二重引用符で囲まれた引数は、空白区切りが含まれていても、1 つの単語として表示されます。