Bash scripting is vital for Linux system administrators and developers. It offers automation and system management capabilities. However, mastering conditions in Bash, crucial for decision-making in scripts, can be challenging for beginners. This guide titled ‘Bash If Statement: Conditions in Bash Scripting’ digs into Bash scripting conditions, covering types, special characters and syntax, making it accessible for both novices and those seeking to improve their scripting skills.
Understanding Bash Scripting
Before we explore the world of Bash scripting conditions, let us ensure that we are all on the same page. Bash scripting is like writing a script for a movie. It tells Bash what to do at specific times. Instead of manually executing commands one by one, you can create Bash scripts to automate these tasks. But remember, to run your Bash script, you must set the execute bit on the file.
Common Special Characters in Bash
In Bash scripting, special characters are used for various purposes. Here are some of the most commonly used ones:
” ” or ‘ ‘: Denotes whitespace. Single quotes preserve literal meanings, while double quotes allow substitutions.
$: Denotes an expansion, used with variables, command substitution, arithmetic substitution, etc.
: Escape character, used to remove “specialness” from special characters.
#: Comments. Anything after this character isn’t interpreted.
=: Assignment.
or [[ ]]: Test; evaluates for either true or false.
!: Negation.
, >, <: Input/output redirection.
|: Sends the output of one command to the input of another.
or ?: Globs (wildcards). ? is a wildcard for a single character.
Bash Programming Introduction
Bash scripting provides a wide range of built-in checks and comparisons. These come in handy for various situations. Conditions, often used with ‘if’ statements, play a crucial role in these checks. Here is an example of an ‘if’ statement:
if [ $foo -ge 3 ]; then
The condition within the square brackets is essentially a command. It might seem peculiar, but surrounding a comparison with square brackets is equivalent to using the built-in ‘test’ command, as shown below:
if test $foo -ge 3; then
If the variable $foo is greater than or equal to 3, the block of code following ‘then’ will be executed. You might wonder why Bash uses ‘-ge’ or ‘-eq’ instead of ‘>=’ or ‘==’ for comparisons. This choice stems from the origin of this condition type, where ‘-ge’ and ‘-eq’ are options.
Essentially, ‘if’ checks the exit status of a command. We will explain this in more detail later in the tutorial. In addition to file-based conditions, there are checks more specific to shells, like these:
if [ -f regularfile ]; then
The above condition is true if the file ‘regularfile’ exists and is a regular file. A regular file is neither a block or character device nor a directory. This enables you to ensure the existence of a usable file before performing further operations. You can also check if a file is readable:
if [ -r readablefile ]; then
The condition above is true if the file ‘readablefile’ exists and is readable. Pretty straightforward, right?
The Syntax of a Bash ‘if’ Statement
The basic syntax of an ‘if…then’ statement in Bash looks like this:
if <condition>; then
<commands>
fi
The condition can be surrounded by specific brackets, such as [ ]. You can include commands to execute when the condition is false using the ‘else’ keyword. To execute commands based on another condition if the primary condition is false, you can use the ‘elif’ (elseif) keyword. The ‘else’ keyword always comes last. Here’s an example:
if [ -r somefile ]; then
content=$(cat somefile)
elif [ -f somefile ]; then
echo “The file ‘somefile’ exists but is not readable to the script.”
else
echo “The file ‘somefile’ does not exist.”
Fi
In the provided example, we initially verify the accessibility of the file ‘somefile.’ If it is indeed readable, we proceed to store its content in a variable. If the file exists but is not readable, we acknowledge its existence but also its lack of readability. In the case where the file doesn’t exist, we communicate this as well. It’s important to note that the ‘elif’ condition is examined only when the ‘if’ condition returns false, and the commands within ‘else’ are executed solely when both conditions yield false results.
Basic Rules of Bash Conditions
Using own conditions requires some rules to avoid difficult-to-trace errors:
Maintain spaces between the brackets as well as the actual check or comparison. For example, the following won’t work:
if [$foo -ge 3]; then
Bash will report a “missing `]'”.
It is essential to remember that when writing Bash conditions, you should complete the line before introducing a new keyword such as “then.” Keywords like ‘if,’ ‘then,’ ‘else,’ ‘elif,’ and ‘fi’ are specific to the shell and must not be on the same line. You can either separate the previous statement and the keyword with a semicolon or begin a new line with the keyword. Neglecting this rule can lead to errors like “syntax error near unexpected token `fi'” in your Bash scripts.
A best practice in Bash scripting is to enclose string variables in quotes when using them in conditions. This is important to avoid problems related to spaces and newlines. For instance:
if [ “$stringvar” == “tux” ]; then
There are a few rare cases where you should not quote, but those are exceptions.
Furthermore, there are two additional things to know:
You can invert a condition by placing an “!” in front of it, like this:
if [ ! -f regularfile ]; then
Be sure to place the “!” inside the brackets.
You can combine conditions using specific operators. In the single-bracket syntax we’ve discussed so far, you can use “-a” for ‘and’ and “-o” for ‘or,’ like this:
if [ $foo -ge 3 -a $foo -lt 10 ]; then
This condition evaluates to true when the variable $foo holds an integer value that is greater than or equal to 3 and less than 10. If you want to delve deeper into combining expressions, you can explore the specific condition syntaxes.
It is worth mentioning that conditions can also be applied in various other statements, like ‘while’ and ‘until.’ While these subjects go beyond the scope of this tutorial, you can find additional resources in the ‘Bash Guide for Beginners’ for further insights.
Different Condition Syntaxes
Bash offers different syntaxes for conditions, and we will explore three main ones: single-bracket syntax, double-bracket syntax, and double-parenthesis syntax.
Single-Bracket Syntax:
This is the oldest and most widely supported condition syntax. It supports three primary condition types:
File-based conditions: These are used to check files based on various criteria.
if [ -L symboliclink ]; then
String-based conditions: These are used for string comparisons.
if [ “$stringvar1” == “cheese” ]; then
Arithmetic (number-based) conditions: These allow you to compare integer numbers.
if [ $num -lt 1 ]; then
The single-bracket syntax supports these basic conditions.
Double-Bracket Syntax:
The double-bracket syntax is an enhanced version of the single-bracket syntax. It features similar capabilities but with some important differences and additional features. Here is what you can do with double brackets:
Shell globbing: Double brackets allow shell globbing when comparing strings.
if [[ “$stringvar” == *string* ]]; then
Word splitting: Word splitting is prevented in double-bracket conditions, so you can often omit quotes around string variables.
No filename expansion: The double-bracket syntax doesn’t expand filenames, ensuring that glob patterns are taken literally.
Additional combining expressions: The double-bracket syntax introduces the ‘&&’ and ‘||’ operators for combining conditions.
Regular expression matching: It allows regular expression pattern matching using the “=~” operator.
This syntax provides more advanced capabilities and is often favored for its improved string handling.
Double-Parenthesis Syntax:
This syntax is mainly used for arithmetic (number-based) conditions. It resembles the double-bracket syntax but is geared toward numerical comparisons.
if (( num < 10 )); then
You can use this syntax for more complex mathematical comparisons.