Skip to content
Logical Operators && and ||
step 1/5

Reading — step 1 of 5

Read

~2 min readExecution & Pipelines

&& and || — Exit Codes as Control Flow

Bash chains commands by their exit code, not by their stdout. A command that exits 0 is "true"; anything else is "false". && and || short-circuit on that boolean.

mkdir -p build && cd build && make    # stop on first failure
test -f cfg.yml || cp cfg.yml.example cfg.yml    # provide default
grep -q ERROR log && notify || echo "ok"         # if/else-ish

Precedence and grouping

&& and || have equal precedence and are left-associative. That means

a && b || c

is (a && b) || c, NOT a && (b || c). So if a succeeds and b fails, c runs. If you want a real if/else, use if:

if a; then b; else c; fi    # clearer than a && b || c

Exit code rules

ConstructResulting exit code
a && bIf a fails -> exit of a. Else exit of b.
a || bIf a succeeds -> exit of a (=0). Else exit of b.
; (sequence)Exit of the last command (b).
& (background)Always 0 for the surrounding shell.

Why exit codes matter

Exit codes are the Unix world's universal "did it work?" channel. They flow into:

  • $? (the last command's status)
  • set -e (script aborts on a non-zero status not consumed by &&/||)
  • CI systems (a build "fails" iff the top-level script exits non-zero)
  • Container runtimes (an exit != 0 ends the container)

&& and || are how you build a pipeline of dependent steps without writing if for every branch — and how you protect against silently ignoring the error from cd build before running make.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…