どのような状況でBash変数を二重引用符で囲んではいけませんか? [コピー]

どのような状況でBash変数を二重引用符で囲んではいけませんか? [コピー]

[[...]]insideのように、Bashで変数を拡張するときや変数の割り当ての右側に使用するときに二重引用符を必要としない状況がいくつかあることがわかります。

変数の引用を読むときに二重引用符が必要ない場合はまれです。

どのような状況で引用行為が望ましくないのですか?参照が不要な状況を言うのではなく、参照変数が何かの動作を積極的に妨げる状況を言うことです。

答え1

空の変数を消去するには(空の文字列を保持するのとは対照的に)引用しないでください。

verbose=
[[ some_condition ]] && verbose=-v

# ...later...

some_program $verbose some_args

変数にスペースで区切られた引数が含まれ、シェルがそれを別の単語として扱うようにするには、引用しないでください。

exclude_file=
[[ -s excludelist.txt ]] && exclude_file='--exclude excludelist.txt'

# ...later...

rsync -avP $exclude /path/to/source/ remote:target

一般的なアプローチは常に二重引用符を使用します。なぜあなたがそれをしたくないのかわからない限り

答え2

シェルが「ああ、これは全体ではなく個々の要素です!」と思わせたい場合は、引用を避けることが望ましいです。このようなものは配列に非常に便利です。

bash-4.3$ var="one two three"
bash-4.3$ arr=( $var  )
bash-4.3$ for i in "${arr[@]}"; do echo "$i"; done
one
two
three

特に、上記の例のような配列を作成するときに便利です。私はUbuntuワークスペースの実際のアドレスを列挙するときに個人的にこの方法を使います(正確な用語はビューポートであり、X、yなどの座標形式を使用しますが、まったく異なる話です)。

別の方法は、変数を別々の項目として扱う必要がある他のコマンドに変数を提供することです。比較する:

bash-4.3$ bash -c 'for item; do echo $item; done' sh "$var"
one two three
bash-4.3$ bash -c 'for item; do echo $item; done' sh $var
one
two
three

注釈に記載されている問題を解決するために、これらの例は「予期しない入力」と一緒に使用するのではなく、制御された環境で使用するためのものです。またset noglob、グローバルマッチングを回避したい場合にも使用できますが、やはり一部の文字列の組み合わせ(デスクトップビューポートの数値など)の配列を作成したい場合はまったく危険ではありませんglog。実際のユーザー入力を処理する場合は、この質問のトピックではなく引用符を使用する必要があります。

答え3

[] = 組み込み、携帯性の向上

[[]] = 複合コマンド、追加された機能

複数のプラットフォームでインデントが共有されるスクリプトを生成するときは、単一​​の角かっこを使用することをお勧めします。

関連情報