Bashでドル記号の評価に二重引用符を入れるのはなぜですか? [コピー]

Bashでドル記号の評価に二重引用符を入れるのはなぜですか? [コピー]

一重引用符は内部内容を評価しませんが、二重引用符は評価することを知っています。人々がドル記号を引用するレビューをよく見ます。ここにいくつかの例があります。

  • for i in "${indices[@]}"; do
  • if [ "${a}" == 0 ]; then
  • ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4

ドル記号表現を二重引用符で囲まないとどうなりますか? AFAIK、forループはまだ動作します。

ベストアンサー1

3つの例はまったく同じではありません。

最後の2つのうち:

if [ "${a}" == 0 ]; then
ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4

$a引用符ではなく、その値に文字$IFS(デフォルトでは空白、タブ、および改行)またはワイルドカードが含まれている場合、3つ以上の引数(および[除外)が受け取られ、値が空の場合でも同様にエラーが発生します。文字列のため、少なすぎるパラメータを受け取ります。[]$a[

$ (a=0; [ $a == 0 ] && echo OK)
OK

(ただし、$IFS現在含まれていない場合のみ0

$ (a='foo bar'; [ $a == 0 ] && echo OK)
bash: [: too many arguments

(デフォルトは$IFS

$ (a=; [ $a == 0 ] && echo OK)
bash: [: ==: unary operator expected

(空であるか$IFSwithを使用してもzsh(そうでない場合は、暗黙の分割+glob演算子が引用されていない拡張では実装されていません))

$ (a='*'; [ $a == 0 ] && echo OK)
bash: [: too many arguments

(非表示のファイルが2つ以上含まれているディレクトリで実行されている場合)

ちなみにエラーはありません。

$ (a='foo bar'; [ "$a" == 0 ] && echo OK)
$ (a=; [ "$a" == 0 ] && echo OK)

最初の例は異なります。a配列が含まれている場合、二重引用符内の拡張規則は特別です。

  • $a配列の最初の要素です。厳密に言えば、${a[0]}インデックス0の要素が定義されていない場合でも同様です。

  • ${a[*]}またはさらに${a[@]}分割される配列要素$IFS(デフォルトでは空白、タブ、改行)。

  • "${a[@]}"で分割されていない配列の要素です$IFS

したがって、ループはfor i in "${indices[@]}"; do ...配列の内容によって実際には同じではありません。たとえば、

$ (declare -a a=(a b c); printf '%s\n' $a)
a

$ (declare -a a=(a b c); printf '%s\n' ${a[*]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' ${a[*]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' ${a[@]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' "${a[*]}")
a b c

$ (declare -a a=(a 'b c'); printf '%s\n' "${a[@]}")
a
b c

おすすめ記事