|

Linux CLI 59 ๐Ÿง shell scripts flow control and if

59 – shell functions flow control and if

#!/bin/bash

# Get a number from user input
read -p "Enter a number: " num

if [ $num -lt 0 ]; then
    echo "The number is negative."
elif [ $num -eq 0 ]; then
    echo "The number is zero."
else
    echo "The number is positive."
fi

num1=10
num2=5

sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))
remainder=$((num1 % num2))

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"
echo "Remainder: $remainder"

num1=10
num2=5

if [ $num1 -gt 0 ] && [ $num2 -gt 0 ]; then
  echo "Both numbers are positive."
else
  echo "At least one number is not positive."
fi

string1=""

if [ -z "$string1" ]; then
    echo "String is empty."
else
    echo "String is not empty."
fi

Flow control is what turns a script from a straight line of commands into a program that makes decisions. The if statement is the most important of these โ€” it lets you run different code depending on whether a condition is true or false. Combined with operators for comparing numbers, strings, and logic, you can build scripts that respond to their environment.

Key point: In shell scripting, if tests the exit status of a command โ€” 0 means true, anything else means false. The [ ... ] (or [[ ... ]]) syntax is actually a command that returns 0 or 1 based on the condition inside.


a – flow control in shell scripts

Flow control is an essential aspect that allows you to manage the execution of commands based on certain conditions or loops. It helps in structuring the script to perform different tasks under varying circumstances.

Shell scripting supports several flow control constructs:

ConstructPurpose
ifRun code if a condition is true
if / elseTwo-way branch
if / elif / elseMulti-way branch
caseMatch against multiple patterns
forLoop over a list
whileLoop while a condition is true
untilLoop until a condition is true
breakExit a loop early
continueSkip to the next iteration

Key flow control constructs:

  • if, if-else, and elif (else-if) โ€” decide which block to run
  • Loops โ€” for, while, and until โ€” repeat a block

This chapter focuses on if and its variants. Loops come next.

Why flow control matters:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Without flow control               โ”‚
โ”‚                                              โ”‚
โ”‚  cmd1                                        โ”‚
โ”‚  cmd2                                        โ”‚
โ”‚  cmd3                                        โ”‚
โ”‚  cmd4                                        โ”‚
โ”‚                                              โ”‚
โ”‚  Always runs in the same order.              โ”‚
โ”‚  Can't respond to anything.                  โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           With flow control                  โ”‚
โ”‚                                              โ”‚
โ”‚  cmd1                                        โ”‚
โ”‚  if condition; then                          โ”‚
โ”‚      cmd2       โ† only if true               โ”‚
โ”‚  else                                        โ”‚
โ”‚      cmd3       โ† only if false              โ”‚
โ”‚  fi                                          โ”‚
โ”‚  cmd4                                        โ”‚
โ”‚                                              โ”‚
โ”‚  Decides what to do based on the situation.  โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

b – if, else and elif in shell scripts

if statements are fundamental components for controlling the flow of execution in shell scripts. They allow parts of your script to run only if certain conditions are met, making your scripts more dynamic and responsive.

Basic syntax:

if [ condition ]; then
    # Commands to run if condition is true
elif [ condition ]; then
    # Commands to run if the first was false and this is true
else
    # Commands to run if all conditions are false
fi

How if works:

if runs a command and checks its exit status:

  • 0 โ†’ true โ†’ run the then block
  • non-zero โ†’ false โ†’ check elif, then else

Example โ€” classify a number:

#!/bin/bash

read -p "Enter a number: " num

if [ $num -lt 0 ]; then
    echo "The number is negative."
elif [ $num -eq 0 ]; then
    echo "The number is zero."
else
    echo "The number is positive."
fi
InputOutput
-5The number is negative.
0The number is zero.
42The number is positive.

Breaking it down:

  • read -p "Enter a number: " num โ†’ prompts the user to enter a number
  • if [ $num -lt 0 ]; then โ†’ checks if num is less than 0
  • elif [ $num -eq 0 ]; then โ†’ checks if num is equal to 0
  • else โ†’ if all previous conditions were false, run this block

Simple if (no else):

if [ -f /etc/passwd ]; then
    echo "File exists"
fi

