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)は! [[
非常によく定義されており、理解しやすいです。全体のプロセスを実行し[[
、結果を無効にします。
どちらを使用すべきかは個人的な好み(および理解)の問題です。