Bash Conditionals, Loops, and Functions

Bash if/elif/case logic, test expressions, loops, functions, return codes, and robust control-flow patterns.

View
StandardDetailedCompact
Export
Copy the compact sheet, download it, or print it.
Download
`D` dense toggle · `C` copy all

Tests and Conditionals

Use test, [, [[, and arithmetic conditions.

Test whether file exists

Check whether a regular file exists.

bashANYiffile-tests
bash
if [[ -f /etc/hosts ]]; then echo yes; fi
Notes

[[ ... ]] is generally safer and more expressive than [ ... ].

Test whether directory exists

Check whether a directory exists.

bashANYifdir-tests
bash
if [[ -d /var/log ]]; then echo yes; fi
Notes

Useful before cd, mkdir, or file operations.

Test for empty string

Check whether a string is empty.

bashANYifstrings
bash
if [[ -z "$name" ]]; then echo empty; fi
Notes

Quote variable expansions inside tests.

Compare strings

Compare string values.

bashANYifstrings
bash
if [[ "$env" == 'prod' ]]; then echo deploy; fi
Notes

[[ supports pattern matching with == as well.

Compare integers

Use arithmetic context for integer comparisons.

bashANYifarithmetic
bash
if (( count > 10 )); then echo large; fi
Notes

Cleaner than -gt for many Bash scripts.

Test command success

Use a command directly as the condition.

bashANYifcommands
bash
if grep -q needle file.txt; then echo found; fi
Notes

Shell conditions commonly use exit status rather than booleans.

Pattern matching with case

Match one variable against several patterns.

bashANYcasepatterns
bash
case "$ext" in
  jpg|png) echo image ;;
  txt) echo text ;;
  *) echo other ;;
esac
Notes

case is usually clearer than many if/elif checks.

Loops

for, while, until, and select loops.

For loop over words

Iterate over a list or glob.

bashANYforloops
bash
for f in *.log; do echo "$f"; done
Notes

Pair with nullglob when patterns may not match.

C-style arithmetic for loop

Use arithmetic syntax in Bash for loops.

bashANYforarithmetic
bash
for ((i=0; i<5; i++)); do echo "$i"; done
Notes

Helpful for counters and indexed arrays.

While read loop

Read input line by line safely.

bashANYwhileread
bash
while IFS= read -r line; do printf '%s
' "$line"; done < file.txt
Notes

Common in parsing and scripting.

Until loop

Run loop until command succeeds.

bashANYuntilretry
bash
until curl -sf http://localhost:8080/health; do sleep 1; done
Notes

Good for readiness checks in scripts.

Use break and continue

Skip or exit loop iterations.

bashANYbreakcontinueloops
bash
for n in {1..5}; do [[ $n -eq 3 ]] && continue; echo "$n"; done
Notes

Fundamental control-flow building blocks.

Simple select menu

Create a numbered shell menu.

bashANYselectinteractive
bash
select choice in start stop status quit; do echo "$choice"; break; done
Notes

Useful for interactive admin helpers.

Functions

Define reusable Bash functions and control return behavior.

Define a function

Define a shell function.

bashANYfunctionsdefinition
bash
greet() { echo "Hello, $1"; }
Notes

Bash supports both name() { ... } and function name { ... } forms.

Call a function

Invoke a shell function with arguments.

bashANYfunctionscall
bash
greet Jonathan
Notes

Function arguments are available as positional parameters inside the function.

Use local variable in function

Keep function internals from leaking into caller scope.

bashANYfunctionslocal
bash
work() { local dir=${1:-/tmp}; cd "$dir" || return 1; pwd; }
Notes

local is a Bash builtin, not POSIX sh.

Return status from function

Return a status code from a function.

bashANYfunctionsreturn
bash
validate() { [[ -n "$1" ]] || return 1; }
Notes

return is for status codes, not arbitrary values.

Return data via stdout

Emit data to stdout and capture it with command substitution.

bashANYfunctionsstdoutsubstitution
bash
slugify() { tr '[:upper:] ' '[:lower:]-' <<< "$1"; }
slug=$(slugify 'Hello World')
Notes

This is the most common shell pattern for function 'return values'.

Trace shell functions

Trace function execution during debugging.

bashANYfunctionsdebug
bash
set -x
my_func() { echo ok; }
my_func
set +x
Notes

Useful when debugging control flow and variable expansion.

Script Safety

Safer Bash defaults for production scripts.

Enable stricter script mode

Exit on errors, unset variables, and pipeline failures.

bashANYstrict-modeset
bash
set -euo pipefail
Notes

Popular baseline for defensive scripting, though you should still understand edge cases.

Set safer IFS

Restrict word splitting to newline and tab.

bashANYifsstrict-mode
bash
IFS=$'
\t'
Notes

Sometimes used with strict scripts to reduce splitting surprises.

Run cleanup on exit

Register cleanup logic for normal exit.

bashANYtrapcleanup
bash
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
Notes

Very common when using temp files or temp dirs.

Print error location

Add basic error diagnostics to a script.

bashANYtraperrdebug
bash
trap 'echo "error on line $LINENO"' ERR
Notes

Helpful when paired with set -e.

Shellcheck directive example

Document intentional exceptions for static analysis.

bashANYshellchecklint
bash
# shellcheck disable=SC2086
echo $unquoted
Notes

Useful when you use ShellCheck in CI.