if / else (two branches):

if [ -f /etc/passwd ]; then
    echo "File exists"
else
    echo "File not found"
fi

if / elif / else (multiple branches):

if [ $grade -ge 90 ]; then
    echo "A"
elif [ $grade -ge 80 ]; then
    echo "B"
elif [ $grade -ge 70 ]; then
    echo "C"
elif [ $grade -ge 60 ]; then
    echo "D"
else
    echo "F"
fi

Nested if:

if [ -f "$file" ]; then
    if [ -r "$file" ]; then
        echo "File exists and is readable"
    else
        echo "File exists but is not readable"
    fi
else
    echo "File not found"
fi

[ ] vs [[ ]]:

Feature[ ] (POSIX)[[ ]] (bash)
Word splittingYesNo
GlobbingYesNo
&& / || insideNoYes
Regex =~NoYes
Pattern matchingNoYes
PortabilityAll shellsBash, ksh, zsh
# [ ] requires quoting
if [ "$name" = "Alice" ]; then ...; fi

# [[ ]] doesn't
if [[ $name == "Alice" ]]; then ...; fi

# [[ ]] supports &&
if [[ $a -gt 0 && $b -gt 0 ]]; then ...; fi

# [[ ]] supports regex
if [[ $email =~ @.*\.com$ ]]; then ...; fi

# [[ ]] supports glob patterns
if [[ $file == *.txt ]]; then ...; fi

Use [[ ]] when:

  • You’re writing bash-specific scripts
  • You want to avoid quoting
  • You need &&/|| inside the test
  • You need regex or glob matching

Use [ ] when:

  • You need POSIX portability
  • You’re writing for sh or dash

The test command:

[ ... ] is actually a command โ€” test. These are equivalent:

if [ -f file ]; then ...; fi
if test -f file; then ...; fi

Common file test operators:

OperatorTrue if
-e FILEFile exists
-f FILERegular file
-d FILEDirectory
-r FILEReadable
-w FILEWritable
-x FILEExecutable
-s FILENon-empty
-L FILESymlink
if [ -d /home/kronos ]; then
    echo "Directory exists"
fi

if [ -x /usr/bin/ls ]; then
    echo "ls is executable"
fi

case โ€” the multi-way alternative:

When you have many branches based on the same value, case is cleaner than a chain of elif:

case "$1" in
    start)   echo "Starting..." ;;
    stop)    echo "Stopping..." ;;
    restart) echo "Restarting..." ;;
    *)       echo "Usage: $0 {start|stop|restart}" ;;
esac

c – operators in shell scripts

Operators in shell scripts are essential for performing comparisons, logical operations, and arithmetic calculations.

Types of operators:

  1. Arithmetic operators
  2. Comparison (relational) operators
  3. Logical operators
  4. String operators

Arithmetic operators:

OperatorMeaning
+Addition
-Subtraction
*Multiplication
/Division
%Modulo (remainder)
**Exponentiation (bash)

Arithmetic in $((...)):

num1=10
num2=5

sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))
remainder=$((num1 % num2))

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"
echo "Remainder: $remainder"
[ Sum: 15 ]
[ Difference: 5 ]
[ Product: 50 ]
[ Quotient: 2 ]
[ Remainder: 0 ]

Note: Bash arithmetic is integer only. 10 / 3 gives 3, not 3.333. For floating point, use bc or awk.

$ echo "scale=2; 10 / 3" | bc
[ 3.33 ]

$ awk 'BEGIN {print 10 / 3}'
[ 3.33333 ]

Increment and decrement:

$ i=5
$ ((i++))
$ echo $i
[ 6 ]

$ ((i--))
$ echo $i
[ 5 ]

$ ((i += 10))
$ echo $i
[ 15 ]

Comparison (relational) operators:

For numbers, use the alphabetic forms:

OperatorMeaning
-eqEqual to
-neNot equal to
-gtGreater than
-geGreater than or equal to
-ltLess than
-leLess than or equal to
if [ $num -gt 0 ]; then
    echo "Positive"
fi

if [ $a -eq $b ]; then
    echo "Equal"
fi

if [ $age -ge 18 ]; then
    echo "Adult"
fi

For strings, use symbols:

