ShBash · Lesson 3 of 8
Control Flow
Bash conditionals look strange at first. The [ ... ] is actually a command (test). The spaces inside are required. Yes, really.
Bash
#!/bin/bash
# if / elif / else
age=20
if [ "$age" -ge 18 ]; then
echo "Adult"
elif [ "$age" -ge 13 ]; then
echo "Teenager"
else
echo "Child"
fi
# Numeric comparisons (use -eq -ne -lt -le -gt -ge, NOT == < >)
x=10
if [ "$x" -eq 10 ]; then echo "equal to 10"; fi
if [ "$x" -gt 5 ]; then echo "greater than 5"; fi
if [ "$x" -lt 20 ]; then echo "less than 20"; fi
# String comparisons
name="Alice"
if [ "$name" = "Alice" ]; then echo "It's Alice!"; fi
if [ -z "$name" ]; then echo "Empty string"; fi # -z: zero length
if [ -n "$name" ]; then echo "Non-empty string"; fi # -n: non-zero length
# File tests
if [ -f "script.sh" ]; then echo "File exists"; fi
if [ -d "/tmp" ]; then echo "Directory exists"; fi
if [ -e "anything" ]; then echo "Path exists"; fi
if [ -r "file.txt" ]; then echo "Readable"; fi
if [ -x "script.sh" ]; then echo "Executable"; fi
# Combine conditions
if [ "$age" -ge 18 ] && [ "$name" = "Alice" ]; then
echo "Adult Alice"
fi
# [[ ]] is more powerful (bash-specific, but preferred)
if [[ "$name" == Ali* ]]; then # pattern matching!
echo "Name starts with Ali"
fiBash
#!/bin/bash
# for loop — over a list
for fruit in apple banana cherry; do
echo "I like $fruit"
done
# for loop — with range
for i in {1..5}; do
echo "Count: $i"
done
# for loop — C-style
for ((i=0; i<5; i++)); do
echo "i = $i"
done
# for loop — over files
for file in *.sh; do
echo "Shell script: $file"
done
# for loop — over command output
for user in $(cut -d: -f1 /etc/passwd | head -5); do
echo "User: $user"
done
# while loop
count=0
while [ "$count" -lt 5 ]; do
echo "count: $count"
((count++))
done
# read lines from a file
while IFS= read -r line; do
echo "Line: $line"
done < "data.txt"
# until loop — opposite of while
n=10
until [ "$n" -le 0 ]; do
echo "$n"
((n -= 3))
done