Sometimes you need to specify different courses of action to be taken in a shell script, depending on the success or failure of a command. The if construction allows you to specify such conditions.
The most common syntax of the if command is:
if TEST-COMMAND
then
POSITIVE-CONSEQUENT-COMMANDS
else
NEGATIVE-CONSEQUENT-COMMANDS
fiThis is a conditional statement in Bash that consists of a TEST-COMMAND, followed by a positive consequent command block (POSITIVE-CONSEQUENT-COMMANDS), and an optional negative consequent command block (NEGATIVE-CONSEQUENT-COMMANDS). If the TEST-COMMAND is successful (returns an exit status of 0), then the positive consequent commands are executed, otherwise, the negative consequent commands (if provided) are executed. The if statement is terminated with the fi command.
Before you start, review the man page of the test command.
The first example checks for the existence of a file:
echo "This script checks the existence of the messages file."
echo "Checking..."
if [ -f /var/log/messages ]
then
echo "/var/log/messages exists."
fi
echo
echo "...done."🧐 What is the relation between the
testcommand and[?
Recall that the $? variable holds the exit status of the previously executed command. The following example utilizes this variable to make a decision according to the success or failure of the previous command:
curl google.com &> /dev/null
if [ $? -eq 0 ]
then
echo "Request succeeded"
else
echo "Request failed, trying again..."
fiThe below example demonstrates numeric comparison between a variable and 20. Don't worry is it doesn't work, you'll fix it soon 🙂
num=$(wc -l /etc/passwd)
echo $num
if [ "$num" -gt "20" ]; then
echo "Too many users in the system."
fiCopy the above script to a
.shfile, and execute. Debug the script until you understand why the script fails. Use theawkcommand to fix the problem. Tip: using the-xflag can help you debug your bash run:bash -x myscript.sh
if [[ "$(whoami)" != 'root' ]]; then
echo "You have no permission to run $0 as non-root user."
exit 1;
fiecho "Bash is ok" > file
if grep -q Bash file
then
echo "File contains at least one occurrence of Bash."
fiAnother example:
word=Linux
letter_sequence=inu
if echo "$word" | grep -q "$letter_sequence"
# The "-q" option to grep suppresses output.
then
echo "$letter_sequence found in $word"
else
echo "$letter_sequence not found in $word"
fiWith version 2.02, Bash introduced the [[ ... ]] extended test command, which performs comparisons in a manner more familiar to programmers from other languages. The [[...]] construct is the more versatile Bash version of [...]. Using the [[...]] test construct, rather than [...] can prevent many logic errors in scripts.
The curl command can be used to perform a request to an external website and return the response's status code:
curl -o /dev/null -s -w "%{http_code}" www.google.comThis curl command suppresses output (-o /dev/null), runs silently without printing the traffic progress (-s), and prints the HTTP status code (-w "%{http_code}").
Create an availability_test.sh script that receives an address as the 1st (and only) argument, and perform the above curl command.
The script should be completed successfully if the returned HTTP status code is < 500,
or fail otherwise (you can exit the script with exit 1 to indicate failure).
Here is the expected behaviour:
myuser@hostname:~$ ./availability_test.sh www.google.com
www.google.com is up!
myuser@hostname:~$ ./availability_test.sh http://cnn.com
http://cnn.com is up!
myuser@hostname:~$ ./availability_test.sh abcdefg
abcdefg is not available.
myuser@hostname:~$ echo $?
1
myuser@hostname:~$ ./availability_test.sh
A valid URL is required
myuser@hostname:~$ ./availability_test.sh google.com cnn.com
The script is expected a single argument only, but got 2.
myuser@hostname:~$ ./availability_test.sh httpbin.org/status/500 # this url should return a status code of 500
httpbin.org/status/500 is not available.Write a bash script geo_by_ip.sh that, given an ip address, prints geo-location details, as follows:
- The script first checks if
jqcli is installed. If not installed, it prints a message to the user with a link to download the tool: https://stedolan.github.io/jq/download/ - The script checks that exactly one argument was sent to it, which represents the ip address to check. Otherwise, an informative message is printed to stdout.
- The script checks that the given IP argument is not equal to
127.0.0.1. - The script performs an HTTP GET request to
http://ip-api.com/json/<ip>, where<ip>is the IP argument. The results should be stored in a variable. - Using the jq tool and the variable containing the HTTP response, check that the request has succeeded by checking that the
statuskey has a value ofsuccess. The commandjq -r '.<key>'can extract a key from the json (e.g.echo $RESPONSE | jq -r '.status') - If the request succeed, print the following information to the user:
- country
- city
- regionName