# Shell Tools

### Objectives

• Discussion of last lesson.
• Shell tool Phone Book, design.
• Lets build the modules.
• Lets tie this all together.
• Lets expand the original Phone Book

Last lesson I asked you to write some shell scripts using regular expression tools. Lets look over your homeworks and discuss them. The idea is to learn by doing. Unix is not a subject for memorization, it requires facility. The best way I know to acquire facility is to use a tool.

### Shell tool Phone Book.

Today we will look at using shell scripts to create a small phone book application. Lets start by outlining the project.

First lets state the goal:
Create a shell program to store names and phone numbers.
Now lets bullet the design ideas.

1. View contents of the phone book.

Display the contents of the phone book preceeding each entry with a line number for easy reference.

2. Add new entries to the phone book.

Alway add the entries to the end of the book.

3. Find specific entries in the book.

Ask the user for a name or number to search for, then find that entry.

4. Delete entries from the book.

Ask the user which line to delete, then remove that line.

OK, now lets do some archetecture design.

The data will be stored in a text file in the following format.

    Name ; phone number

Each entry will be on a separate line terminated by a line feed.

### Lets build the modules

I suggest we start with a script to add entries to the phone book. Here is one I cooked up.

        #!/bin/sh
# Date: Wed Feb 27 18:06:30 EST 2002
# Last Revised: Time-stamp: <2002-02-27 18:45:45 john> maintained by emacs
# =======================================================================

# Ask the user for a name and assign to a variable
echo -n "Name of person: "

# Ask the user for a phone number and assign to a variable
echo -n "Phone number: "

echo "Should I enter the values:"
echo -e "$name ;$phone \n"
echo -n "y/n: "

if [ "$answer" == "y" ] then # Write the values to the address book echo "$name ; $phone" >>$BOOK
else
# Give the user a message
echo "$name ;$phone NOT written to $BOOK" fi exit 0 Now we have the ability to add entries to our book. Next we should build something to list the contents of our book.  #!/bin/sh # File: /home/john/work/bayer/training/list.sh # Date: Wed Feb 27 18:04:46 EST 2002 # Last Revised: Time-stamp: <2002-02-27 18:17:38 john> maintained by emacs # Description: List the entries in the address book with line numbers. # ======================================================================= BOOK="address-book.txt" # Display the format before the entries echo "Line Number: Name ; Phone Number" # Print the book with line numbers and paused with less nl --number-separator=": "$BOOK | less 

Now suppose we want to search the address book to find a specific entry?

        #!/bin/sh
# File: /home/john/work/bayer/training/find.sh
# Date: Wed Feb 27 18:50:13 EST 2002
# Last Revised: Time-stamp: <2002-02-27 18:53:00 john> maintained by emacs
# Description: Find a specific line in the file.
# =======================================================================

# Ask the user what to look for.
echo -n "What person or number are you seeking: "

echo "Name ; Phone number"
grep -i $find$BOOK

Lastly in the tool set, build a tool to delete a specific entry in the phone book.

        #!/bin/sh
# File: /home/john/work/bayer/training/del.sh
# Date: Wed Feb 27 18:21:33 EST 2002
# Last Revised: Time-stamp: <2002-02-27 18:47:49 john> maintained by emacs
# Description: Delete the line specified by the user.
# =======================================================================

# Ask the user which line to delete
echo -n "Which line should I delete: "

# Rename the file before deleting
mv $BOOK boo.txt # Add line numbers and delete against that number nl --number-separator=":" boo.txt | grep -v$number: | awk -F: '{print $2}' | tee$BOOK

### Lets tie this all together

OK, now that we have the individual shell scripts to perform the functions, why not make a master script to call the individual scripts. Here is what I created in the class.

        #!/bin/sh
# File: d:/home/john/tmp/phone.sh
# Date: Thu 28 Feb 2002 10:35:24 Eastern Standard Time
# Last Revised: Time-stamp: <2002-02-28 10:46:15 exmxm> maintained by emacs
# Description: Master script for phone book program
# =======================================================================

exit=0

