Chcete-li stavět na chepnerově bystrém komentáři k otázce:
-
V
[ ! condition ],!je pouze argument na[vestavěný (účinný aliastestvestavěný); stane se, že[/testinterpretuje argument!jako negace. -
V
! [ condition ],!je klíčové slovo shellu který neguje jakýkoli příkaz, který následuje (což je shodou okolností[v tomto případě).
Jedna věc je ! [ condition ] syntaxe vám implicitně dává, že negace se vztahuje na cokoli [ condition ] vyhodnotí jako jako celek , takže pokud je to záměr, nemusíte si dělat starosti s prioritou operátorů.
Výkon , kterou zvolenou syntaxi pravděpodobně příliš nemění; rychlé testy naznačují:
-
Pokud
conditionje v obou případech doslova stejný a předává!jako argument k[je zanedbatelně rychlejší. -
Pokud
!se používá jako klíčové slovo , a proto můžete podmínku zjednodušit tím, že se nebudete starat o prioritu, může být o něco rychlejší (např.! [ 0 -o 1 ]vs.[ ! \( 0 -o 1 \) ]; všimněte si, že specifikace POSIX. odrazuje od používání-aa-okvůli nejednoznačnosti).
To znamená, pokud mluvíme o Bash , pak byste měli zvážit použití [[ místo [ , protože [[ je klíčové slovo shellu který analyzuje uzavřený výraz ve speciálním kontextu, který:
- nabízí více funkcí
- umožňuje bezpečně kombinovat výrazy s
&&a|| - přichází s méně překvapeními
- je také o něco rychlejší (ačkoli na tom v praxi bude záležet jen zřídka)
Viz tato moje odpověď.
! neguje ukončovací kód následujícího příkazu:
$ ! test 1 = 1 || echo $? # negate command with true expression
1
Jak je uvedeno v manuálové stránce, test (a podobné [ builtin) exit se stavem určeným následujícím výrazem :
$ test ! 1 = 1 || echo $? # return false expression
1
$ [ ! 1 = 1 ] || echo $?
1
Pro daný výraz :
- na jedné straně negujete
testpříkaz, který ukončí se stavem true expression. - na druhé straně negujete výraz a
testpříkaz (nebo[) ukončete s falešným stavem
Obojí bude mít stejný účinek.
Řekl bych tedy, že tyto syntaxe jsou ekvivalentní. S výhodou pro externí ! povolit negaci složených testů:
$ ! [ 1 = 1 -a 2 = 2 ] || echo $?
1