主にJavaプログラマーとして、私はbash if
を見つけました –then
特に空白に関しては、非常に紛らわしい構成になります。最初のものは機能するが、2番目または3番目は機能しない理由を誰かが説明できますか?
#works
if [ -n $1 ]; then echo "parameterized"; fi
#output: ./links: Zeile 1: [-n: Kommando nicht gefunden.
if [-n $1 ]; then echo "parameterized"; fi
#output: ./links: Zeile 1: [: Fehlende `]'
if [ -n $1]; then echo "parameterized"; fi
承認された回答:
不整合は主に歴史的な理由によるものです。
条件付きコマンドとして角かっこを使用したのは、ワイルドカードパターンで角かっこを使用した後です。したがって、その時点で[ -n foo ]
シーンに登場した、[foo]
すでに「f
という名前のファイル」を意味していました またはo
」。実際の括弧演算子の使用法は、ワイルドカードでの括弧の実際の使用法と競合することはほとんどありませんが、作成者は、構文を変更して既存のスクリプトを壊すリスクを冒さないことを選択しました。この設計上の選択により、実装も容易になりました。最初は[
[
の後のスペースがあれば実行できなかった、外部コマンドとして実装されました オプションでした。 (最新のシステムにはまだ[
があります 外部コマンドとしてですが、ほとんどすべての最新のシェルにも組み込まれています。)
同様の理由で、ほとんどの状況で「動作する」コードは実際には正しくありません。 $1
「パラメータ1の値」を意味するのではなく、「パラメータ1の値を取得し、空白(またはIFS
の値)で別々の単語に分割する」ことを意味します。 is)、そして各単語をグロブパターンとして解釈します。 「パラメータ1の値」を記述する方法には、二重引用符が必要です:"$1"
。二重引用符が必要なのはいつですか?を参照してください。核心のために。これを理解する必要はありません。覚えておく必要があるのは、次のとおりです。変数の置換は常に二重引用符で囲みます"$foo"
およびコマンドの置換"$(foo)"
。したがって:
if [ -n "$1" ]; then …
bash、ksh、zshでは、プレーンshではなく、二重角かっこを使用することもできます。単一の角かっこ[ … ]
通常のコマンドのように解析されます(実際、[
通常は組み込まれていますが、通常のコマンドです)。二重括弧は別個の構文構造であり、ほとんどの場合、二重引用符を省略できます。
if [[ -n $1 ]]; then …
ただし、例外があります:[[ "$foo" = "$bar" ]]
2つの変数の値が同じかどうかをテストするには、$bar
を二重引用符で囲む必要があります。 、それ以外の場合は$bar
ワイルドカードパターンとして解釈されます。繰り返しになりますが、詳細を覚えておくのではなく、常に二重引用符を使用することをお勧めします。