while [ $exit -ne 1 ] do echo "What operation do you want?" echo -e "add, list, find, del, exit: " read answer if [ "$answer" = "add" ]
then
elif [ "$answer" = "list" ] then ./list.sh elif [ "$answer" = "find" ]
then
./find.sh
elif [ "$answer" = "del" ] then ./del.sh elif [ "$answer" = "exit" ]
then
exit=1
else
echo "I do not understand the command."
fi
done

exit 0

### Lets expand the original Phone Book

OK, we are going to take the original shell scripts for the phone book program and expand them. Lets take a minute and define the improvements wanted.

• Add street, city, state, and zip code to records
• Display the records in a more common format.
• Add the ability to search only specified fields

### New Version of Phone Book

Ok here is a listing of the Design changes to be made. I will then show the code that was produced.

In the phone.sh file, which will be renamed to phone2.sh, clear the screen before printing the user prompt. This will give it a cleaner look. In addition, define the storage file here and not in the individual files.

#!/bin/sh
# File: /dosd/home/john/tmp/phone2.sh
# Date: Wed Mar  6 08:17:29 EST 2002
# Last Revised: Time-stamp: <2002-03-07 09:28:14 john> maintained by emacs
# Description: Master script for phone book program
# Revised for the second version of the phone book.
# =======================================================================

export BOOK

exit=0

while [ $exit -ne 1 ] do clear echo "What operation do you want?" echo -e "add, list, find, del, exit: " read answer if [ "$answer" = "add" ]
then
elif [ "$answer" = "list" ] then ./list2.sh elif [ "$answer" = "find" ]
then
./find2.sh
elif [ "$answer" = "del" ] then ./del2.sh elif [ "$answer" = "exit" ]
then
exit=1
else
echo "I do not understand the command."
sleep 5
fi
done

exit 0

In the add2.sh script, add additional requests for the additional data, street, city, state, and zip. Once the data is entered, display the results in a more normal format. Paying attention to the look of the input and output will make the program seem more professional. At the end of any output, besure to pause for the user to be able to read the output before clearing it.

#!/bin/sh
# Date: Wed Mar  6 08:19:36 EST 2002
# Last Revised: Time-stamp: <2002-03-06 09:03:48 john> maintained by emacs
# Revisied: Modifyed for the second version of phone book
# =======================================================================

# echo "Book = $BOOK" echo -e "\n ======== Beginning Adding Addresses =======\n\n" # Ask the user for a name and assign to a variable echo -n "Name of person: " read name # Ask for the street address echo -n "Street Address: " read street # Ask for the city echo -n "City: " read city # Ask for the state address echo -n "State: " read state # Ask for the zip address echo -n "Zip Code: " read zip # Ask the user for a phone number and assign to a variable echo -n "Phone number: " read phone # Echo the answers and ask for confirmation echo "Should I enter the values:" echo -e "$name \n $street \n$city, $state,$zip \n $phone \n" echo -n "y/n: " read answer # Convert the answer to lower case fixedanswer=echo$answer | tr "A-Z" "a-z";

if [ "$fixedanswer" = "y" ] then # Write the values to the address book echo "$name;$street;$city;$state;$zip;$phone" >>$BOOK
sleep 5
else
# Give the user a message
echo -e " $name \n$street \n $city,$state, $zip \n$phone \n NOT written to $BOOK" sleep 5 fi exit 0 In the file list2.sh, provide a more normal display showing the output in a more natural format. Pass the user information on how to end the display and return to the top level program. #!/bin/sh # File: /home/john/work/bayer/training/list.sh # Date: Wed Feb 27 18:04:46 EST 2002 # Last Revised: Time-stamp: <2002-03-06 09:07:04 john> maintained by emacs # Description: List the entries in the address book with line numbers. # ======================================================================= # Read each line in the book and display (awk -F ";" '{printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n==========================\n\n", NR,$1, $2,$3, $4,$5, $6}'$BOOK ; echo "Press Q to Quit and return to the menu." ) | less

# Display the format before the entries
#echo "Line Number:   Name  ;  Phone Number"

