Bash scripts often need to make decisions based on multiple conditions. This tutorial explains how to combine conditions within if
statements, focusing on the common pitfalls and best practices.
Understanding Boolean Logic
At its core, conditional logic involves evaluating whether conditions are true or false. In Bash, the success (exit status 0) or failure (non-zero exit status) of a command determines its truthiness. To combine multiple conditions, we use logical operators. The key ones are:
- AND: Both conditions must be true for the overall expression to be true.
- OR: At least one of the conditions must be true for the overall expression to be true.
The test
Command and [
Syntax
Bash uses the test
command (or its synonym, [ ]
) to evaluate conditions. The test
command (and [ ]
) takes arguments that specify the conditions to check. It’s crucial to remember that [
is actually a command, and requires a closing ]
as its final argument.
Here’s a basic example:
#!/bin/bash
file="my_file.txt"
if [ -f "$file" ]; then
echo "$file exists"
fi
In this example, -f "$file"
checks if the file exists and is a regular file. The if
statement executes the echo
command only if the file exists. Note the use of double quotes around the variable $file
; this is important to prevent word splitting and globbing.
Combining Conditions with AND
To combine multiple conditions with AND, you can use the -a
operator with the [
command. However, using -a
is considered bad practice. A more reliable and readable approach is to use separate test
commands (or [ ]
statements) chained with the &&
operator.
Here’s an example:
#!/bin/bash
status_code=404
string_value="example"
expected_value="test"
if [ "$status_code" -ne 200 ] && [ "$string_value" != "$expected_value" ]; then
echo "Status code is not 200 and string values are different"
fi
In this example, the if
statement will only execute the echo
command if both conditions are true: the status_code
is not equal to 200, and the string_value
is not equal to expected_value
.
Important Considerations
- Exit Status: The
if
statement evaluates the exit status of the command(s) it runs. A zero exit status indicates success (true), while a non-zero exit status indicates failure (false). - Variable Quoting: Always quote your variables (e.g.,
"$variable"
) to prevent unexpected behavior due to word splitting and globbing. - Whitespace: Use whitespace around operators (e.g.,
[ "$a" -eq "$b" ]
) to improve readability. - Avoid
[[ ]]
: While[[ ]]
offers some advantages in certain situations, it is a Bash-specific extension and may not be portable to other shells. It can also suppress error messages which is undesirable. For maximum portability and clarity, stick to the[
andtest
commands.
Example: Checking Website Status and Content
Here’s a practical example that combines multiple conditions to check if a website is down and if a specific string is present on the page:
#!/bin/bash
WEBSITE="domain.example"
SUBJECT="$WEBSITE DOWN!"
EMAILID="[email protected]"
STATUS=$(curl -sI "$WEBSITE" | awk '/HTTP\/1.1/ { print $2 }')
STRING=$(curl -s "$WEBSITE" | grep -o "string_to_search")
VALUE="string_to_search"
if [ "$STATUS" -ne 200 ] && [ "$STRING" != "$VALUE" ]; then
echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" "$EMAILID"
fi
This script checks if the HTTP status code is not 200 (indicating an error) and if the string_to_search
is not found on the website. If both conditions are true, it sends an email notification.