x && y
executes x
, then only executes y
if x
succeeds (i.e., has an exit status of 0)
x || y
executes x
, then only executes y
if x
fails (i.e., has a non-zero exit status)
The output of x
is irrelevant.
One place they do not differ is in precedence. Unlike Boolean operators in other languages, &&
and ||
have equal precedence, so something like
a || b && c
is parsed and evaluated the same as
{ a || b; } && c
rather than
a || { b && c; }