Pattern: Possibly malformed boolean statement
Issue: -
This is not a bash issue, but a simple, common logical mistake applicable to all languages.
[ "$1" != foo ] || [ "$1" != bar ]
is always true (when foo != bar
):
- If
$1 = foo
then$1 != bar
is true, so the statement is true. - If
$1 = bar
then$1 != foo
is true, so the statement is true. - If
$1 = cow
then$1 != foo
is true, so the statement is true.
[ $1 != foo ] && [ $1 != bar ]
matches when $1
is neither foo
nor bar
:
- If
$1 = foo
, then$1 != foo
is false, so the statement is false. - If
$1 = bar
, then$1 != bar
is false, so the statement is false. - If
$1 = cow
, then both$1 != foo
and$1 != bar
is true, so the statement is true.
This statement is identical to ! [ "$1" = foo ] || [ "$1" = bar ]
, which also works correctly (by De Morgan's law).
Example of incorrect code:
if [ "$1" != foo ] || [ "$1" != bar ]
then
echo "$1 is not foo or bar"
fi
Example of correct code:
if [ "$1" != foo ] && [ "$1" != bar ]
then
echo "$1 is not foo or bar"
fi