The words "true" and "false" are special words (builtins) for bash.
If used in an if
test, they act as intuitively expected:
$ if true; then echo "true"; else echo "false"; fi
true
$ if false; then echo "true"; else echo "false"; fi
false
However, this two tests:
$ [[ true ]] && echo "true" || echo "false"
true
$ [[ false ]] && echo "true" || echo "false"
true
Both result in true. Why?
This is because in your first example,
true
is a builtin command.In your second exmaple, however, the
true
inside[[ true ]]
is not interpreted as a command, but just treated as a string-like token, and it returns true if string is not empty.The second example could be written like this for fix:
[[ … ]]
is, in this case, equivalent totest
, i.e.test true
andtest false
. Looking at the manual for test(1):true
andfalse
are both non-empty strings.When we use test or its equivalent
[
we, sometimes, get strange results. Lets try to understand why that happens.We can make simple tests manually:
Or
And be intermediately shocked that both the above tests are reported as true. Is test telling us that 0 is equal to 1 ?
To answer this question we could create a testing function and run all the tests that appear in this page.
A page which also aims to explain all the details with "test". With the aid of the testing function, we could run an script similar to the next one. It prints both the result of the test and the exit value of the function 'test':
The results:
From all the tests above, it becomes clear the rule for unary test:
Well, that is the whole true for any "unary" test. i.e. Tests perform on values that could NOT be split with spaces. Tests that are binary
[ -n $var ]
or ternary[ 1 -eq "$one" ]
result in a true value if the conditions (-n
or-eq
) are valid.Amazingly, this (more complex) binary or ternary tests are more intuitive to understand. There exist a huge list of longer tests, but I feel that those fall outside the scope of this short question.
It is sometimes called pedantic to ask if a var is NOT zero length with the condition
-n
as exactly the same test happens without any explicit condition.However, it is often clearer to the reader what is the goal of the programer when the condition
-n
is explicitly used.The condition
-z
tests for "zero length".With this tests:
We get:
Any missing aspect of test? Thanks.