I understand that !
is used to negate an if condition in Bash, but I've just seen code which takes the format:
if ! [[ CONDITION ]]; then
SOMETHING
fi
Is there a difference between this format and the below?
if [[ ! CONDITION ]]; then
SOMETHING
fi
I've tried to Google but haven't found anything yet about the former syntax.
答案1
for single condition they are both same:
$ if [[ ! 1 = 1 ]]; then echo true; else echo false; fi
false
$ if ! [[ 1 = 1 ]]; then echo true; else echo false; fi
false
the difference come when testing multiple conditions:
$ 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
so outer negation has more priority on the result.
of course you can apply inner negation for whole condition, so in this case you will prefer to use a outer negation instead:
$ if [[ ! ( 1 = 2 || 2 = 2 ) ]]; then echo true; else echo false; fi
false
答案2
if ! [[ CONDITION ]]; then
The first !
is from the pipeline syntax:
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.
Your second example:
if [[ ! CONDITION ]]; then
is an expression:
[[ expression ]]
Execute conditional command.
! EXPRESSION True if EXPRESSION is false; else false
答案3
From the bash manpage:
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the conditional expression
expression
.
So,
[[ condition ]]
returns 0
when the condition evaluates to "true", and 1
otherwise. The !
negates the overall result. This is logically the same as negating the overall condition inside the test.
This kind of negation is more usual when testing for the result of an external command rather than the test constructs (e.g.
if ! grep -q "pattern" file
would execute the code if the pattern is not found in the file) and thus may come from times/shells where no internal test construct existed and the [ condition ]
test, which calls the test command [
(sometimes external, sometimes builtin), was used.
答案4
In the first the negation is done by the if
. It the 2nd it is done by the [[
. In the simple case this makes no difference.
However both are sometimes needed e.g.
if [[ ! a && b ]]
the[[
needs this ability.if ! ls
now theif
needs it.