Docs > Bash Handbook > Conditional-statements
Conditional statements
Like in other languages, Bash conditionals let us decide to perform an action or not. The result is determined by evaluating an expression, which should be enclosed in [[ ]]
.
Conditional expression may contain &&
and ||
operators, which are AND and OR accordingly. Besides this, there many other handy expressions.
There are two different conditional statements: if
statement and case
statement.
Primary and combining expressions
Expressions enclosed inside [[ ]]
(or [ ]
for sh
) are called test commands or primaries. These expressions help us to indicate results of a conditional. In the tables below, we are using [ ]
, because it works for sh
too. Here is an answer about the difference between double and single square brackets in bash.
Working with the file system:
Primary | Meaning |
---|---|
[ -e FILE ] |
True if FILE exists. |
[ -f FILE ] |
True if FILE exists and is a regular file. |
[ -d FILE ] |
True if FILE exists and is a directory. |
[ -s FILE ] |
True if FILE exists and not empty (size more than 0). |
[ -r FILE ] |
True if FILE exists and is readable. |
[ -w FILE ] |
True if FILE exists and is writable. |
[ -x FILE ] |
True if FILE exists and is executable. |
[ -L FILE ] |
True if FILE exists and is symbolic link. |
[ FILE1 -nt FILE2 ] |
FILE1 is newer than FILE2. |
[ FILE1 -ot FILE2 ] |
FILE1 is older than FILE2. |
Working with strings:
Primary | Meaning |
---|---|
[ -z STR ] |
STR is empty (the length is zero). |
[ -n STR ] |
STR is not empty (the length is non-zero). |
[ STR1 == STR2 ] |
STR1 and STR2 are equal. |
[ STR1 != STR2 ] |
STR1 and STR2 are not equal. |
Arithmetic binary operators:
Primary | Meaning |
---|---|
[ ARG1 -eq ARG2 ] |
ARG1 is equal to ARG2 . |
[ ARG1 -ne ARG2 ] |
ARG1 is not equal to ARG2 . |
[ ARG1 -lt ARG2 ] |
ARG1 is less than ARG2 . |
[ ARG1 -le ARG2 ] |
ARG1 is less than or equal to ARG2 . |
[ ARG1 -gt ARG2 ] |
ARG1 is greater than ARG2 . |
[ ARG1 -ge ARG2 ] |
ARG1 is greater than or equal to ARG2 . |
Conditions may be combined using these combining expressions:
Operation | Effect |
---|---|
[ ! EXPR ] |
True if EXPR is false. |
[ (EXPR) ] |
Returns the value of EXPR . |
[ EXPR1 -a EXPR2 ] |
Logical AND. True if EXPR1 and EXPR2 are true. |
[ EXPR1 -o EXPR2 ] |
Logical OR. True if EXPR1 or EXPR2 are true. |
Sure, there are more useful primaries and you can easily find them in the Bash man pages.
Using an if
statement
if
statements work the same as in other programming languages. If the expression within the braces is true, the code between then
and fi
is executed. fi
indicates the end of the conditionally executed code.
# Single-line
if [[ 1 -eq 1 ]]; then echo "true"; fi
# Multi-line
if [[ 1 -eq 1 ]]; then
echo "true"
fi
Likewise, we could use an if..else
statement such as:
# Single-line
if [[ 2 -ne 1 ]]; then echo "true"; else echo "false"; fi
# Multi-line
if [[ 2 -ne 1 ]]; then
echo "true"
else
echo "false"
fi
Sometimes if..else
statements are not enough to do what we want to do. In this case we shouldn't forget about the existence of if..elif..else
statements, which always come in handy.
Look at the example below:
if [[ `uname` == "Adam" ]]; then
echo "Do not eat an apple!"
elif [[ `uname` == "Eva" ]]; then
echo "Do not take an apple!"
else
echo "Apples are delicious!"
fi
Using a case
statement
If you are confronted with a couple of different possible actions to take, then using a case
statement may be more useful than nested if
statements. For more complex conditions use case
like below:
case "$extension" in
"jpg"|"jpeg")
echo "It's image with jpeg extension."
;;
"png")
echo "It's image with png extension."
;;
"gif")
echo "Oh, it's a giphy!"
;;
*)
echo "Woops! It's not image!"
;;
esac
Each case is an expression matching a pattern. The |
sign is used for separating multiple patterns, and the )
operator terminates a pattern list. The commands for the first match are executed. *
is the pattern for anything else that doesn't match the defined patterns. Each block of commands should be divided with the ;;
operator.