Skip to content
koalaman edited this page Sep 24, 2016 · 4 revisions

You probably wanted && here

Problematic code:

if [[ $1 != foo || $1 != bar ]]
then
  echo "$1 is not foo or bar"
fi

Correct code:

if [[ $1 != foo && $1 != bar ]]
then
  echo "$1 is not foo or bar"
fi

Rationale:

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.

Exceptions

Rare.

Clone this wiki locally