Reference no: EM133140289
Goal
The main purpose of this practical is to give you further familiarity with UNIX shell scripts.
1. UNIX Shell Scripting
1.2 Hands on exercises:
A Create a script named emp3.sh, with the following content:
#! /bin/sh
echo -e "Enter the pattern to be searched: \c" read pname
echo -e "Searching for $pname\n"
if grep "$pname" e.lst; then
echo "Pattern found in e.lst" elif grep "$pname" f.lst; then
echo "Pattern found in f.lst" else echo "Pattern not found"
fi
Save the script. Assign execute permission to the script.
B Create a text file named e.lst, with the following content:
2000, John Warren, NSW 2001, Adam Davis, NSW 3000, John Smith, ACT
Create a text file named f.lst, with the following content:
2000, Jack Williams, NSW 2001, Adam Davis, NSW
3000, Jack Swan, ACT
C Ensure that your emp3.sh, e.lst, and f.lst are all stored under the current directory. Then run the emp3.sh script by specifying the pattern as John, Jack, and Andrew, respectively.
Observe the outputs and ensure that they are correctly generated.
2. UNIX Shell Scripting - test
The test command uses certain operators to evaluate a condition and returns either a true or false
exit status - which can then used by if for making decisions. It works in three ways:
• Compare two numbers
• Compares two strings or a single string for a null value (the empty string, "")
• Checks a file's attributes
The test command does not display any output but simply returns a value that sets the exit status variable $?.
In addition to the test command, some other syntax is very useful for strings:
Determining the size of a string
• Method 1: Assign the string to a variable, then use ${#variableName}
e.g. 1
e.g. 2
$ s1="someString"; theSize=${#s1}
$ echo $theSize 10
$ mystring="this is the test"
$ echo ${#mystring} 16
• Method 2: Assign the string to a variable, use the length keyword for the expr command
See the expr command in section 4.1
e.g.
$ s1="someString"; theSize=`expr length "$s1"` note the use of backquotes (`) here
$ echo $theSize 10
• Method 3: Use the echo command in combination with wc e.g
$ s1="someString"
$ theSize=`echo -n "$s1" | wc -m` -n suppresses adding a new line, -m counts characters
$ echo $theSize 10
Determining a character in a specific position in a string
A string is just a sequence of characters, one after the other, numbered from position 0 (left to right). One or more characters can be determined from the following syntax:
Syntax: ${varname:position:count} the $ here is not the prompt, it is required
e.g
e.g
e.g
Start from where? How many characters?
$ s1="someString"
$ someChar=${s1:3:1}
$ echo $someChar e
$ s1="someString"
$ someChar=${s1:4:3}
$ echo $someChar Str
$ s1="someString"; start=1; num=4
$ someChar=${s1:start:num}
$ echo $someChar omeS
Note the variable names inside the ${} do not need to be prefixed by '
e.g. num and not $num
Hands on exercises:
A Perform the following actions on your shell. For each command line, the first $ is the shell prompt. Remember $? has the value of 0 if the command succeeds, and a non-zero (normally 1 or 2) value if it fails.
$ x=5; y=7; z=8
$ test $x -eq $y; echo $?
$ test $x -lt $y; echo $?
$ test $z -gt $y; echo $?
$ test $z -eq $y; echo $?
B Try to understand the following statements:
if test $# -ne 3; then
echo "You did not enter three arguments" else
echo "You entered the right number" fi
Remember from a previous tutorial that, $# refers to the number of arguments in a command line.
C Repeat step A by changing the test commands to []:
$ [ $x -eq $y ]; echo $?
$ [ $x -lt $y ]; echo $?
$ [ $z -gt $y ]; echo $?
$ [ $z -eq $y ]; echo $?
D The above examples show how to compare numbers on a UNIX shell. The following example demonstrates how to compare strings.
Create the following script and name it as compile.sh: #! /bin/sh
if [ $# -eq 1 ]; then
if [ $1 = "j" ]; then
file=`ls -t *.java | head -1`
echo -e "The last modified Java file is $file\n" elif [ $1 = "c" ]; then
file=`ls -t *.c | head -1`
echo -e "The last modified C file is $file\n" else
echo "Invalid file type"
fi else
echo -e "Usage: $0 file_type\nValid file types are c and j"
fi
This script stores the last modified C or Java program filename in the variable file. It then displays the file name. You have to provide one argument to the script - the file type, which must be c (for C program) or j (for Java program). If a user does not enter a file type or enters a file type which is neither c nor j, then the script usage information is displayed. The usage information shows the correct way to run a script.
Remember from last week's tutorial that, a shell script can read in command-line arguments. The first argument is referred to as $1, the second argument is referred to as $2, and so on. $0 refers to the script file name. $# refers to the number of arguments in the command line.
The ls with option -t displays file names by modification time. The last modified file is displayed first. The head -1 (digit one, not ell) gets the file name listed at the top (or in the beginning).
E Prepare some testing C and Java files before you attempt to run this script. Following exercises in the previous section, make a copy of e.lst and name it as t1.c. Make a copy of f.lst and name it as p1.java. Make a copy of t1.c and name it as t2.c. Make a copy of p1.java and
name it as p2.java.
F Assign execute permission to compile.sh. Run the script as follows. Ensure that you understand the outputs.
$ ./compile.sh
$ ./compile.sh k
$ ./compile.sh c
$ ./compile.sh j
G Create a script named emp4.sh, with the following content:
if [ -f $1 ]; then echo "File exists"
else
echo "File does not exist"
fi
Save it. Assign execute permission to it.
H Run the script as follows:
$ emp4.sh t1.c
$ emp4.sh t2.c
$ emp4.sh t3.c
I Modify the content of emp4.sh, so that it becomes the following:
if [ ! -f $1 ]; then
echo "File does not exist" elif [ ! -r $1 ]; then
echo "File is not readable" elif [ ! -w $1 ]; then
echo "File is not writable" else
echo "File is readable and writable"
fi
? Note: ! reverses a condition (it is the equivalent to not)
• [ ! -f $1 ] is true if the ordinary file $1 does NOT exist.
• [ ! -r $1 ] is true if the file $1 is NOT readable
• [ ! -w $1 ] is true if the file $1 is NOT writable
• [ ! -x $1 ] is true if the file $1 is NOT executable
J Run the script again as follows:
$ emp4.sh t1.c
$ emp4.sh t2.c
$ emp4.sh t3.c
K Remove the read permission of t1.c and the write permission of t2.c, and then run the above command lines again to observe the outputs.
3. UNIX Shell Scripting - The case conditional
3.1 Hands on exercises
A Remove all the temporary C or Java files from your current directory. Create a scrip which is named emp5.sh, with the following content:
#! /bin/sh tput clear
echo -e "\n 1. Find files modified in last 24 hours" echo -e "\n 2. The free disk space"
echo -e "\n 3. Space consumed by this user" echo -e "\n 4. Exit\n\n"
echo -e "SELECTION: \c"
read choice case $choice in
1) find $HOME -mtime -1 -print ;;
2) df ;;
3) du -s $HOME ;;
4) exit ;;
*) echo "Invalid option" ;;
esac
Here the first 4 echo commands generate a menu. The 5th echo prompts the user to make a selection (which needs to be a number in the range of 1 - 4, inclusive). Depending on the user's selection (which is stored in the variable choice), a corresponding command line is run. If the user's selection is a character other than 1, 2, 3, 4, then the message "Invalid option" is displayed.
B Run emp5.sh, and enter a number in the range of 1 - 4 (inclusive) to observe its output. Run the script again by entering another number. Also try to enter a number which is not in the
range (such as 5) to see the output.
C The case conditional is able to match multiple patterns or using wild cards as described in previous tutorials. Add the following statements to the end of emp5.sh:
echo -e "Wish to continue? (y/n): \c" read answer
case $answer in
Y|y) echo -e "I will do something later\n"
;;
N|n) echo "OK, no longer continuing!" exit
;;
*) echo "Invalid option" ;;
esac
Here Y|y matches Y or y, N|n matches N or n. Save the change and run emp5.sh again.
D You can also use wildcards in case conditional:
echo -e "Wish to continue? (y/n): \c" read answer
case $answer in
[Yy][Ee]*) ;; # matches YES, yes, Yes, etc
[Nn][Oo]) exit ;; # matches NO, No, no, nO
*) echo "Invalid option" ;; esac
4. Arithmetic expressions and the sleep command
4.1.1 Hands on exercises
A Run the following command line to see the effect of sleep.
$ sleep 3; echo "3 seconds have elapsed"
B Try the following arithmetic operations:
$ expr 3 + 5
$ x=3; y=5
$ expr $x - $y
$ expr 3 \* 5
$ expr $y / $x
$ expr $x % $y
The operators (+, -, *, /, %) must be enclosed on both sides by whitespace.
? Note: The expr command only handles integers.
In the 4th command line above, why is there a \ character required before *? The most common use of expr is for incrementing the value of a variable e.g.:
$ x=5
$ x=`expr $x + 1` (note the back-quotes)
$ echo $x
$ x=5; y=2; z=`expr $x + $y` (note the back-quotes)
Double parentheses
The double parentheses (( and )) are also often used to perform basic arithmetic (think of them as a shortcut for the expr command, although there are some differences).
e.g.
$ x=3; y=5
$ echo $(( $x + $y ))
$ z=$(( $x * $y )) (note the * does not need to be escaped here!)
5. UNIX Shell Scripting - Looping
Like in C or Java programming, loops (or iteration) allow you to perform a set of instructions repeatedly - repeating a block of commands over and over again either until some condition is no longer true (the while loop), or repeating commands for each item in a sequence (the for loop - next week).
Hands on exercises
A Under your kit501 directory, make a new directory named Looping. Change into this new directory.
B Create a shell script which is named as colour.sh, with the following content:
echo "Guess my favourite colour: " read guess
while [ "$guess" != "red" ] do
echo "No, not that one. Try again." read guess
done
echo "Well done"
Here the read command stores the user input into variable guess. As long as the user input is not "red", the loop body is entered, which displays a message and then prompts the user to enter a guess again. By the time the user input is "red" (has guessed correctly), the loop is broken and exited.
Assign execute permission to the script, and run it. To break the loop, you have to enter "red". Alternatively, you can press CTRL-C to stop.
C Copy the script emp5.sh into the current Looping folder. The script is from a previous section of this tutorial. Rename emp5.sh as emp6.sh. Modify the exiting content of emp6.sh so that its new content are as follows (note the -mtime option for find here is -1 (minus one)):
#! /bin/sh tput clear
answer=y
while [ $answer = y ] do
echo -e "\n 1. Find files modified in last 24 hours" echo -e "\n 2. The free disk space"
echo -e "\n 3. Space consumed by this user" echo -e "\n 4. Exit\n\n"
echo -e "SELECTION: \c"
read choice case $choice in
1) find $HOME -mtime -1 -print ;;
2) df ;;
3) du -s $HOME ;;
4) exit ;;
*) echo "Invalid option" ;; esac
done
Note the use of a variable named answer which is used to control the loop. Run the script. Can you see the purpose of the loop for this script?
D The above script needs to be terminated by entering 4 as the user input (or pressing CTRL-C). Another way to control a loop is to use the continue command and the break command.
• break: break out of the current loop
• continue: start the current loop again
Add the following statements to the end of the loop body in emp6.sh (ie, between the esac
line and the done line):
echo -e "Wish to continue? (y/n): \c" read answer2
case $answer2 in [yY]) continue ;;
*) break ;; esac
Save the change and run emp6.sh again.
E Sometimes it is necessary to set up an infinite loop. The following is such an example:
while true do
echo "message repeated every 2 seconds" sleep 2
done
Use the above statements to make a new script named emp7.sh. Assign execute permission to it. Run the script. You have to press CTRL-C to stop it.
An infinite loop can be used for more useful purposes, eg, a system administrator can set up an infinite loop to monitor the available space in disks every few minutes.
F What does the following program do? while [ ! -r invoice.lst ] do
sleep 30 done
echo "That file can be read now!"
Attachment:- UNIX shell scripts.rar