Bashからif! [[ foo ]] と if [[ ! foo]]の違いは何ですか?

Bashからif! [[ foo ]] と if [[ ! foo]]の違いは何ですか?

Bashはif条件を否定するために使用されることを知っていますが、私は!次の形式を使用するコードを見ました。

if ! [[ CONDITION ]]; then
    SOMETHING
fi

この形式と以下の形式の間に違いはありますか?

if [[ ! CONDITION ]]; then
    SOMETHING
fi

Googleに試しましたが、以前の構文についてはまだ何も見つかりませんでした。

答え1

単一条件の場合、両方とも同じです。

$ if [[ ! 1 = 1 ]]; then echo true; else echo false; fi
false
$ if ! [[ 1 = 1 ]]; then echo true; else echo false; fi
false

複数の条件をテストするときに違いがあります。

$ if  [[ ! 1 = 2 || 2 = 2 ]]; then echo true; else echo false; fi
true
$ if  ! [[ 1 = 2 || 2 = 2 ]]; then echo true; else echo false; fi
false

したがって、外部否定は結果に優先順位があります。

もちろん、条件全体に内部否定を適用することができるので、この場合の代わりに外部否定を使用することをお勧めします。

$ if  [[ ! ( 1 = 2 || 2 = 2 ) ]]; then echo true; else echo false; fi
false

答え2

if ! [[ CONDITION ]]; then

最初のものは!パイプライン構文からのものです。

   A pipeline is a sequence of one or more commands separated by one of the control
   operators | or |&.  The format for a pipeline is:

          [time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

   If the reserved word ! precedes a pipeline, the exit status of that pipeline is 
   the logical negation of the exit status as described above.

2番目の例:

if [[ ! CONDITION ]]; then

式は次のとおりです。

  [[ expression ]]
  Execute conditional command.

  ! EXPRESSION              True if EXPRESSION is false; else false

答え3

Bashのマンページから:

[[ expression ]]

条件式の評価に応じて、0または1の状態を返しますexpression

だから、

[[ condition ]]

0条件が "true" と評価された場合に返され、1それ以外の場合は!結果全体が否定されます。これは、論理的にテスト内部の全体的な条件を否定するのと同じです。

この種の否定は、テスト構成ではなく外部コマンドの結果をテストする場合に一般的です(例:

if ! grep -q "pattern" file

パターンがファイルに見つからない場合はコードが実行されるため、内部テスト構成が存在せず、[ condition ]テストコマンド[(時には外部、時には組み込み)を呼び出すテストが使用された時間/シェルで発生する可能性があります。

答え4

最初の否定はによって行われますif。 2番目はによって行われます[[。単純なケースでは違いはありません。

しかし、どちらも時々必要です。

  • if [[ ! a && b ]]この[[能力が必要です。
  • if ! ls今はifそれが必要です。

関連情報