次のスクリプトは、期待したものとは異なる動作をします。条件文で「=」の周りにスペースを追加すると、私は好きなように動作しますが、条件文で実際に何をしているのかを考えました。
#!/bin/bash
S1='foo'
S2='bar'
if [ $S1=$S2 ];
then
echo "S1('$S1') is equal to S2('$S2')
fi
echo $S1
echo $S2
出力は次のとおりです
S1('foo') is equal to S2('bar')
foo
bar
S1とS2の内容は割り当てられた内容を変更しないため、割り当ては行われません。
ベストアンサー1
これは、Bourneに似たほとんどのシェルと同様に、Bashでも[
使用できるtest
コマンドなので、組み込みコマンドなので、info bash [
内部で検索してドキュメントを使用または表示することができますman bash
(man builtin
一部のシステムではbash)。システム全体にも適用されますsh
)。
この記事では:
test
そして、[
引数の数に応じて一連の規則を使用して条件式を評価します。
- 引数0個の
式が偽です。- 1パラメータパラメータ
が空でない場合にのみ、式はtrueです。- 2つのパラメータ
[...]- 3つのパラメータ
[...]
賢明に言えば、コマンド[
の代わりに使用するときの最後(必須)は次のとおりです。test
]
返品1つの引数ですが、これは上記の数字には含まれていません(bashドキュメントから直接参照)。それでも…
2つのパラメータルールはさまざまなテストであり、3つのパラメータルールは通常比較です。周囲にスペースを追加すると、=
3つのパラメータが得られます。しかし、それらを合わせると、一つパラメータは、ご覧のとおり、パラメータがnullでない場合はtrueを返します。
まあ、技術的にはパラメータ拡張[ $S1=$S2 ]
(および他の場所)の引用符を忘れて$S1
しまい$S2
、Split + globの影響を受けるため、より多くのパラメータが[
コマンドに渡される可能性があります。 kshと同様に、bashでもコマンドインジェクションの脆弱性を構成できます。
たとえば、分割された部分として定義され、定義されている$S1
場合、デフォルトはYield、、、です。ワイルドカードは、現在のディレクトリにそのファイルがある場合は拡張されますが、そうでない場合はそのまま渡されます。 bashの組み込み機能には、コマンド出力に基づいてインデックスを決定するために配列要素が設定され拡張されていることを確認するテストがあります。S1='-v xx[$(reboot)] -o yy'
$S2
S2='zz'
$IFS
-v
xx[$(reboot)]
-o
yy=zz
[...]
xx[$(reboot)]
xxo
xxt
xx[$(reboot)]
[
-v array[index]
[
$(reboot)
reboot
正しい構文では、[ "$S1" = "$S2" ]
引用符を忘れないことも重要です。