This tutorial will introduce you to several features of different shell scripting languages available for the UNIX operating system.
This tutorial is designed as an introduction to UNIX shell scripting languages. Many users that are new to UNIX don't realize the powerful program development and testing capabilities that writing simple shell scripts provide.
The ability to write simple and flexible scripts can greatly increase your productivity while working in UNIX. Most scripts are written to automate routine tasks that require several commands to be executed in order. By placing these commands in a script, the task can be completed simply by running the script.
A shell script is a text file that contains a list of commands that are placed in the order that the user would like the shell to execute each command. Most shell scripting languages also allow the definition and use of variables and provide some type of program control structures, such as selection and repetition statements.
By placing the commands in a script, the user simply has to run the script each time they wish the list of commands to be executed.
Running a script also makes the list of commands execute faster, since it allows the shell to execute each step of the task as soon as it completes the previous task. Otherwise, the shell would have to wait for the user to type the next command, and the user would have to wait for each command to complete before starting to type.
Another advantage to writing a script for common tasks is that there is less chance for a typing error that requires restarting the entire command sequence. Once, the commands are typed correctly into the script, they can be run as often as needed without error.
Write a script that say's "Hello World" and then shows the date.
echo "Hello World"
date
hello
.hello
to run your script.hello: Permission denied.
chmod
command as follows to set the permissions
so that your script can be executed.chmod 711 hello
hello
to run your script.Hello World
Sun Mar 17 15:23:40 CST 2002
A scripting language is used to communicate directly with the shell environment in UNIX. A shell is a program that runs on most UNIX systems to provide a convenient interface to the operating system and file system.
High-level languages are designed to provide flexibility and functionality to application programmers. They require some type of compilation or translation before they can be run.
Because is it difficult and time consuming to write full-fledged programs in high-level languages that can communicate effectively with your file system and shell environment in UNIX.
Scripting languages are specifically designed to do just that. They are composed of variables, control constructs and shell commands. They are interpreted by the shell and then executed by the shell. Shell scripts do not need to be compiled. Instead, the shell interprets each command as it is reached according to the control structures used.
Write a Java program that says "Hello World" and then shows the date.
import java.util.Date;
class Hello {
public static void main ( String [] args ) {
System.out.println("Hello World\n" + new Date());
}
}
hello.java
.javac hello.java
to compile your program.java hello
to run your program.Hello World
Sun Mar 17 15:23:40 CST 2002
Now compare the work involved in writing this Java program with the work to write the shell script in the above exercise. Most of us will agree that the minor inconvenience of having to set the file permissions was much easier than typing the longer Java program and having to compile it. Even C programs need to be compiled before they can be executed. But, shell scripts can be run just by typing the name of the script. The file permissions only need to be set once.
Before you can write powerful shell scripts, you will likely need to become a more powerful shell user. Most of us learn new shell commands only after witnessing a more savvy user execute them. But, on-line help is only a web site away. The CSL web pages document lots of information to get novices started on becoming more knowledgeable UNIX users. All CS account users should be familar with the information in the CS1000 An Introductory Manual to the Unix Operating System and the Computer Sciences Department's Instructional Computing Environment UNIX User's Guide. ©1998
The following was taken directly from the CSL's "Shell" web page of that document.
In Unix the shell is a program which prompts the user and directs the operating system to do what the user wants. When you login to your account, you see the prompt, ``sol21(1)% ''. This means that the shell is waiting for you to type a command. The shell is actually just a regular program like any other, yet it is a user interface which allows you to execute other programs. Your user account is configured with tcsh, an enhanced version of csh, the C-shell. Most literature describes csh and should be compatible with tcsh. Among the additional features of tcsh are filename completion (with the TAB key) and previous command repetition (with the UP and DOWN arrow keys). If you would like to use one of the many alternate shells, you can use the chsh command to change the shell your account uses. The shell is a very powerful tool that can be customized. Using just tcsh, new commands can be created, old ones altered, input and output files dynamically redefined, and even entire programs written without ever using a compiler. Chapter 5 contains a number of useful hints to get more out of the shell. Consult the man pages for csh and tcsh (see chapter 4, Getting Help) for more information on the many features of the c-shell and tc-shell.
There are dozens of other web pages of interest in the CS1000 document. But, here's some practice to get you started with some more advanced TC Shell commands.
From the man csh
page:
Control Flow The shell contains a number of commands to regulate the flow of control in scripts and within limits, from the terminal. These commands operate by forcing the shell either to reread input (to loop), or to skip input under certain conditions (to branch). Each occurrence of a foreach, switch, while, if...then and else built-in command must appear as the first word on its own input line. If the shell's input is not seekable and a loop is being read, that input is buffered. The shell performs seeks within the internal buffer to accomplish the rereading implied by the loop. (To the extent that this allows, backward goto commands will succeed on nonseekable inputs.)
You can use variables and program control structures in your shell commands. This may not seem useful while you're working from the command prompt, but it is this ability that will allow you to make powerful and flexible scripts. These are only some of the commands that you can place inside of a shell script to be executed at your command.
The following code sample shows the user entries in bold and the results of each command. See description of each command following the code example.
1. nova33(79)% alias ls 'ls -lbFp'
2. nova33(80)% ls
total 2
-rw-r----- 1 deppeler 143 Mar 17 15:36 Hello.java
-rwx--x--x 1 deppeler 25 Mar 17 15:12 hello*
3. nova33(81)% set d=myscripts
4. nova33(82)% mkdir $d
5. nova33(83)% ls
total 4
-rw-r----- 1 deppeler 143 Mar 17 15:36 Hello.java
-rwx--x--x 1 deppeler 25 Mar 17 15:12 hello*
drwxr-x--- 2 deppeler 2048 Mar 17 16:47 myscripts/
6. nova33(84)% mv *ello* $d
7. nova33(85)% ls
total 2
drwxr-x--- 2 deppeler 2048 Mar 17 16:48 myscripts/
8. nova33(86)% ls $d
total 2
-rw-r----- 1 deppeler 143 Mar 17 15:36 Hello.java
-rwx--x--x 1 deppeler 25 Mar 17 15:12 hello*
9. nova33(87)% mv $d/* .
10. nova33(88)% ls
total 4
-rw-r----- 1 deppeler 143 Mar 17 15:36 Hello.java
-rwx--x--x 1 deppeler 25 Mar 17 15:12 hello*
drwxr-x--- 2 deppeler 2048 Mar 17 16:48 myscripts/
11. nova33(89)% rmdir $d
12. nova33(90)% ls
total 2
-rw-r----- 1 deppeler 143 Mar 17 15:36 Hello.java
-rwx--x--x 1 deppeler 25 Mar 17 15:12 hello*
13. nova33(91)% unset d
14. nova33(93)% alias ls 'ls'
Explanationalias ls '-lbFp'
modifies the action of the
ls command.l
to show expanded listingb
to show control characters as '?'F
to show a trailing "/" after directoriesp
to show a "*" after executables.
ls
lists the contents of the current directory.set d=myscripts
sets a variable named d.mkdir $d
uses the variable to create a directory.
ls
verifies that the directory was created.mv ?ello* $d
moves all files that match (hello & Hello.java) to the new directory.ls
confirms the files no longer exist in current directory.ls $d
confirms the files do exist in the new location.mv $d/* .
moves all files from the new directory back to the current directory.ls
confirms the files have been moved.rmdir $d
removes the newly completed directory.ls
confirms the directory has been removed.unset d
removes the variable definition for d.alias ls
restores the action of the list command.Basically, anything that can be done from the command prompt can
be saved in a script, including control statements, like if
statements and loops.
However, the syntax is important and can vary in simple, but significant ways.
if ( cond ) then echo "reached the true part" else echo "reached the else part" endif
foreach name ( `\ls -d $dest/*` ) echo "$name" end
while ( cond ) echo "$name" end
myFirstScript
,
with the following contents.#! /bin/csh # set the base directory for all commands set base = /u/d/e/deppeler/public/html/tutorials/scripting set project = "" if ( $2 != "" && $1 != "" ) then # set the uname to the first word after the command name set uname = $1 # set the project directory to the second word after the command name set project = $2 # Tell the user hello echo "Hello $uname, user of $base/$project" # Get a listing of the base directory and process all commands for alias ls 'ls' echo "\ls -d $base/$project/* " foreach name ( `\ls -d $base/$project/*` ) echo "$name" end alias ls 'ls -lbFb' else echo "Usage: aScript uname dname" echo " where uname is the user's name" echo " and dname is the name of a directory in $base/$project echo endif
chmod 711 myFirstScript
myFirstScript
at the command prompt.This depends on what shells are available. Currently, there are several options for UNIX users in the CS Department.
sh
to use the original, the Bourne Shell.
Type exit
or [Ctrl-D] to exit and return to tcsh.ksh
to use the Korn Shell.
Type exit
or [Ctrl-D] to exit and return to tcsh.bash
to use the Bourne Again Shell.
Type exit
or [Ctrl-D] to exit and return to tcsh.set
and press [Enter].shell /bin/tcsh
. The shell variable
tells you which shell your account uses by default.
You can try different shells temporarily just by typing the name of shell
and pressing enter.
bash
and press [Enter] to try the Bourne Again Shell.bash-2.03$
exit
to exit BASH and return to the tcsh
.Yes, there are many scripting languages available. One of the most popular is Practical Extraction and Report Language (perl). The Perl scripting language has even more power and flexibility than the shell scripts introduced in this document.
If you're interested in learning Perl, there are a number of resources available. Here are some:
This is an example of a perl script that I used to alphabetically sort the names of students in my CS302 grade file. It will not work as the directorys have changed and you don't have file permissions to those given. But, it does show you some common commands and there syntax in perl.
#!/s/std/bin/perl # # This script will sort the grades file in your CS302 grading # by each student's login name. # # This is desirable so that the order of students in both the # quick grader program ("gr q ...") and the table format ("gr t") # will match # # written by: Deb Deppeler (deppeler) on 2/9/2000 # # Note: anyone who knows perl knows that this could have been done # with no named variables, the right regular expression and some cool syntax. # Since I didn't know what that was, I did the following: # use File::Copy; use strict; # update the directory's according to the current roster system("gr u"); my $sInstructor = $ENV{USER}; my $sGradingDir = "/p/course/cs302/private/grading/$sInstructor"; my $sGradeFile = "grades"; my $sNewGradeFile = "temp"; my $sGradeFullName = $sGradingDir . "/" . $sGradeFile; my $sNewGradeFullName = $sGradingDir . "/" . $sNewGradeFile; my %hGrades; open (GRADEFILE , $sGradeFullName ) || die "unable to open $sGradeFullName: $!"; open (NEWGRADEFILE, ">$sNewGradeFullName") || die "unable to open $sNewGradeFullName: $!"; while () { my @aFields = split(":"); $hGrades{@aFields[2]} = $_; } my @aSortedLogins = sort keys(%hGrades); foreach (@aSortedLogins) { print NEWGRADEFILE "$hGrades{$_}"; } unlink($sGradeFullName) || die "couldn't delete $sGradeFullName: $!"; move($sNewGradeFullName, $sGradeFullName) || die "couldn't move $sNewGradeFullName to $sGradeFullName: $!"; print "$sGradeFullName now contains the list of students sorted by login name\n"; #print "$sNewGradeFullName now contains the list of students sorted by login name\n";
In this lesson you have learned about shell command and basic scripting languages in UNIX.
man csh
in an xterm window..