The Insides of Athena Unix
Today we will discuss Shell Scripts. I will start by discussing how and why they are used.
You will find that most shell scripts are written for the bourne shell. The reason for this is that all unix systems have the bourn shell, wehreas not all of them have the c shell. It is possible to write a shell script that runs under the c shell, though, by putting
#!/bin/csh
On the first line of the script. I will only discuss bourne shell programming here, and you should refer to the man page for the c shell for information on how to write shell scripts which use it.
Simple shell programs are often only one line long. If there is a command line that you type frequently (often that involves piping the output of one command into another) you can enter that line into a file, and use it as a shell script which can be invoked by its name. For example, suppose you wanted a command that listed all the places you are logged in on a given cluster.
One way to do this would be to issue the command:
rwho | grep {your username}
Now suppose that instead you wanted to do this whenever you typed the command „findme“. You would then create a file „findme“ containing the line above. Before you can execute the shell script, you have to tell UNIX that the file findme is in fact a program and not just a text file. You can do this by changing is mode to allow execute access:
chmod a+x findme
At this point, typeing „findme“ would perform those commands. This could have been done using the alias feature instead, so what is so special about shell scripts? Well, to start with, next time you log in, this command will still be there. Further, other people can use the new command you just defined (if they can access the file).
Shell scripts also can be much more complex (several pages for example.
—–
[] arguments
The next useful ability with shell scripts is arguments. Suppose that you wanted to do the same as we did above, but you want to specify the user on the command line. Lets call that command „findu“. If I want to see where bcn is logged in I should be able to say „findu bcn“. Well, this is simple. Instead of your username, you use the value „$1“. $1 in a shell script expands to the value of the first argument. Similarly, $2 is the second argument, $3 the third and $0 is the name of the command itself.
So findu would look as follow:
rwho | grep $1
Note that arguments are used in the same manner that variables are used.
—
[] for, while do, if then else, and case
Like any other programming language, shell scripts allow various looping and selection constructs. One of these is the „for“ statement.
It’s format is:
for variable in list_of_values
do
statemtns
done
the list of variables can use *s to select file names. If you leave out the in list_of values, the for statement will iterate through the arguments given to the shell.
—
The form of the while do statement is:
while condition
do
statements
done
This is like the while do statement in most programming languages, so I won’t go into details about it.
—
Then there is the if then else statement.
Its form is:
if condition
then
statements
[elif condition then]
statements
[else]
fi
The elif (else if) and the else statements are optional. The if statements does just what you would expect. If the condition is true, then it executes the then part. If it is false, and if the is an elif, then it check that condition, and executes the then clase of it. If none of the conditions are ture, it executes the else clause.
The last construct I will talk about is the case statement. Its form is:
case $variable in
v1) statement
break;;
v2)
statement
break;;
*)
esac
There is also an until statement which is similar to the while statement.
———
[] test
So far, I have mentioned condition, but I haven’t mentioned how to specify conditions. Conditions are really only the exit status of a program. Hence, the way you specify a condition is to run a program which will return an error if a condition is face, and will return successfully if it is true. This program is the test program. I will very briefly describe the test command. For more information you can say „man test“ when logged in.
Arguments for test are of the form N <primitive> M where N and M are variables or constants, and the promitive is
-eq, -ne, -gt, -lt, -ge, -le for numbers
= and != for strings.
Alternatively you can say test -f filname to test for existance of a file, -s to check that the file isn’t empty. -d checks if a file is a directory, -w if it is writable, and -r checks if it is readable. These aren’t all the options to test though.
In many shell scripts, you may see square brackets around what looks like a test statement. If square brackets are used, you don’t have to say test. In other words,
[-f file]
is equivilant to
test -f file
[] use of /tmp
When writing shell scripts, one will often need to use temporary files. When doing so, a good place to sture these temporary file is in /tmp. It is important that the temporary file you create has a different name than any file already in tmp. To do this, you can use the shell variable $$ which translates into the current process number. In fact, a good name to use is $0$$ which is the name of the current shell script followed by the process ID. Ussing this name will prevent conflicts with other programs, or different invocations of the same program.
Another thing which is important is to have your shell script remove the file when it is done using it. This way, /tmp does not fill up.
Files in /tmp in theory are deleted periodically, but the policy is different on different systems. It never hurts to delete a temporary file that you no longer need.
———
[] interrupts
The trap command is useful for dealing with interrupts such as ^C or hanging up the phone line. The form for the trap command is:
trap ‚command arguments‘ signal1 signal2
for example
trap ‚rm $tmp* ;exit‘ 2 1
———
[] exit
This brings us to the last command I want to describe. The exit command. The exit command alows one to exit a shell script. Exit takes an argument, and returns that value. A zero value usually indicated that the command has run successfuly, whereas a value of 1 usually indicates that an error has occured.
- Unix Course: Introduction, Shell Commands – Lecture 1
- Unix Course: The Shell, and Shell Programming – Lecture 2
- Unix Course: More Shell Programming – Lecture 3
- Unix Course: Unix Security – Lecture 4