OperatorMeaning
=Equal to
!=Not equal to
<Less than (ASCII)
>Greater than (ASCII)
if [ "$name" = "Alice" ]; then
    echo "Hello, Alice"
fi

if [ "$a" != "$b" ]; then
    echo "Different"
fi

โš ๏ธ Warning: > and < inside [ ] need escaping (\>) or use [[ ]] โ€” otherwise the shell treats them as redirection!

# โŒ Wrong โ€” creates a file called "file"
if [ "$a" > "$b" ]; then ...; fi

# โœ… Correct
if [ "$a" \> "$b" ]; then ...; fi
if [[ "$a" > "$b" ]]; then ...; fi

Logical operators:

OperatorMeaning
&&Logical AND
||Logical OR
!Logical NOT
num1=10
num2=5

if [ $num1 -gt 0 ] && [ $num2 -gt 0 ]; then
    echo "Both numbers are positive."
else
    echo "At least one number is not positive."
fi
if [ $age -lt 18 ] || [ $age -gt 65 ]; then
    echo "Discounted ticket"
fi

if ! [ -f "$file" ]; then
    echo "File not found"
fi

With [[ ]], combine inside:

if [[ $a -gt 0 && $b -gt 0 ]]; then
    echo "Both positive"
fi

if [[ $name == "Alice" || $name == "Bob" ]]; then
    echo "Known user"
fi

String operators:

OperatorMeaning
=Equal to
!=Not equal to
-zNull string (length zero)
-nNon-null string
<Less than in ASCII order
>Greater than in ASCII order
string1=""

if [ -z "$string1" ]; then
    echo "String is empty."
else
    echo "String is not empty."
fi
[ String is empty. ]

string2="hello"

if [ -n "$string2" ]; then
    echo "String has content."
fi
[ String has content. ]

Always quote strings in [ ]:

# โŒ Wrong โ€” if $name is empty, this becomes [ = "Alice" ] โ†’ error
if [ $name = "Alice" ]; then ...; fi

# โœ… Correct
if [ "$name" = "Alice" ]; then ...; fi

Operator summary table:

CategoryOperatorUse
Arithmetic+ - * / %Inside $((...))
Numeric compare-eq -ne -gt -ge -lt -leInside [ ]
String compare= != < >Inside [ ] or [[ ]]
String test-z -nInside [ ]
File test-e -f -d -r -w -x -s -LInside [ ]
Logical&& || !Between [ ] blocks or inside [[ ]]

A complete example โ€” classify a number and a string:

#!/bin/bash

read -p "Enter a number: " num

if [ "$num" -lt 0 ]; then
    echo "The number is negative."
elif [ "$num" -eq 0 ]; then
    echo "The number is zero."
else
    echo "The number is positive."
fi

num1=10
num2=5

sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))
remainder=$((num1 % num2))

echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"
echo "Remainder: $remainder"

if [ $num1 -gt 0 ] && [ $num2 -gt 0 ]; then
    echo "Both numbers are positive."
else
    echo "At least one number is not positive."
fi

string1=""

if [ -z "$string1" ]; then
    echo "String is empty."
else
    echo "String is not empty."
fi
$ ./script.sh
Enter a number: -3
[ The number is negative. ]
[ Sum: 15 ]
[ Difference: 5 ]
[ Product: 50 ]
[ Quotient: 2 ]
[ Remainder: 0 ]
[ Both numbers are positive. ]
[ String is empty. ]

Complete Example Session

# ============================================
# PART 1: BASIC IF
# ============================================

$ num=5
$ if [ $num -gt 0 ]; then
>     echo "Positive"
> fi
[ Positive ]

# ============================================
# PART 2: IF / ELSE
# ============================================

$ num=-3
$ if [ $num -gt 0 ]; then
>     echo "Positive"
> else
>     echo "Not positive"
> fi
[ Not positive ]

# ============================================
# PART 3: IF / ELIF / ELSE
# ============================================

$ num=0
$ if [ $num -lt 0 ]; then
>     echo "Negative"
> elif [ $num -eq 0 ]; then
>     echo "Zero"
> else
>     echo "Positive"
> fi
[ Zero ]

# ============================================
# PART 4: ARITHMETIC
# ============================================