# Print the book with line numbers and paused with less
#nl --number-separator=":    " $BOOK | less  In the find2.sh script, allow the user to select which field to search, and what to search for. When the result is found, format the output before displaying. #!/bin/sh # File: /dosd/home/john/tmp/find2.sh # Date: Wed Mar 6 09:07:47 EST 2002 # Last Revised: Time-stamp: <2002-03-07 09:30:03 john> maintained by emacs # Description: Find a specific line in the file. # Revised for a more complex search capability # ======================================================================= # Ask the user what to look for. echo -n -e "What field would you like to search: \n\tname, street, city, state, zip, or phone: " read field echo -n "In the field = \"$field\", what string should I find? "

# Find the string in the selected field
case $field in "name" ) # Search for a specific name awk -v var=$string -F ";" '$1 ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR,$1, $2,$3, $4,$5, $6}'$BOOK | less
# result=awk -F ";" '{printf "%d: %s\n", NR, $1}'$BOOK | grep -i $string | \ #awk -F ":" '{print$1}'
;;

"street" ) # Search for a specific name
awk -v var=$string -F ";" '$2 ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR, $1,$2, $3,$4, $5,$6}' $BOOK | less ;; "city" ) # Search for a specific name awk -v var=$string -F ";" '$3 ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR,$1, $2,$3, $4,$5, $6}'$BOOK | less
;;

"state" ) # Search for a specific name
awk -v var=$string -F ";" '$4 ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR, $1,$2, $3,$4, $5,$6}' $BOOK | less ;; "zip" ) # Search for a specific name awk -v var=$string -F ";" '$5 ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR,$1, $2,$3, $4,$5, $6}'$BOOK | less
;;

"phone" ) # Search for a specific name
awk -v var=$string -F ";" '$6 ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR, $1,$2, $3,$4, $5,$6}' $BOOK | less ;; "*" ) # Search pattern not recognized echo "I did not understand your field name"; ;; esac # echo "Result =$result";

# if [ "$result" != "" ] # then # for number in$result
#     do
#        awk -v val=$number -F ";" 'NR == val {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR,$1, $2,$3, $4,$5, $6}'$BOOK
#     done
# else
#     echo "Did not find $string in$field"
# fi

# echo "Past Case"
# sleep 5;

exit 0

Finally in the del2.sh script, the only change is the remove the reference to the storage location.

#!/bin/sh
# File: /home/john/work/bayer/training/del2.sh
# Date: Wed Feb 27 18:21:33 EST 2002
# Last Revised: Time-stamp: <2002-03-07 18:15:04 john> maintained by emacs
# Description: Delete the line specified by the user.
# =======================================================================

# Ask the user which line to delete
echo -n "Which line should I delete: "

# Display the record selected
awk -v var=$number -F ";" 'NR ~ var {printf "Record: %d\n\t%s\n\t%s\n\t%s, %s, %s\n\t%s\n", NR,$1, $2,$3, $4,$5, $6}'$BOOK

# Ask the user if this is correct before deleting.
echo -n "Is this the correct record to delete? (y/n): "

# Lower case the answer and check
fixedanswer=echo $answer | tr "A-Z" "a-z"; if [ "$fixedanswer" = "y" ]
then

# Rename the file before deleting
mv $BOOK boo.txt # Add line numbers and delete against that number nl --number-format=rz --number-separator=":" boo.txt | grep -v 0$number: | awk -F: '{print $2}' | tee$BOOK

else

echo "Did not delete the record"
sleep 5

fi

### Home Work

This week I would like you to extract the scripts displayed above. Place them in a local directory and see if you can improve them. Try making changes to see what happens. One of the best ways to learn about something is to try modifying it.

No, this phone book is not a replacement for a real phone book program. But in the same vane, once you start to learn the possibilities of scripts, you will understand one of the most misunderstood parts of computing. Let the computer do the repetative tasks for you. One of the original uses of computers was Batch Processing. By teaching the computer to perform tasks for you, you gain the ability to have it be a real helper, not just a word processor and a game machine.

Written by John F. Moore

Last Revised: Wed Oct 18 11:01:31 EDT 2017