UNIX Shell Scripting Looping

Looping

While Loop

The while statement is used when you want to loop while a statement is true. This is the same in many other programming and scripting languages. The body of the loop is put between do and done. Suppose that we want to write a script to have the user guess what number we are thinking of. The best way to use this would be to use a while loop.

#!/bin/sh
# Guess the number game.

ANSWER=5          # The correct answer
CORRECT=false     # The correct flag

while [ "$CORRECT" != "true" ]
do
        # Ask the user for the number...
        echo "Guess a number between 1 and 10. "
        read NUM

        # Validate the input...
        if [ "$NUM" -lt 1 ] || [ "$NUM" -gt 10 ]; then
                echo "The number must be between 1 and 10!"
        elif [ "$NUM" -eq "$ANSWER" ]; then
                echo "You got the answer correct!"
                CORRECT=true
        else
                echo "Sorry, incorrect."
        fi
done

You can also loop while reading a variable to make the code simpler. Let’s try the above example revised:

#!/bin/sh
# Guess the number game.  Version 2.0

ANSWER=5          # The correct answer

echo "Guess a number between 1 and 10. "

while read NUM
do
        # Validate the input...
        if [ "$NUM" -lt 1 ] || [ "$NUM" -gt 10 ]; then
                echo "The number must be between 1 and 10! Guess again. "
        elif [ "$NUM" -eq "$ANSWER" ]; then
                echo "You got the answer correct!"
                exit
        else
                echo "Incorrect, guess again. "
        fi
done

Another way to loop forever is to use the : in your while statement. Let’s write a simple program that will print out how long it has been running until the user presses Ctrl+C to terminate the program.

#!/bin/sh

COUNTER=0

while :
do
	sleep 1
	COUNTER=`expr $COUNTER + 1`
	echo "Program has been running for $COUNTER seconds..."
done

This program will loop until the user presses Ctrl+C. Notice that we use something else new here. The unix expr command is used to evaluate a mathematical expression. If you want to increment a variable, this is the command that you will use.

For Loop

The for statement is used when you want to loop through a list of items. The body of the loop is put between do and done. Let’s say that we want to write a program that will validate numbers in a given list. These numbers can be loaded from a file, hard coded, or manually entered by the user. For our example, we will ask the user for a list of numbers separated with spaces. We will validate each number and make sure that it is between 1 and 100. The best way to write a program like this would be to use a for loop.

#!/bin/sh
# Validate numbers...

echo "Please enter a list of numbers between 1 and 100. "
read NUMBERS

for NUM in $NUMBERS
do
	if [ "$NUM" -lt 1 ] || [ "$NUM" -gt 100 ]; then
		echo "Invalid Number ($NUM) - Must be between 1 and 100!"
	else
		echo "$NUM is valid."
	fi
done

Notice that we give the for statement a variable “NUM”, this can be whatever variable name you want to use. It will loop through each item in the given variable (in this case $NUMBERS) and put that item in the $NUM variable. Run the file and give it the input “1 4 3 55 48 120 1000 4 1” and you will have the following output:

Please enter a list of numbers between 1 and 100.
1 4 3 55 48 120 1000 4 1
1 is valid.
4 is valid.
3 is valid.
55 is valid.
48 is valid.
Invalid Number (120) - Must be between 1 and 100!
Invalid Number (1000) - Must be between 1 and 100!
4 is valid.
1 is valid.

Shell Scripting Variables

Variables

Variables are an important part of any program or script. A variable is a simple way to refer to a chunk of data in memory that can be modified. A variable in a unix script can be assigned any type of value, such as a text string or a number. In unix to create a variable, we simply put in our script:

VARIABLE_NAME=value

Note that we do not have to put the variable name in uppercase, but it is the standard way of naming variables in unix. The text “VARIABLE_NAME” can be anything you want, as long as it only contains numbers, letters and/or an underscore “_”. A variable name also cannot start with a number. After the equal sign you put the value, there must be no space between the variable name and the equal sign. To use the variable, we simply put a dollar sign “$” before the name of the variable in our script code. Let’s revise our original script to use the two words in two variables as such:

