Bash as a programming language is not most programmers’ go-to, especially with far more common languages like Python and C.
It’s helpful to write programming constructs to execute commands based on criteria with if statements or the same command with multiple arguments using a
This tutorial will go over if statements in Bash, focusing on the kinds of conditional expressions used in if statements.
if Statement in Bash
The general syntax of the
if statement in Bash is as follows.
if condition; then do-if-true; elif second-condition; then do-else-if-true elif third-condition; then do-else-if-third-true else do-else-false fi
The conditions themselves can have different syntax, depending on the required condition.
- If you would like to use the output of a command as a condition, such as
grepthe contents of a file to see if it contains a certain substring, you can place the command after the if keyword, as follows.
if greq -q "string" file.txt; then echo "string exists in file.txt." else echo "string does not exist in file.txt." fi
[ "$s" = "string" ]checks if the variable
$scontains the value
string. It is also equivalent to
test "$s" = "string", where
testeffectively substitutes the square brackets.
if [ "$s" = "string" ]; then echo "string is equivalent to \$s" else echo "string is not equivalent to \$s" fi
You can even perform arithmetic operations, such as checking if the expected number of files or lines in a file is certain or if the number in a directory is smaller or larger than that of another directory.
We do this with pairs of parentheses.
a=$(ls dir_a | wc -l) b=$(ls dir_b | wc -l) if (( a < b )); then echo "Directory a has fewer files than directory b." elif (( a > b )); then echo "Directory a has more files than directory b." else echo "Directory a has the same number of files as that of directory b." fi
Built-In Bash Conditionals
Sometimes, running a separate program to check something as simple as file existence, modification dates, and sizes is tedious and resource-consuming, so Bash can check such attributes as if statements directly.
The following flags check for these attributes’ existence or non-existence, returning an effectively true or false result to the if statement.
For example, to check if a command produced no output, we can treat its output as a string and check if the length of that string is zero with the
-z flag, as follows.
out=$(bash print-if-error.sh) if [[ -z $out ]]; then echo "The script ran successfully." else echo "The script produced the following errors: " echo $out fi
To get the inverse of the condition, you can either use the
! NOT operator, or use the converse form of this flag, which is either
-n, or no flag at all, since a non-empty string can behave as “true” in a Bash if statement.
out=$(bash print-if-error.sh) if [[ $out ]]; then echo "The script produced the following errors: " echo $out else echo "The script ran successfully." fi
Some other useful flags are explained below, with explanations referenced from the GNU Bash Reference Manual.
-fchecks if the file exists and it’s a regular file.
-dchecks if the argument provided was a directory.
-hchecks if the argument provided was a symbolic link.
-schecks if the file exists and is not empty.
-rcheck if the file is readable.
-wcheck if the file is writable.
-xcheck if the file is executable.
For flags that take two arguments, like comparison operators, the first argument comes before the flag while the second appears after the flag.
Suppose we compare two files - a.txt and b.txt - to see which is newer, with the
-nt flag. The converse will check if it is older, with
out=$(bash print-if-error.sh) if [[ a.txt -nt b.txt ]]; then echo "a.txt is newer than b.txt." else echo "a.txt is older or the same age as b.txt." fi
Other such two-operand flags are as follows.
-efensures that the two arguments refer to the same device and inode numbers.
!=ensures that the two arguments are not equal.
<checks that the first argument is alphabetically before the second.
>checks that the first argument is alphabetically after the second.
-eqassumes that both args are integers and checks that they are equal.
-neassumes that both args are integers and checks that they are not equal.
-ltassumes that both args are integers and checks that the first is less than the second. One can use
-leto check if they are equal.
-gtassumes that both args are integers and checks that the first is greater than the second. One can use
-geto check if they are equal.
- Single Line if...else in Bash
- Multiple if Conditions in Bash Script
- The if not Condition in Bash
- Use and With the if Statement in Bash