The basic test
[ $wtf ]
tests whether the string in the middle is empty or not.
Since $wtf is 'false', the test returns true (because 'false' is not the same as '') - and hence you get WTF1 as the response.
Try with:
wtf=''
As pointed out by Gordon Davisson (and Dennis Williamson), it is a good idea to be careful with strings that you are testing. Indeed, I should have stated that I would always use [ -n "$wtf" ]
or [ -z "$wtf" ]
to test whether a variable is set, because that was necessary when I was learning shell, once upon a quarter century ago. I've had counter stories from Bash afficionados that you don't have to worry about it in bash - however, I think the code here provides a counter-example that in fact you do still have to worry about it.
So, some best practices:
- Enclose tested variables in double quotes, or
- (In Bash), use
[[ $wtf ]]
which does know how to handle the variable expansion.
- Use the
-n
or -z
tests to test for non-empty or empty values.
There can be exceptions to the rules - but you will not go far wrong following them.
Consider the code:
wtf="1 -eq 0"
[ $wtf ] && echo "WTF0"
[[ $wtf ]] && echo "WTF1"
wtf="false"
[ $wtf ] && echo "WTF2"
[[ $wtf ]] && echo "WTF3"
wtf=""
[ $wtf ] && echo "WTF4"
[[ $wtf ]] && echo "WTF5"
wtf="false"
[ "$wtf" ] && echo "WTF6"
[[ "$wtf" ]] && echo "WTF7"
wtf=""
[ "$wtf" ] && echo "WTF8"
[[ "$wtf" ]] && echo "WTF9"
That produces:
WTF1
WTF2
WTF3
WTF6
WTF7
with both bash and ksh (as found on MacOS X 10.6.4, when run with 'bash testcode.sh' or 'ksh testcode.sh'). A real Bourne shell (if you can still find such a thing) would object to the double-bracket operations - it would not be able to find the command '[[
' on $PATH
.
You can extend the testing to cover more cases ad nauseam.