User Input! Shell Scripting Part 4

Published on September 12, 2022 at 6:27 pm by LEW

Introduction

In this installment we are going to up the complexity a little. We will be collecting input from the user while the script is running, and introducing a couple of new structures (while loop and case).

Nothing that is to bizarre. The program flow and logic should still be straight forward and easy to follow. I have, on occasion, noticed on a lot of scripts I look at have some fairy complex logic, structure, and flow. The script we will review today could be cut down to less than half the length it is, but it would not be as easy to follow.

These are text files after all and I would be looking at the difference between 1.7 KB and 0.8 KB. Not a lot by today’s standard. So I prefer to make the script easier to follow, even if it takes up a few extra KB.

Simple Calculator Script

Today’s scrip is a simple calculator script that provides basic instruction to the user, gets and validates user input (asking for reentry if incorrect), and then outputs results. I am posting the script, after which we will go thought it. This one is a bit longer than previous scripts.

#!/bin/bash

# Name: user_math             Version: 1
# Author: RetiredTechie       Date: 11 SEP 2022
#
# Description: Get user input to perform some basic math operations

# Set some variable values before doing anything esle
NUMBER1="0"
NUMBER2="0"
NUMBER3="0"
OPERATOR="0"

# Print out instructions for the user

printf "%b" "\nBASH SIMPLE CALCULATOR SCRIPT\n\n"
printf "%b" "This script will perform simple calculations based on\n"
printf "%b" "three pieces of user input. These are as follows:\n\n"
printf "%-10s %s\n" "Entry" "Type"
printf "%-11s %s\n" "----------" "-----------------------"
printf "%-11s %s\n" "Digit 1" "An integer from 1 to 9"
printf "%-11s %s\n" "Digit 2" "An integer from 1 to 9"
printf "%-11s %s\n" "Operator" "Addition         [+]"
printf "%-11s %s\n" " " "Subtraction     [-]"
printf "%-11s %s\n" " " "Multiplication  [x]"
printf "%-11s %s\n" " " "Division        [/]"
printf "%b" "\n"

# Collect User input

while [ $NUMBER1 -lt 1 ]; do     # While loop cycles though until
                                 # valid input received.
    read -p "Digit 1: " NUMBER1  # Restates input requirements on
                                 # bad input
    if ! echo $NUMBER1 | grep -Eq '^[1-9]*$'; then
        NUMBER1="0"
        echo "Must be an integer between 1 and 9"
    fi
done

while [ $NUMBER2 -lt 1 ]; do

    read -p "Digit 2: " NUMBER2

    if ! echo $NUMBER2 | grep -Eq '^[1-9]*$'; then
        NUMBER2="0"
        echo "Must be an integer between 1 and 9"
    fi
done

while ! echo $OPERATOR | grep -Eq '^[+,--,x,/]$' > /dev/null; do

    read -p "Operator: " OPERATOR

    if ! echo $OPERATOR | grep -Eq '^[+,--,x,/]$'; then
        OPERATOR="0"
        echo "Must be +, -, x, or /"
    fi

done

echo

# Do calculation and output results

case $OPERATOR in

    +)          # Case operator for each instance
        NUMBER3=$(($NUMBER1+$NUMBER2))
        echo $NUMBER1 "+" $NUMBER2 "=" $NUMBER3
    ;;

    -)
        NUMBER3=$(($NUMBER1-$NUMBER2))
        echo $NUMBER1 "-" $NUMBER2 "=" $NUMBER3
    ;;

    x)
        NUMBER3=$(($NUMBER1*$NUMBER2))
        echo $NUMBER1 "x" $NUMBER2 "=" $NUMBER3
    ;;

    *)        # catch all end operator, whatever is left
        NUMBER3=$(($NUMBER1/$NUMBER2))
        echo $NUMBER1 "/" $NUMBER2 "=" $NUMBER3
    ;;

esac

echo

exit 0

Script Review

Skipping over items form previous posts, we start at Line 8. Here we are declaring some variables we will be using and assigning them a value. Some might argue we do not need to do this in a shell script, but to me it makes the flow easier to follow.

After assigning some variables we print out user instructions. I used printf instead of echo, to demonstrate some of the formatting options. We could have done the same thing with echo, but if you do a lot of scripting for different distributions you will find that sometimes the echo command can behave differently than expected.

We then use while – done loops to collect user input. We are using one of the variables we defined earlier to contorl the loop. It must be set to a value greater than 1 to exit the loop.

We use an if – fi statement and a regular expression to evaluate user input. If it does not match our input requirements, we send the user a message reminding them what the requirement is, and give them a chance to reenter. We also reset the control variable to zero.

For each of the three user inputs we perform a similar loop test.

Since we only allow four possible calculations, we use a case statement. In a case statesmen we select a variable, then can match on specific patterns, which in turn executes only the specific code for that pattern.

Note that on the last match we use a star (*). This technically can match any pattern, and is a catchall at the end of a case statement. We could have used the divide symbol here. But in practice the last part of a case should be what to do if nothing else matches.

Conclusion

This script introduced while and case, as well as collecting user input. While the code here is a little longer than before, you should be able to follow the flow without any problems.

In our next installment we will look at functions inside a bash script.

Shell or Terminal? Shell Scripting – Part 1

Simple Script Example! Shell Scripting – Part 2

Command Line Arguments! Shell Scripting Part 3

User Input! Shell Scripting Part 4

Using Functions! Shell Scripting Part 5

Variable Odds and Ends! Shell Scripting Part 6

Add New Comment

Your email address will not be published. Required fields are marked *