#!/bin/sh
# This is my second script.
VAR_1=Hello
VAR_2=Unix

echo "$VAR_1 $VAR_2"

This gives the same output as the original script but uses two variables. This is not a very exciting use of variable I will admit, let’s try something more interesting. Let’s write a program that will open a file and read the head and tail of it. This can be useful if you want to see the first items in your log and the last items in your log but you don’t want to see the whole log file, which could be very large. To write this program, we will make use of the unix commands head and tail. Our script will use a predefined varible called $1. This variable will display the first item in the list of command line arguments to your script. You can also access any other command line argument from $1 to $9. You can also use the variable $@ to access all of the command line arguments in a single variable.

#!/bin/sh
# This program will print the head and 
# tail of a file
# passed in on the command line.

echo "Printing head of $1..."
head $1

echo ""  #this prints an extra return...
echo "Printing tail of $1..."
tail $1

Give this program a name of ht.sh (for Head Tail shell script), be sure to give it execute permission and then run it with the following command:

./ht.sh WEB_LOG

The parameter WEB_LOG must point to an actual text file on your system, it will open the file and print the head and tail. Now let’s assume that we want the user to be able to input the file name after the script has been run. We can read input from the console by using the unix read command. Let’s modify the program and try it again:

#!/bin/sh
# This program will read the filename 
# from user input.

echo "Enter the file: "
read FILENAME
echo "Printing head of $FILENAME..."
head $FILENAME

echo ""  #this prints an extra return...
echo "Printing tail of $FILENAME..."
tail $FILENAME

This way of printing a variable does have limitations, for instance you cannot print text without a space after the variable name. Suppose that we want to create a script that will read the head and tail of the file as before, but we know that the user will always be using files that end with “_LOG”. If we tried to open the file $FILENAME_LOG, then it would look for a variable with that specific name and not a file named $FILENAME + _LOG. We can fix this by using another way of displaying and using a variable. We use the format ${VARIABLE_NAME}. Let’s modify our program again to automatically append “_LOG” to the end of the filename for our users:

#!/bin/sh
# This program will read the filename 
# from user input.

echo "Enter the file: "
read FILENAME
echo "Printing head of ${FILENAME}_LOG..."
head ${FILENAME}_LOG

echo ""  #this prints an extra return...
echo "Printing tail of ${FILENAME}_LOG..."
tail ${FILENAME}_LOG

Now if you run the script with the command ./ht.sh WEB it will open the file “WEB_LOG” for the user.

UNIX Shell Scripting Tutorial

The first script that we will use will be a simple script that will output the text “Hello Unix”. I would suggest using vi to create and edit the file. To create and edit the file, run the following command:

Show Code

vi hello.sh

If you don’t know how to use vi, I would suggest that you read a quick tutorial by searching for “vi tutorial” with the search bar above. To enter input mode in vi, press “i”. Now, for the code in this first script, enter the following code in the file:

Show Code

#!/bin/sh
# This is my first script. 

echo "Hello Unix"

Now save the file and close it by hitting Escape followed by “:wq” and Return. The first line of the file tells unix which shell to use to execute the file. /bin/sh is the default location for the bourne shell. In Linux this will normally point to the bourne again shell, which is a remake of the original unix shell and works pretty much the same. The second line of the file is just a simple comment. Comments are ignored by the shell interpreter but are very useful when developing large and complex scripts. Everyone forgets what their original logic or intention was when coding a script and it’s much easier to read a comment than it is to try to understand large and complex sections of code. Before we can run this script, we must first make it executable. To do this we will use the unix chmod command:

chmod u+x hello.sh

Now our script is executable. This command basically tells unix to set the x (executable) flag for the user level access of the file. Now we are able to run the file. If you don’t have “.” in your unix PATH environment variable, then you will need to proceed the name of the script with “./” to execute it. It is generally considered to be a security risk to put “.” in your PATH evironment variable, so we will assume that you don’t have it. Now you can execute your script by using the following command:

./hello.sh

You will see the text “Hello Unix” output to the console, congratulations, you have created your first unix script! Now you can move on to the next topic where we will discuss using variables in a unix script.