[
コマンドは通常のコマンドです。ほとんどのシェルは、効率のために組み込みとして提供しますが、シェルの通常の構文規則に従います。[
は、最後の引数としてa test
を[
必要とし、必要]
とtest
しないことを除いて、とまったく同じです。
二重括弧[[ … ]]
は特別な構文です。これらは、正しく使用するのが面倒であり、シェル特殊文字を使用するいくつかの新しい追加ができる[
ため、ksh(数年後)で導入されました。たとえば、次のように書くことができます[
[[
[[ $x = foo && $y = bar ]]
全体の条件式がシェルによって解析されているので、一方で[ $x = foo && $y = bar ]
最初の2つのコマンドに分割される[ $x = foo
と$y = bar ]
により分離&&
演算子。同様に二重括弧は、パターンマッチング構文のようなもの、例えばを有効に[[ $x == a* ]]
する値かどうかをテストするx
と始まりますa
。単一の括弧内a*
でa
は、現在のディレクトリで名前が始まるファイルのリストに展開されます。二重括弧はkshで初めて導入され、ksh、bash、およびzshでのみ使用可能です。
単一の括弧内では、他のほとんどの場所と同様に、変数置換の周りに二重引用符を使用する必要があります。これは、変数がコマンド(たまたま[
コマンド)の引数にすぎないためです。二重括弧内では、二重引用符は必要ありません。シェルは単語の分割やグロビングを行わないためです。コマンドではなく条件式を解析します。
ただし例外[[ $var1 = "$var2" ]]
は、バイト単位の文字列比較を行う場合に引用符が必要な場合です。そうでない場合は、照合$var2
するパターンになります$var1
。
できないことの1つ[[ … ]]
は、変数を演算子として使用することです。たとえば、これは完全に合法です(ただし、ほとんど役に立ちません)。
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
あなたの例では
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
内部コマンドがif
ある[
4つの引数で-d
、/home/mazimi/VirtualBox
、VMs
と]
。シェルは解析され-d /home/mazimi/VirtualBox
、何をすべきかわかりませんVMs
。${dir}
適切な形式のコマンドを取得するには、単語の分割を防ぐ必要があります。
一般的に、結果に対して単語の分割とグロビングを実行することがわかっている場合を除き、変数とコマンドの置換は常に二重引用符で囲みます。二重引用符を使用しないことが安全である主な場所は次のとおりです。
- 割り当て内:(
foo=$bar
ただし、export "foo=$bar"
などの配列割り当て内または二重引用符が必要なことに注意してくださいarray=("$a" "$b")
);
case
声明:case $foo in …
;
- 右側のを除いて二重括弧の内側
=
または==
:演算子(あなたはパターンマッチングを行いたい場合を除きます)[[ $x = "$y" ]]
。
これらすべてで、二重引用符を使用するのが正しいので、高度なルールをスキップして、常に引用符を使用することもできます。