A shell script is a plain ASCII text file and can hence be created with any text editor (even vi!). It is a list of commands which you would normally have issued yourself on the commandline (quite similar in concept to command files under VMS or batch files under MSDOS). In addition, most UNIX shells have the capability of command flow logic ( goto, if/then/else/endif etc.), retrieving the command line parameters, defining and using (shell) variables etc.
Under the UNIX environment one can also choose which shell to use, although we shall only give examples in the most commonly used shell, the C-shell (csh). As an example, we will show a shell script which copies all files from one directory to a new one, also creating that new directory. The new directory must not exist yet, otherwise the script will fail with an error message. It's usage would look like:
% csh -f scriptname dir1 dir2or shorter:
% scriptname dir1 dir2The second form, in which the script is not told through which shell it should process its commands, is the recommended practice. The first line of this script file must then contain the magic line
#! /bin/csh -fto denote the script is to be run via the C-shell, which on standard UNIX systems is located in /bin/csh. In this case the script also needs to be made executable, i.e.
% chmod +x scriptname
In effect your operating system will then issue the first form of the command, The second form has the advantage that you don't have to remember which shell to use, and in the end saves a few keystrokes, always considered a big issue in UNIX!
Now lets look at the full text of the script first:
#! /bin/csh -f
# Example of a shell script to copy all files from one directory
# to another. The input directory must not contain any subdirectories,
# and it will not copy any so-called (hidden) dot-files.
## check if called properly
if ($#argv != 2) then
echo "Usage: $0 dir1 dir2"
echo "copies all files from one directory to another"
## save command line args in variables
## check if dir1 indeed is an existing dir
if (! -d $dir1) then
echo "$dir1 is not a directory" ; exit 1
## check if dir2 does not exist
if (-e $dir2) then
echo "$dir2 already exists" ; exit 1
## create new dir2
if ($status != 0) goto error
## loop through all files in dir1
foreach file ($dir1/*)
if (-d $file) then
echo "Skipping $file (is a directory)"
echo "Copying $file"
cp $file $dir2
## Labels to jump to exit OK (done) or not OK (error)
A few things can be noted:
$#argv(the same as
$*) can be used to find the number of elements in the list. In our example we want exactly two, hence the first check. A shell variable list can be initialized using brackets, e.g.: set name=(val1 val2 val3). In this case
$namehas the value val2 etc.