UNIX Bourne Shell Scripting (an Introduction)
Purpose
The purpose of this lab is to familiarise you with the basics of Bourne shell scripting. There are
various scripts included in this material which illustrate the points being made, and which you can
copy into a file and run to see what they do. At the end of this file are some exercises which test
your knowledge of shell scripting.
In shell scripting the Bourne shell (sh) and its extension the Bourne again shell (Bash) are very
similar. On robin, type
sh or /bin/sh
to invoke the Bourne shell. (To invoke Bash, type bash)
References
Bourne Shell Programming: http://www.ooblick.com/text/sh/
Steve Bourne's original shell tutorial: http://partmaps.org/era/unix/shell.html
Calling external programs / Exit status and Return code
Chaining. First, note that by convention C programs return a 0 to indicate successful exit
status, e.g.,
PROGRAM: code.c
#include
int main(int argc, char *argv[]) {
printf("Hello World!\n");
return 0;
}
This C hello program can be tested by running:
gcc -o out code.c
and then run with:
./out
after calling out use this command to get the exit code:
echo $?
Try changing the return value in the C program to 10, recompile, run, and finally output the
return code
Hello World!
Add the following to hello.sh.
#!/bin/sh
echo Hello World!
You must have execute permission on this script in order to run it. Make the file executable by
typing the following at the command prompt and hitting return:
$ chmod u+x hello.sh
You can then run the file as follows:
$./hello.sh
Hello World!
Command-line arguments and variables
The Command-line parameters provide scripts with a way to access data from the shell. These
reserved parameter variables start with the name of the script, $0, and are assigned by position for
each argument $i. The number of parameters is set in $#. The script below simply prints its first
two arguments:
#!/bin/sh
echo $1
echo $2
The example below shows how the programmer can define variables. The variable $string is
assigned the value '' argument 1: '' and then concatenated to the command-line parameter $1. Copy
the text into a file and call it hello2.sh:
#!/bin/sh
string="The argument 1 is: "
echo $string$1 #concatenate $string with $1
The script prints out its first command-line argument.
$ ./hello2.sh "Hello World!"
The argument 1 is: Hello World!
With regard to user-defined variables (like $string in the above example), NOTE the following:
Variables can simply be used without any explicit introduction;
Changes to variables within a script are not visible outside the script, e.g.:
$ string="original string"
$ ./hello2.sh “Hello World!”
argument 1: Hello World!
$ echo $string
original string
The export command makes variables visible to subscripts, but not outer scripts, e.g.
suppose script s1.sh uses the variable $STR:
$ export STR="original string"
$ ./s1.sh # s1.sh will see STR="original string"
There are various built-in variables set by the shell, for example, PATH, HOME, etc.
Input/Output
Bash has several interactive commands. echo command allow users to print a string of characters.
read command could be used to read a string from the keyboard and assigns it to one or more
variables. While printf command prints out a formatted string of characters.
Type in the follow fragment into a text file and save it as read.sh
#!/bin/sh
echo -n "Please type in your first and last name: "
read firstname lastname
echo "Hello ${firstname}(fn) ${lastname}(ln)“
Now execute the above script, it will prompt you to type in your first name and last name. Type in
your first name and last them and then press carriage return. What do you get? What output do you
get when you type in your first name only? What do you get when you type in your first name,
middle name, and last name?
Now edit the script and remove –n option in the first echo command, did you notice any
differences?
printf is a powerful string formatting command. Copy the following script in to a file and
execute it. You may also try other format options that are listed in the lecture slides.
#!/bin/sh
avgmark=65.765
fname=“Ruibin”
lname=“Bai”
printf “Hello %10s, %-10s, average=%7.2f\n” $fname $lname $avgmark
Conditionals
There are several forms for conditionals, the simplest of which uses if statements. This script tests
to see if there is more than one command-line argument:
#!/bin/sh
MIN_ARGS=1
if [ "$#" -gt "$MIN_ARGS" ]; then
echo more than one command line argument is present
else
echo Fail
fi
The following script tests to see if FILE exists and if it is a “regular file” (i.e. one that is neither a
directory nor device file):
#!/bin/sh
FILE="fifo"
if [ -f $FILE ]
then
echo FILE fifo is a regular file
fi
The appendix at the end of this lab gives some further test conditions that can be used in if
statements.
Looping
Loops are useful in shell scripting and have several forms. This script prints three strings:
#!/bin/sh
for num in one two three
do
echo $num
done
When run, it outputs:
one
two
three
This example prints out a directory listing:
#!/bin/sh
for val in $( ls )
do
echo “item: $val”
done
Try copying this script into a file and running it. What do you get?
C-style loops are also available.
#!/bin/sh
UB=3
for (( i=1; i
do
echo item: $i
done
When run it outputs:
item: 1
item: 2
The while loop is also available:
#!/bin/sh
i=1
LIM=3
while [ "$i" -lt "$LIM" ]
do
echo item: $i
(( i++ ))
done
When run this outputs:
item: 1
item: 2
Arithmetic operations
Performing arithmetic in a shell script does not work as expected. E.g., if you did the following:
$ x=1+2
$ echo $x
you would get the result:
1+2
Instead, use the double parenthesis to perform arithmetic:
$ ii=1
$ (( jj=$ii+1 ))
$ echo $jj
2
Appendix
This section shows different test operations that can be done within IF statements in shell scripts.
“num1”, “num2”, “string” and “FILE” are numbers strings and files respectively:
string1 = string2 string 1 is equal to string 2
string1 !=string2 string 1 is not equal to string 2
-n string string is not zero length
-z string string is zero length
-d FILE FILE is a directory
-e FILE FILE exists
-f FILE FILE exists and is a regular file
-r FILE FILE exists and is readable
-s FILE FILE exists and has length greater than zero
-w FILE FILE exists and is writable
-x FILE FILE exists and is executable
num1 -eq num2 num1 equal to num2
num1 -ne num2 num1 not equal to num2
num1 -lt num2 num1 less than num2
num1 -le num2 num1 less than or equal to num2
num1 -gt num2 num1 greater than num2
num1 -ge num2 num1 greater than or equal to num2
Dostları ilə paylaş: |