Introduction
The Shell is a hard casing that provides a friendly environment to the user, while protecting each user from every other one. When a user logs into a Unix system, the operating system automatically starts a unique copy of the Shell under which the user can perform any of the functions available. The original Unix shell was rewritten by S.R.Bourne in 1975, giving us the current version of the shell known as the Bourne Shell. Students and professors at the Berkeley campus created another version of the Shell, known as the C Shell, that is useful for C language programmers. Later another shell called the T shell (tcsh) was developed, which is an enhanced but completely compatible version of the Berkeley Unix C shell. There are some new features in the T shell which are not present in the C shell. A shell is basically a command line interpretor. It takes commands and executes them. As such, it implements a programming language, called the Shell Script Language. Programs that are interpreted/executed by the shell are called Shell Scripts.
There are several on-line tutorials on shell script languages.
For C Shell :
http://www.eng.hawaii.edu/Tutor/csh.html
For T Shell:
For Bourne Shell:
http://207.213.123.70/book
http://unixhelp.ed.ac.uk/scrpt/scrpt2.html
http://theory.uwinnipeg.ca/UNIXhelp/shell/shell_help.html
The Linux machines at NMSU CS Department have both the Bourne shell and the T shell. So, users can program in any one of the shells.
You can check to see what shell you are running by typing
env
| grep SHELL at the command line, and by looking at the very
last name in the path given.
The output will look something like:
anson:[13] env | grep SHELL
SHELL=/local/common/bin/tcsh
anson:[14]
which shows that the shell that I am running is T Shell.
How to run Shell Script
Since shell script is basically a command line interpreter, it is easier to write several commands in a file and make the file executable to execute them simultaneously, instead of writing them one at a time on the command line to execute them. First of all you have to prepare a text file that contains the shell script. If you choose to run the script as an executable file, you must add the following line to the very beginning of your script file:
#!/bin/sh
if you want to run it in Bourne shell, or
#!/bin/tcsh or
#!/bin/csh
if you want to run it in Tshell (which is very similar to the C shell)
or C shell. In the NMSU CS Department environment, both
tcsh
and
csh
will execute the script in T shell.
Note: If the above line doesn't start from the first column of the line, then the line doesn't get executed and the script is considered to be the default shell, in this case T shell script.
Then set execute permissions to your script file using the following command:
chmod u+x my_file
Then call your script file directly in the command line as:
my_file
This is the sequence in which you should type in the commands:
anson:[11] chmod u+x my_file
anson:[12] my_file
intro.ps
my_file
test
anson:[13]
The program my_file outputs the name of all the files my directory that has been modified/written in the month of September:
#!/bin/sh
for file in *
do
mon=`ls -l $file|cut -c43-45`
if [ "$mon" = "Sep" ]
then
echo $file
fi
done
Bourne shell
max=0
this assigns
0 to the variable max. Notice that
no spaces are allowed around the equality symbol.
max=$linecount
this assigns the value stored in the variable linecount
to the variable
max. In order to
access the value of a variable , you precede the variable name with a dollar
sign($).
Notice that both linecount
and max are variables, but since
0 or the value of linecount is
getting assigned to the variable max,
the '$' sign is not added to its
beginning, otherwise all variables are identified by the '$'
sign before them.
Also, note that each of
the assignment operators should be written in a seperate line.
if [ test condition ]
then
process 1
else
process 2
fi
where the test conditions are the conditions you are checking for before deciding whether you have to execute process 1 or process 2. If you want the default processing path to do nothing, you can just write the if condition without the else part as:
if [ test condition ]
then
process 1
fi
Note that
the test conditions are conditions constructed from variables, operators
and constants and they should be enclosed in square brackets. The test
conditions can contain operators. Some of the Arithmetic Test Operators
are as follows:
-lt : less than
-le : less than or equal
-gt : greater than
-ge : greater than or equal
-ne : not equal
-eq : equal
For example:
if [ $linecount -gt $max ]
then
echo "the end"
else
echo $linecount
fi
Note that
the '$' is not used on the loop
variable, but it is used on the variable inside the loop.
An example of the
for
loop is given below:
for
file in *
do
echo $file
done
This prints out the filenames of all the files that exist in the current directory (the '*' refers to current directory). The output after executing the above for loop is as follows:
singapore:[20]
my_forloop
intro.ps
my_file
test
my_forloop
singapore:[21]
For example:
echo $max
This
prints the value of the variable max on
the screen.
Notice
the usage of back quotes around the unix command. The back quotation marks(`)
are used when you want to use the results of a command in another command.
. For example, if you want to set the value of the variable contents
equal to the list of files in the current directory, type the followingcommand:
contents=`ls`
Here is an usage of the wc command on the command line itself:
anson:[15]
wc -l my_file
11 my_file
anson:[16]
where the first argument is the number of lines in the file, and the second is the name of the file; i.e. the file my_file consists of 11 lines.
In order to seperate out the number of lines from the wc command output, you can use awk in conjunction with wc.
linecount=`wc -l my_file | awk '{print $1}'`
This
assigns to the variable linecount,
the number of lines in the filename
my_file.
Notice that the awk
command parameter is in regular quotes, while the unix commands are in
back quotes.
T shell
There are some differences in the syntax between the T shell script and the Bourne shell script .
set max=0
this assigns 0 to the variable max. Notice that no spaces are allowed around the equality symbol.
set max=$linecount
this
assigns the value stored in the variable linecount
to the variable
max.
Notice that both linecount
and max are variables, but since
0 or the value of linecount is
getting assigned to the variable max,
the '$' sign is not added to its
beginning, otherwise all variables are identified by the '$'
sign before them.
Also, note that each of
the assignment operators should be written in a seperate line.
if ( condition ) then
statements
endif
The typical if-then-elsestatement
looks like this:
if ( test condition )
then
process 1
else
process 2
endif
where the test conditions are the conditions you are checking for before deciding whether you have to execute process 1 or process 2. If you want the default processing path to do nothing, you can just write the if condition without the else part as:
if ( test condition )
then
process 1
endif
Note that the test conditions
are conditions constructed from variables, operators and constants and
they should be enclosed in ordinary round brackets. The test conditions
can contain operators. Some of the Arithmetic Test Operators are as follows:
< : less than
<= : less than or equal
> : greater than
>= : greater than or equal
!= : not equal
== : equal
For example:
if ( $linecount > $max ) then
echo "the end"
else
echo $linecount
endif
foreach
variable ( value1 )
repeat action on $variable
end
Note that
the '$' is not used on the loop
variable, but it is used on the variable inside the loop.
An example of the
for
loop is given below:
foreach
file (*.c)
echo $file
end
This prints out the filenames of all files in the current directory with *.c extension. The output after executing the above foreach loop is as follows:
singapore:[20]
my_foreachloop
test1.c
test2.c
singapore:[21]
For example
echo $max $name
This prints the value of the variable max
and name on the screen. Note that
if the
echo command is the last
command in the script file, sometimes it doesn't print on the standard
output because of buffering. To fix it, put an additional echo
command
at the end of the script file.
Notice the usage of back quotes around the unix command.
Here is an usage of the wc command on the command line itself:
anson:[15]
wc -l my_file
11 my_file
anson:[16]
where the first argument is the number of lines in the file, and the second is the name of the file; i.e. the file my_file consists of 11 lines.
In order to seperate out the number of lines from the wc command output, you can use awk in conjunction with wc.
linecount=`wc -l my_file | awk '{print $1}'`
This assigns to the variable linecount, the number of lines in the filename my_file.
Here is an usage of wc in conjunction with awk on the command line itself:
anson:[17]
wc -l my_file | awk '{print $1}'
11
anson:[18]
Notice
that the awk command parameter
is in regular quotes, while the unix commands are in back quotes.
Homework Assignment (10 points)
Write a t shell or Bourne shell script to find out the C/C++ header file from all header files (*.h) in /usr/include ( by the way, this is the default include library for the gcc compiler. If you have any problems with include files, you can check them out in this library) with the biggest and the smallest number of lines.
Print out the name , date and number of lines of the max and min files.
If there are several files with the same maximum/minimum number of lines,
print out the name of any one of them. Also, provide a brief explanation
of what your script does by including some comments in your script
file.
This homework is to be e-mailed to the TA before midnight on the
due date. Name of the program should be your login Name.