Nested and Compound Conditionals
In this page:
Combining Conditions in One [[ ]]
Multiple conditions can be combined directly inside a single [[ ]] test using && and ||, avoiding the need for nested if blocks when the checks are independent. This keeps related logic visually grouped together.
Example: Combining Conditions in One [[ ]]
#!/bin/bash
age=25
has_ticket=true
if [[ $age -ge 18 && $has_ticket = true ]]; then
echo "Entry granted"
else
echo "Entry denied"
fi
Login to try C/C++/Java/PHP code in the editor
Grouping with Parentheses
Inside [[ ]], parentheses ( ) can group sub-expressions to control evaluation order explicitly, similar to math expressions. Without grouping, mixing && and || can be evaluated in an order you didn't intend.
Example: Grouping with Parentheses
#!/bin/bash
role="editor"
is_owner=false
if [[ ($role = "admin" || $role = "editor") && $is_owner = false ]]; then
echo "Limited edit access granted"
fi
Login to try C/C++/Java/PHP code in the editor
When Nesting if Is Clearer
Sometimes a later condition only makes sense to evaluate after an earlier one already passed, especially when the second check would error out or be meaningless otherwise (like checking a file's contents only after confirming the file exists). In these cases, nested if blocks are clearer than cramming everything into one compound expression.
Example: When Nesting if Is Clearer
#!/bin/bash
file="data.txt"
echo "sample" > "$file"
if [ -f "$file" ]; then
if [ -s "$file" ]; then
echo "$file exists and is non-empty"
else
echo "$file exists but is empty"
fi
else
echo "$file does not exist"
fi
Login to try C/C++/Java/PHP code in the editor
Flattening Deep Nesting with Guard Clauses
Instead of nesting many if blocks, checking for the failure cases first and exiting/continuing early (a 'guard clause') often produces flatter, more readable code. Each guard handles one specific unwanted condition before the main logic runs.
Example: Flattening Deep Nesting with Guard Clauses
#!/bin/bash
check_input() {
local value="$1"
if [ -z "$value" ]; then
echo "Rejected: empty value"
return 1
fi
if [ "$value" -lt 0 ] 2>/dev/null; then
echo "Rejected: negative value"
return 1
fi
echo "Accepted: $value"
}
check_input ""
check_input "-5"
check_input "42"
Login to try C/C++/Java/PHP code in the editor
- Over-nesting
ifblocks many levels deep when a single compound condition with&&/||inside[[ ]]would be far more readable. - Forgetting operator precedence when mixing
&&and||without parentheses;[[ ]]respects grouping with( )inside the double brackets, and skipping it can silently change which conditions are actually being checked together. - Using
[ ]for compound conditions with-a/-o; these are deprecated and behave unreliably with complex expressions --[[ ]]with&&/||is the modern, safer choice.
- Conditions can be combined in one
[[ ]]using&&(and),||(or), and grouped with( )for explicit precedence. - Nested
ifblocks are appropriate when later checks only make sense/are only safe after earlier ones already passed. [[ ]]supports parentheses for grouping sub-expressions;[ ]does not support this reliably, which is one more reason to prefer[[ ]]for compound logic.- Deeply nested conditionals usually indicate the logic can be flattened using compound
&&/||expressions or earlyreturn/continueguards.
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first: