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

答え2

簡単に言えば、これは変数に存在する可能性のある特殊文字(たとえば)による拡張を防ぐために行われます!。特定の文字(ドル記号、バックティック、バックスラッシュ)が解釈されるため、二重引用符は「弱い引用符」とも呼ばれます。一重引用符は「強い引用符」であり、何も解釈しません。

引用するバッシュ文書:

3.1.2.3二重引用符

文字を二重引用符()で囲むと、(履歴拡張が有効になっている場合)以外の引用符内のすべての文字のリテラル値が保持されます"。シェルがPOSIXモードにある場合(Bash POSIXモードを参照)、履歴拡張が有効になっていても、二重引用符内に特別な意味はありません。$backquote\!!

弱い参照と強い参照の例:

  • echo "Your PATH is: $PATH"- 印刷されますYour PATH is:<variable_content>
  • echo 'Your PATH is: $PATH'- 印刷されますYour PATH is: $PATH

あなたの質問に答えるために変数に二重引用符を使用して拡張を許可します$が、変数の内容がもはや拡張されないようにします。

関連情報:

関連情報