bash - if文の括弧はどのような役割を果たしますか? [コピー]

bash - if文の括弧はどのような役割を果たしますか? [コピー]

おそらくこれはbashにのみ適用されませんが、ifステートメントで括弧の役割について混乱しています。最大はい次の形式があるようです。

if [ expression ]; then
    #do stuff
fi

しかし、それがいつも私に効果があるわけではありません。たとえば、次のスクリプトがありますtest.sh

#!/bin/bash

flag=False
if ! $flag; then
    echo "No brackets: Flag is $flag"
fi
if [ ! $flag ]; then
    echo "With brackets: Flag is $flag"
fi
echo "The end."

どの印刷

$ ./test.sh
No brackets: Flag is False
The end.

したがって、括弧を使用する文は無視されるか、Falseと評価されます。なぜこれが起こるのですか?括弧は何をしますか?

二重括弧も見たことがあります。それらはどのように使用されますか?

-

編集:重複した質問があると主張する(これそしてこれ)はこの質問の小さな部分にのみ答えます。括弧で囲まれた構文が失敗する理由(私の考えでは評価されなければならないtest ! false)と括弧内の構文が成功する理由はまだ不明ですtrue(@ilkkachuがコメントで述べたように実際に失敗する必要があるようです)。

ベストアンサー1

大文字と小文字を区別しないファイルシステム(macOSなど)を除くすべてのUnixでは、次の文if

if ! $flag; then
    echo "No brackets: Flag is $flag"
fi

出力を生成します

bash: False: command not found
No brackets: Flag is False

macOSでは、ファイルシステムは大文字と小文字を区別しないため、コマンドは標準False(外部)コマンドと同じであるため、このエラーは生成されません。false

どちらの場合も、テストは! $flag正確であるため(他の理由により)テキストが印刷されます。ほとんどのUnicesはコマンドを! $flag実行してFalse失敗し、失敗は無効になるためtrueです。 macOSでは、false否定を意味するfalseを返す外部ユーティリティを実行します。

2番目ifの声明は、

if [ ! $flag ]; then
    echo "With brackets: Flag is $flag"
fi

すべてのUnixで同じように動作します。 2つの引数とを使用してユーティリティを呼び出します[。これはユーティリティと同じですtest[最後のオペランドと一致する必要があります)。デフォルトでは、文字列引数の長さがゼロでない場合(長さがゼロでない場合)、真の値が返されますが、これはfalseを返すことによって無効化され実行されません。]!Falsetest!testecho

-nわかりやすくするために、テストを使用して空でない文字列をテストすることをお勧めします。

if [ -n "$flag" ]; then ...

または、-z空の文字列をテストします。

if [ -z "$flag" ]; then ...

変数拡張への参照は、$flagファイル名のワイルドカードパターンではなく単一の単語への拡張であるため、この特定のコード部分では重要ではありません。ただし、通常、変数の拡張は単語の区切りやファイル名のグロービングを防ぐために二重引用符で囲む必要があります。

[vs.の議論については、[[以下を参照してください。

関連:

おすすめ記事