最初の選択

最初の選択

bashに違いがありますか、それともステートメントの否定に対して好ましい使用法がありますか?

if ! [[ -z "${var}" ]]; then
  do_something
fi

比較的

if [[ ! -z "${var}" ]]; then
  do_something
fi

答え1

! [[ expression ]]

テスト全体がfalseを返す場合はtrue

[[ ! expression ]]

単一の式が false を返す場合、値は true です。


テストは複合式である可能性があるため、これは非常に異なる場合があります。たとえば、

$ [[ ! 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
yes
$ ! [[ 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
no

個人的には、該当する場合はテスト構成内で否定を使用することを好みますが、意図に応じて外部でも完全に問題ありません。

答え2

A! cmdは実際に管路!終了コードを無効にします。みんな管路。

メンズバッシュから:

パイプラインパイプラインは、制御演算子で区切られた1つ以上のコマンドシーケンスです。または|&。パイプの形式は次のとおりです。

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

...
予約語の場合!パイプの前のパイプの終了状態は、上記の終了状態に対する論理的な否定です。シェルは、値を返す前にパイプライン内のすべてのコマンドが終了するのを待ちます。

この意味では、aは次のようになります。

! [[ 2 -eq 2 ]]

!完全な終了コードを否定することです[[(すべて実行された後)。したがって、終了コードは0です。

!  [[ 2 -eq 2 && 3 -eq 4 ]]

しかし、

A[[ ! ]]複合コマンド(パイプではない)。メンズバッシュから:

複合コマンド
...
[[expression]] は、
条件式式の評価に基づいて 0 または 1 の状態を返します。
式は、以下の条件式で説明する主な要素で構成されています。

したがって、終了コードは1です。

[[ ! 2 -eq 2 && 3 -eq 4 ]]

これは実際には次のとおりです。

[[ ( ! 2 -eq 2 ) && ( 3 -eq 4 ) ]]

段落評価では、右側は評価されず、&&これははるかに短い式と実質的に同じです。

[[ ! 2 -eq 2 ]]

これは常に間違っています(1)。

一言で言えば:内部[[、!影響部分表現。

最初の選択

!内部を使用する方が[[一般的ですが(より多くのシェルに移植可能です)、[否定の範囲が賢明な使用によって明示的に制御されていない場合は、時々混乱する可能性があります(構文内で問題になる可能性があります)。()[

ただし、結果(bash、ksh、zsh)は! [[非常によく定義されており、理解しやすいです。全体のプロセスを実行し[[、結果を無効にします。

どちらを使用すべきかは個人的な好み(および理解)の問題です。

関連情報