$ num1=10
$ num2=5
$ echo $((num1 + num2))
[ 15 ]
$ echo $((num1 - num2))
[ 5 ]
$ echo $((num1 * num2))
[ 50 ]
$ echo $((num1 / num2))
[ 2 ]
$ echo $((num1 % num2))
[ 0 ]

# ============================================
# PART 5: INCREMENT / DECREMENT
# ============================================

$ i=5
$ ((i++))
$ echo $i
[ 6 ]
$ ((i--))
$ echo $i
[ 5 ]
$ ((i += 10))
$ echo $i
[ 15 ]

# ============================================
# PART 6: LOGICAL OPERATORS
# ============================================

$ a=10
$ b=5
$ if [ $a -gt 0 ] && [ $b -gt 0 ]; then
>     echo "Both positive"
> fi
[ Both positive ]

$ if [ $a -gt 0 ] || [ $b -gt 100 ]; then
>     echo "At least one true"
> fi
[ At least one true ]

$ if ! [ -f /nonexistent ]; then
>     echo "File not found"
> fi
[ File not found ]

# ============================================
# PART 7: STRING COMPARISON
# ============================================

$ name="Alice"
$ if [ "$name" = "Alice" ]; then
>     echo "Hello, Alice"
> fi
[ Hello, Alice ]

$ if [ "$name" != "Bob" ]; then
>     echo "Not Bob"
> fi
[ Not Bob ]

# ============================================
# PART 8: STRING EMPTY / NON-EMPTY
# ============================================

$ s=""
$ if [ -z "$s" ]; then
>     echo "Empty"
> fi
[ Empty ]

$ s="hello"
$ if [ -n "$s" ]; then
>     echo "Not empty"
> fi
[ Not empty ]

# ============================================
# PART 9: FILE TESTS
# ============================================

$ if [ -f /etc/passwd ]; then
>     echo "File exists"
> fi
[ File exists ]

$ if [ -d /home ]; then
>     echo "Directory exists"
> fi
[ Directory exists ]

$ if [ -x /usr/bin/ls ]; then
>     echo "Executable"
> fi
[ Executable ]

# ============================================
# PART 10: NESTED IF
# ============================================

$ file=/etc/passwd
$ if [ -f "$file" ]; then
>     if [ -r "$file" ]; then
>         echo "Readable"
>     fi
> fi
[ Readable ]

# ============================================
# PART 11: [[ ]] INSTEAD OF [ ]
# ============================================

$ name="Alice"
$ if [[ $name == "Alice" ]]; then
>     echo "Match"
> fi
[ Match ]

$ if [[ $name == A* ]]; then
>     echo "Starts with A"
> fi
[ Starts with A ]

$ email="user@example.com"
$ if [[ $email =~ @.*\.com$ ]]; then
>     echo "Valid email"
> fi
[ Valid email ]

# ============================================
# PART 12: COMBINING CONDITIONS IN [[ ]]
# ============================================

$ a=10
$ b=5
$ if [[ $a -gt 0 && $b -gt 0 ]]; then
>     echo "Both positive"
> fi
[ Both positive ]

# ============================================
# PART 13: CASE STATEMENT
# ============================================

$ action="start"
$ case "$action" in
>     start)   echo "Starting..." ;;
>     stop)    echo "Stopping..." ;;
>     restart) echo "Restarting..." ;;
>     *)       echo "Unknown" ;;
> esac
[ Starting... ]

# ============================================
# PART 14: CLASSIFY A NUMBER
# ============================================

$ cat > classify.sh << 'EOF'
#!/bin/bash
read -p "Enter a number: " num
if [ "$num" -lt 0 ]; then
    echo "Negative"
elif [ "$num" -eq 0 ]; then
    echo "Zero"
else
    echo "Positive"
fi
EOF
$ chmod +x classify.sh
$ ./classify.sh
Enter a number: -3
[ Negative ]
$ ./classify.sh
Enter a number: 0
[ Zero ]
$ ./classify.sh
Enter a number: 42
[ Positive ]

# ============================================
# PART 15: GRADE CALCULATOR
# ============================================

$ cat > grade.sh << 'EOF'
#!/bin/bash
read -p "Enter grade: " g
if [ "$g" -ge 90 ]; then
    echo "A"
elif [ "$g" -ge 80 ]; then
    echo "B"
elif [ "$g" -ge 70 ]; then
    echo "C"
elif [ "$g" -ge 60 ]; then
    echo "D"
else
    echo "F"
fi
EOF
$ chmod +x grade.sh
$ ./grade.sh
Enter grade: 85
[ B ]

Quick Reference

if Syntax

FormExample
Simpleif [ cond ]; then ...; fi
If/elseif [ cond ]; then ...; else ...; fi
If/elif/elseif [ c1 ]; then ...; elif [ c2 ]; then ...; else ...; fi
One-linerif [ cond ]; then cmd; fi
Negatedif ! cmd; then ...; fi

Arithmetic Operators

OperatorMeaning
+Addition
-Subtraction
*Multiplication
/Division
%Modulo
**Exponentiation

Numeric Comparison

OperatorMeaning
-eqEqual
-neNot equal
-gtGreater than
-geGreater or equal
-ltLess than
-leLess or equal

String Comparison

OperatorMeaning
=Equal
!=Not equal
-zEmpty
-nNon-empty
<Less (ASCII)
>Greater (ASCII)

File Tests

OperatorTrue if
-eExists
-fRegular file
-dDirectory
-rReadable
-wWritable
-xExecutable
-sNon-empty
-LSymlink

Logical Operators

OperatorMeaning
&&AND
||OR
!NOT

[ ] vs [[ ]]

Feature[ ][[ ]]
PortabilityPOSIXBash
Quote neededYesNo
&&/|| insideNoYes
Regex =~NoYes
Glob matchNoYes

case Syntax

PatternMeaning
value)Exact match
v1|v2)Multiple values
pat*)Glob pattern
*)Default

Best Practices

โœ… Do This:

# Quote variables in [ ]
if [ "$name" = "Alice" ]; then ...; fi    # โœ…

# Use [[ ]] in bash
if [[ $name == "Alice" ]]; then ...; fi   # โœ…

# Use numeric operators for numbers
if [ "$a" -gt "$b" ]; then ...; fi        # โœ…

# Test in order โ€” most specific first
if [ "$x" -gt 100 ]; then ...             # โœ…
elif [ "$x" -gt 10 ]; then ...
else ...

# Use case for multiple exact matches
case "$1" in
    start) ... ;;
    stop)  ... ;;
esac                                      # โœ…

# Use ! for negation
if ! command; then echo "failed"; fi      # โœ…

# Combine with &&
if [ -f "$f" ] && [ -r "$f" ]; then ...; fi  # โœ…

โŒ Don’t Do This:

# Don't use = for numbers
if [ "$a" = 5 ]; then ...; fi             # โš ๏ธ  string compare

# Don't use -eq for strings
if [ "$name" -eq "Alice" ]; then ...; fi  # โŒ error

# Don't forget quotes in [ ]
if [ $name = "Alice" ]; then ...; fi      # โŒ breaks if empty

# Don't use > without escaping
if [ "$a" > "$b" ]; then ...; fi          # โŒ creates file "b"

# Don't use elif after else
if ...; then ...
else ...
elif ...; then ...                         # โŒ unreachable
fi

# Don't forget fi
if [ -f file ]; then
    echo "yes"
# missing fi                                # โŒ syntax error

# Don't mix [ ] and [[ ]]
if [[ $a -gt 0 ] && [ $b -gt 0 ]]; then    # โš ๏ธ  works but inconsistent

# Don't forget spaces around [ ]
if [$a -gt 0]; then ...; fi                # โŒ syntax error

Common Pitfalls

PitfallProblemSolution
No spaces in [ ]Syntax error[ "$a" -gt 0 ]
Missing fiScript failsAdd fi
Unquoted variableBreaks on emptyQuote: "$var"
= for numbersString compareUse -eq
-eq for stringsErrorUse =
Unescaped >Redirection\> or [[ ]]
elif after elseUnreachableReorder
Empty variable[: =: unexpected operatorQuote

Real-World Examples

1. Classify a Number

#!/bin/bash
read -p "Enter a number: " num
if [ "$num" -lt 0 ]; then
    echo "The number is negative."
elif [ "$num" -eq 0 ]; then
    echo "The number is zero."
else
    echo "The number is positive."
fi

2. Arithmetic Calculator

#!/bin/bash
num1=10
num2=5
echo "Sum: $((num1 + num2))"
echo "Difference: $((num1 - num2))"
echo "Product: $((num1 * num2))"
echo "Quotient: $((num1 / num2))"
echo "Remainder: $((num1 % num2))"
[ Sum: 15 ]
[ Difference: 5 ]
[ Product: 50 ]
[ Quotient: 2 ]
[ Remainder: 0 ]

3. Both Positive

#!/bin/bash
num1=10
num2=5
if [ $num1 -gt 0 ] && [ $num2 -gt 0 ]; then
    echo "Both numbers are positive."
else
    echo "At least one number is not positive."
fi
[ Both numbers are positive. ]

4. Empty String Check

#!/bin/bash
string1=""
if [ -z "$string1" ]; then
    echo "String is empty."
else
    echo "String is not empty."
fi
[ String is empty. ]

5. File Exists Check

#!/bin/bash
file="$1"
if [ -f "$file" ]; then
    echo "File exists"
    wc -l "$file"
else
    echo "File not found"
    exit 1
fi

6. Directory Check

#!/bin/bash
dir="$1"
if [ -d "$dir" ]; then
    echo "$dir is a directory"
    ls "$dir" | wc -l
fi

7. Grade Calculator

#!/bin/bash
read -p "Grade: " g
if   [ "$g" -ge 90 ]; then echo "A"
elif [ "$g" -ge 80 ]; then echo "B"
elif [ "$g" -ge 70 ]; then echo "C"
elif [ "$g" -ge 60 ]; then echo "D"
else                       echo "F"
fi

8. Age Check

#!/bin/bash
read -p "Age: " age
if [ "$age" -ge 18 ]; then
    echo "Adult"
else
    echo "Minor"
fi

9. Login Check

#!/bin/bash
read -p "Username: " user
if [ "$user" = "admin" ]; then
    echo "Welcome, admin"
elif [ "$user" = "guest" ]; then
    echo "Welcome, guest"
else
    echo "Unknown user"
fi

10. Regex Email Validation

#!/bin/bash
read -p "Email: " email
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
    echo "Valid email"
else
    echo "Invalid email"
fi

11. Glob Pattern Match

#!/bin/bash
for file in *; do
    if [[ "$file" == *.txt ]]; then
        echo "Text file: $file"
    fi
done

12. Case Menu

#!/bin/bash
echo "1) Start"
echo "2) Stop"
echo "3) Quit"
read -p "Choice: " c
case "$c" in
    1) echo "Starting..." ;;
    2) echo "Stopping..." ;;
    3) exit 0 ;;
    *) echo "Invalid choice" ;;
esac

13. Command Available Check

#!/bin/bash
if command -v git > /dev/null 2>&1; then
    echo "git is installed"
else
    echo "git is not installed"
fi

14. Multiple Conditions

#!/bin/bash
read -p "Age: " age
read -p "Member (y/n): " member
if [ "$age" -ge 18 ] && [ "$member" = "y" ]; then
    echo "Access granted"
else
    echo "Access denied"
fi

15. Negation

#!/bin/bash
if ! [ -f /etc/passwd ]; then
    echo "Missing critical file!"
    exit 1
fi
echo "File exists"

16. Validate Numeric Input

#!/bin/bash
read -p "Number: " n
if [[ "$n" =~ ^[0-9]+$ ]]; then
    echo "Valid: $n"
else
    echo "Not a number"
fi

17. Yes/No Prompt

#!/bin/bash
read -p "Continue? (y/n): " ans
if [[ "$ans" =~ ^[Yy]$ ]]; then
    echo "Continuing"
else
    echo "Cancelled"
fi

18. Disk Usage Warning

#!/bin/bash
usage=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$usage" -gt 80 ]; then
    echo "WARNING: disk at ${usage}%"
fi

19. HTTP Status Check

#!/bin/bash
status=$(curl -s -o /dev/null -w "%{http_code}" https://example.com)
if [ "$status" -eq 200 ]; then
    echo "Site is up"
else
    echo "Site returned $status"
fi

20. Full Menu with Loop

#!/bin/bash
while true; do
    echo "1) Date"
    echo "2) Uptime"
    echo "3) Quit"
    read -p "Choose: " choice
    case "$choice" in
        1) date ;;
        2) uptime ;;
        3) break ;;
        *) echo "Invalid" ;;
    esac
done

Visual: if / elif / else Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           if / elif / else                   โ”‚
โ”‚                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚  โ”‚  if [ condition1 ]; then           โ”‚      โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ”‚                 โ”‚                            โ”‚
โ”‚         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”‚
โ”‚        true           false                  โ”‚
โ”‚         โ”‚                โ”‚                   โ”‚
โ”‚         โ–ผ                โ–ผ                   โ”‚
โ”‚    run block1      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚                    โ”‚ elif [ cond2 ];   โ”‚     โ”‚
โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚                    true           false      โ”‚
โ”‚                     โ”‚                โ”‚       โ”‚
โ”‚                     โ–ผ                โ–ผ       โ”‚
โ”‚                run block2    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚                              โ”‚ else       โ”‚  โ”‚
โ”‚                              โ”‚ run block3 โ”‚  โ”‚
โ”‚                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                              โ”‚
โ”‚                    fi                        โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual: [ ] vs [[ ]]

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           [ ] (POSIX test)                   โ”‚
โ”‚                                              โ”‚
โ”‚  [ "$a" -gt 0 ]                              โ”‚
โ”‚  โ€ข Requires quotes around variables          โ”‚
โ”‚  โ€ข No && or || inside                        โ”‚
โ”‚  โ€ข No regex or glob matching                 โ”‚
โ”‚  โ€ข Works in all shells                       โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           [[ ]] (bash extended test)         โ”‚
โ”‚                                              โ”‚
โ”‚  [[ $a -gt 0 && $b -gt 0 ]]                  โ”‚
โ”‚  โ€ข No quotes needed                          โ”‚
โ”‚  โ€ข && and || work inside                     โ”‚
โ”‚  โ€ข Regex with =~                             โ”‚
โ”‚  โ€ข Glob patterns with ==                     โ”‚
โ”‚  โ€ข Bash, ksh, zsh only                       โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ConceptSyntaxExample
Simple ifif [ cond ]; then ...; fiif [ -f f ]; then ...; fi
If/elseif [ c ]; then ...; else ...; fi
Elifif [ c1 ]; then ...; elif [ c2 ]; then ...; fi
Negationif ! cmd; then ...; fiif ! [ -f f ]; then ...; fi
Numeric compare-eq -ne -gt -ge -lt -le[ $a -gt 0 ]
String compare= != -z -n[ "$s" = "hi" ]
File test-e -f -d -r -w -x -s[ -f "$file" ]
Logical&& || ![ $a -gt 0 ] && [ $b -gt 0 ]
Arithmetic$((...))$((a + b))
Extended test[[ ... ]][[ $a -gt 0 && $b -gt 0 ]]
Regex[[ $s =~ pat ]][[ $email =~ @.*\.com ]]
Casecase ... esaccase $1 in start) ...;; esac

Key takeaways:

  • if tests the exit status of a command โ€” 0 is true, non-zero is false
  • Use [ ... ] for POSIX portability, [[ ... ]] for bash power
  • Always quote variables in [ ] โ€” unquoted empties cause errors
  • Use -eq, -ne, -gt etc. for numbers; =, != for strings
  • Use -z for empty and -n for non-empty strings
  • Use -f, -d, -x to test files
  • Combine conditions with &&, ||, ! โ€” or inside [[ ]]
  • Use case when matching one value against many patterns
  • Arithmetic is integer-only in $((...)) โ€” use bc or awk for floats
  • Always provide an else or handle the missing case explicitly
  • Test in order โ€” put the most specific condition first
  • Don’t forget fi and spaces around [ ]

Remember: if is the decision-maker of your script. Use it to check numbers, strings, files, and command results. Prefer [[ ]] in bash, but quote everything in [ ]. Use -eq for numbers and = for strings โ€” mixing them is a common bug. When you have many branches on the same value, case is cleaner. And always think about the “what if it’s empty?” case โ€” that’s where most shell scripts break.


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!