Shell by Example: If Statements POSIX + Bash

The if statement lets you execute code conditionally. It’s fundamental to controlling program flow in shell scripts.

Basic if statement syntax:

Edit
#!/bin/sh
if true; then
    echo "This always runs"
fi
Output:
This always runs

The if tests the exit status of a command. Exit status 0 means success (true), non-zero means failure (false).

Edit
#!/bin/sh
if ls /tmp >/dev/null 2>&1; then
    echo "/tmp exists and is readable"
fi
Output:
/tmp exists and is readable

Use the test command or [ ] for comparisons. Note: spaces inside [ ] are required!

Numeric comparisons:

  • -eq (equal), -ne (not equal)
  • -lt (less than), -le (less or equal)
  • -gt (greater than), -ge (greater or equal)
Edit
#!/bin/sh
value=10
count=5

if [ "$value" -eq 10 ]; then
    echo "Value is 10"
fi

if [ "$count" -gt 3 ]; then
    echo "Count is greater than 3"
fi
Output:
Value is 10
Count is greater than 3

String comparisons use = and !=.

Edit
#!/bin/sh
name="Alice"

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

if [ "$name" != "Bob" ]; then
    echo "Hello, not Bob!"
fi
Output:
Hello, Alice!
Hello, not Bob!

All test expressions are supported, including checking if a string is empty or non-empty.

Edit
#!/bin/sh
empty=""
nonempty="hello"

if [ -z "$empty" ]; then
    echo "Variable is empty"
fi

if [ -n "$nonempty" ]; then
    echo "Variable is not empty"
fi
Output:
Variable is empty
Variable is not empty

File test expressions are also supported.

Edit
#!/bin/sh
if [ -f "/etc/passwd" ]; then
    echo "/etc/passwd exists and is a file"
fi

if [ -d "/tmp" ]; then
    echo "/tmp exists and is a directory"
fi
Output:
/etc/passwd exists and is a file
/tmp exists and is a directory

Always quote variables in tests to handle empty values and spaces correctly.

Edit
#!/bin/sh
user_input=""
# this will be a syntax error if the variable is not quoted
if [ $user_input = "some_value" ]; then
    echo "No input provided"
fi
Output:
sh: some_value: unknown operand

Bash

Bash provides extended test syntax [[ ]] which is safer and more powerful than single brackets [ ].

With [[ ]], quoting is often optional:

Edit
#!/bin/bash
name="Alice"
if [[ $name = Alice ]]; then
    echo "Hello, Alice!"
fi
Output:
Hello, Alice!

Bash

Bash supports pattern matching with [[ ]] expressions. These are similar to regular expressions, but used for more simple string matching.

Edit
#!/bin/bash
filename="example.txt"
if [[ $filename = *.txt ]]; then
    echo "It's a text file"
fi
Output:
It's a text file

Bash

Regex matching with =~ can be used for more complex string matching.

Edit
#!/bin/bash
email="test@example.com"
# this regex is not comprehesive
# and merely used for demonstration purposes
if [[ $email =~ ^[a-z]+@[a-z]+\.[a-z]+$ ]]; then
    echo "Valid email format"
fi
Output:
Valid email format

Bash

Bash also provides (( )) for arithmetic evaluation, which is cleaner for numeric comparisons:

Edit
#!/bin/bash
count=5
if ((count > 3)); then
    echo "Count is greater than 3"
else
    echo "Count is not greater than 3"
fi

x=40
if ((x >= 0 && x <= 100)); then
    echo "x is between 0 and 100"
else
    echo "x is not between 0 and 100"
fi
Output:
Count is greater than 3
x is between 0 and 100

« Command Substitution | Case Statements »