6.4. Expressions in Conditionals#
Now that you understand operators, let’s put them to work in if statements, loops, and logic. This is where operators become the decision-makers in your scripts.
6.4.1. Real-World Script: File Processor#
Complete example combining all operators:
#!/bin/bash
# Validate input
[ -z "$1" ] && {
echo "Usage: $0 <filename>"
exit 1
}
file="$1"
# Check if file exists and is readable
[ ! -f "$file" ] && {
echo "Error: '$file' is not a file"
exit 1
}
[ ! -r "$file" ] && {
echo "Error: '$file' is not readable"
exit 1
}
# Process file
echo "Processing file: $file"
line_count=0
while IFS= read -r line; do
[ -z "$line" ] && continue # Skip empty lines
((line_count++))
# Check for errors
if [[ "$line" =~ ERROR ]]; then
echo "Line $line_count (ERROR): $line"
elif [[ "$line" =~ WARNING ]]; then
echo "Line $line_count (WARN): $line"
fi
done < "$file"
echo "Processed $line_count non-empty lines"
6.4.1.1. && and || Together: if/else Pattern#
# Run first_command if condition true, else second_command
[ condition ] && first_command || second_command
# Example: copy or warn
[ -f "$source" ] && cp "$source" "$dest" || echo "Source not found"
# Example: grant or deny
[ "$user" = "admin" ] && echo "Welcome!" || echo "Access denied"
Warning: This pattern can fail if first_command fails! Better:
# More robust:
if [ condition ]; then
first_command
else
second_command
fi
6.4.1.2. || Operator: Run if Failed#
# Run command2 only if command1 fails
command1 || command2
# Example: Create dir if it doesn't exist
[ -d "$dir" ] || mkdir -p "$dir"
# Example: Default value
user=${1:-"nobody"} # Use $1, default to "nobody"
# Common pattern: exit if check fails
[ -f "$config" ] || { echo "Config not found"; exit 1; }
6.4.1.3. && Operator: Run if Successful#
# Run command2 only if command1 succeeds
command1 && command2
# Example: Create directory and enter it
mkdir -p /tmp/mydir && cd /tmp/mydir
# Example: Run test only if file exists
[ -f config.sh ] && source config.sh
# Multiple commands
[ -w "$file" ] && echo "Backing up..." && cp "$file" "$file.bak"
6.4.2. Conditional Expressions with && and ||#
Shorthand for if/else logic:
6.4.2.1. continue: Skip to Next Iteration#
for i in {1..5}; do
if [ $i -eq 3 ]; then
echo "Skipping 3"
continue
fi
echo "Number: $i"
done
Output:
Number: 1
Number: 2
Skipping 3
Number: 4
Number: 5
Real example: skip empty lines
#!/bin/bash
while IFS= read -r line; do
[ -z "$line" ] && continue # Skip empty lines
echo "Processing: $line"
done < "input.txt"
6.4.2.2. break: Exit Loop Early#
for i in {1..10}; do
if [ $i -eq 5 ]; then
echo "Found 5, breaking"
break
fi
echo "Number: $i"
done
echo "Done"
Output:
Number: 1
Number: 2
Number: 3
Number: 4
Found 5, breaking
Done
Real example: search for file
#!/bin/bash
for file in *.log; do
if grep -q "ERROR" "$file"; then
echo "Found error in $file"
break # Stop searching after first error file found
fi
done
6.4.3. break and continue#
Control loop flow:
6.4.3.1. for Loop: C-Style#
for (( i=start; i<end; i++ )); do
echo "Iteration $i"
done
Real example: number sequence
#!/bin/bash
for (( i=1; i<=10; i++ )); do
echo "Number: $i"
done
Real example: backwards loop
#!/bin/bash
for (( i=10; i>0; i-- )); do
echo "$i seconds remaining..."
sleep 1
done
Comparison:
for var in list→ Iterate over itemsfor (( i=0; i<10; i++ ))→ C-style loop with counter
6.4.3.2. for Loop: Iterate Over List#
for var in item1 item2 item3; do
echo "Processing: $var"
done
Real example: process files
#!/bin/bash
for file in *.txt; do
echo "Found: $file"
wc -l "$file"
done
Real example: command output
#!/bin/bash
for user in $(cat /etc/passwd | cut -d: -f1); do
echo "User: $user"
done
6.4.4. for Loops#
Three ways to loop in bash:
6.4.4.1. until Loop#
Execute until condition becomes true (opposite of while):
until [ condition ]; do
# code runs until condition becomes true
done
Real example:
#!/bin/bash
# Keep trying to connect until success
until ping -c 1 8.8.8.8 &>/dev/null; do
echo "Waiting for internet..."
sleep 2
done
echo "Connected!"
Comparison:
while [ $x -lt 10 ]→ Loop while x < 10 (stop when x >= 10)until [ $x -ge 10 ]→ Loop until x >= 10 (same effect!)
6.4.4.2. while Loop#
Execute while condition is true:
while [ condition ]; do
# code runs as long as condition is true
done
Real example: countdown
#!/bin/bash
count=5
while [ $count -gt 0 ]; do
echo "$count..."
((count--))
done
echo "Blastoff!"
Real example: read until empty
#!/bin/bash
while [ -z "$input" ]; do
read -p "Enter something: " input
[ -z "$input" ] && echo "Can't be empty!"
done
echo "You entered: $input"
6.4.5. while and until Loops#
Loop while (or until) conditions are true:
6.4.5.1. if/elif/else Statement#
Test multiple conditions in sequence:
if [ condition1 ]; then
echo "condition1 was true"
elif [ condition2 ]; then
echo "condition1 was false, condition2 was true"
elif [ condition3 ]; then
echo "conditions 1 and 2 were false, condition3 is true"
else
echo "all conditions were false"
fi
Real example:
#!/bin/bash
score=$1
if [ $score -ge 90 ]; then
echo "Grade: A"
elif [ $score -ge 80 ]; then
echo "Grade: B"
elif [ $score -ge 70 ]; then
echo "Grade: C"
elif [ $score -ge 60 ]; then
echo "Grade: D"
else
echo "Grade: F"
fi
6.4.5.2. if/else Statement#
if [ condition ]; then
echo "condition was true"
else
echo "condition was false"
fi
Real example:
#!/bin/bash
password="$1"
if [ "$password" = "secret" ]; then
echo "Access granted"
else
echo "Access denied"
fi
6.4.5.3. Basic if Statement#
if [ condition ]; then
# code executes if condition is true
echo "condition was true"
fi
Real example:
#!/bin/bash
age=20
if [ $age -ge 18 ]; then
echo "You are an adult"
fi
6.4.6. if/else Statements#
The basic decision structure: