You are on page 1of 70

Lecture 44: UNIX

Shell Programming
 Unix Shell programming:
– What is shell
• Types of shell
– Shell scripts.
• Definition.
• Uses of shell scripts.
• Writing shell scripts.
• Examples
Unix Architecture
User UNIX Interface: SHELL
 Provides command line as an interface between
the user and the system
 Is simply a program that starts automatically when
you login
 Uses a command language
– Allows programming (shell scripting) within the shell
environment
• Uses variables, loops, conditionals, etc.
– Accepts commands and often makes system calls to
carry them out
Types of Unix Shell
 The most commonly used
 SH(Bourne Shell)

 CSH(C shell)

 KSH(Korn shell)

 most of the other shells you encounter will be


variants of these
 KSH is based on SH and so is BASH(Bourne
again shell). TCSH(Extended C SHell) is
based on CSH.
1.Bourne shell
– Early Unix shell that was written by Steve Bourne of AT&T Bell Lab.
– It is most popular shell.
• It is bundle with every UNIX system
– Basic shell provided with many commercial versions of UNIX
– Many system shell scripts are written to run under Bourne Shell
Features-
1.File descriptor operations- for reading writing and closing
2.It provides dup support for files
3.It support combination of command in a single line in efficient manner.

4.Redirection of pipe is available .


2.C Shell
 It was created by Bill Joy.
 It has two more advantages then Bourne shell
1. It allow aliasing of commands –instead of
writing lengthy command we can use short
alias.
2. Command history features –Previously
types command can be recalled since the C
shell keeps track of all commands issue at the
command line. This features is similar to the
one provided by the program DOSKEY in
MS-DOS environment.
3.KORN SHELL
 It is super set of Bourne shell
 Designed by David Korn of AT & T Bell laborites.
 Features
– Formatted printing
– Simplified menu generation.
– String handling
– Vi style command handling
– Extended regular expression.
– It Is faster then born
Drawback- It uses the system resources heavily.
Comparison between shell
(Bourne and c shell)
1.File descriptor operations-Bourne shell
provides various operations for writing,
reading and closing of files descriptors but
such operations are not available in C shell.
2.Bourne shell provides dup support for files
while c –shell doesn’t have dup.
3.Redirection of pipes is available in Bourne shell
but not in c shell.
Why use shell ???

 The various shells all have built in


functions which allow for the creation of
shell scripts.
Why use shell cont….
 Why write shell scripts ?
– To avoid repetition:
• If you do a sequence of steps with standard Unix
commands over and over, why not do it all with
just one command?
• Or in other words, store all these commands in a
file and execute them one by one.
– To automate difficult tasks:
• Many commands have subtle and difficult options
that you don’t want to figure out or remember
every time .
Simple Example

 Assume that I need to execute the


following commands once in a while when
I run out of disk space:
rm -rf $HOME/.netscape/cache
rm -f $HOME/.netscape/his*
rm -f $HOME/.netscape/cookies
rm -f $HOME/.netscape/lock
rm -f $HOME/.netscape/.nfs*
rm -f $HOME/.pine-debug*
rm -fr $HOME/nsmail
Simple Example (contd.)
 We can put all those commands into a shell
script, called myscript.
[axgopala@nitrogen axgopala]$ cat myscript
#! /bin/bash
rm -rf $HOME/.netscape/cache
rm -f $HOME/.netscape/his*
rm -f $HOME/.netscape/cookies
rm -f $HOME/.netscape/lock
rm -f $HOME/.netscape/.nfs*
rm -f $HOME/.pine-debug*
rm -fr $HOME/nsmail
Sample Example (contd.)
 To run the script:
– Step 1:
• $ chmod u+x myscript
– Step 2:
• Run the script:
• $ ./myscript
 Each line of the script is processed in
order.
Syntax for shell

#!/path/to/shell
 Usually anything following ( # ) is
interpreted as a comment and ignored but
if it occurs on the first line with a ( ! )
following it is treated as being special and
the filename following the ( ! ) is
considered to point to the location of the
shell that should interpret the 1script.
What is a shell script ????
Shell scripts
 A shell script is a text file with Unix
commands in it.
 Shell scripts usually begin with a #! and a
shell name (complete pathname of shell).
– Pathname of shell be found using the which
command.
– The shell name is the shell that will execute
this script.
• E.g: #!/bin/bash
Shell scripts (contd.)

If no shell is specified in the


script file, the default is
chosen to be the currently
executing shell.
Shell scripts (contd.)
 Any Unix command can go in a shell
script
– Commands are executed in order or in
the flow determined by control
statements.
 Different shells have different control
structures
– The #! line is very important.
– We will write shell scripts with the
Bourne shell (bash).
Shell scripts (contd.)
 A shell script as a standalone is an
executable program:
– Must use chmod to change the
permissions of the script to be executable
also.
 Can run script explicitly also, by
specifying the shell name.
– E.g: $ bash myscript
– E.g: $ csh myscript
Invoking Shell Scripts
1. Direct Interpretation
 In direct interpretation, the command
Syntax
csh filename [arg ...]

 invokes the program csh to interpret the


script contained in the file ‘filename’.
2.Indirect Interpretation

 In indirect interpretation, we must insert as


the first line of the file
Syntax- #! /bin/csh
or
#! /bin/csh –f

Note- The -f option says that we want fast


startup
What is shell
variable ?????
echo and read
 The backslash quoted characters in echo
– \c suppress the new line
– \n new line
– \r return
– \t tab
 Read
– read variable1 [variable2 …]
• Read one line of standard input
• Assign each word to the corresponding variable,
with the leftover words assigned to last variables
• If only one variable is specified, the entire line will
be assigned to that variable.
shell variable bourne shell
 Shell variables:
– Declared by:
– varname=varvalue
– To make them an environment variable, we
export it.
– export varname=varvalue
shell variable bourne shell
 When a script starts all environment
variables are turned into shell variables.
New variables can be instantiated like this:
Syntax - name=value
Example 1. –for console display
#!/bin/sh
msg1=Hello /*variable 1
msg2=There! /*variable 2
echo $msg1 $msg2

 This would echo "Hello There!" to the console display,


 if you want to assign a string to a variable and the
string contains spaces (see eg 2)
Example 2 for shell variable
#!/bin/sh
msg1="one"
msg2="$msg1 two"
msg3="$msg2 three"
echo $msg3
Out put -"one two three"
 if you want to assign a string to a variable and the
string contains spaces
 you should enclose the string in double quotes ("),
 the double quotes tell the shell to take the contents
literally and ignore keywords,
 however, a few keywords are still processed. You
can still use $ within a (") quoted string to
include variables:
Example 3 for shell variable (redirecting a output)
example3:

#!/bin/sh
echo 'msg="Hello World!"' > hello
echo 'echo $msg' >> hello
chmod 700 hello
./hello

Output –
 This would cause "msg="Hello World!" to be echoed and
 redirected to the file hello, "echo $msg" would then be echoed and
 redirected to the file hello but this time appended to the end.
 The chmod line changes the file permissions of hello so that we can
execute it.
 The final line executes hello causing it output "Hello World".
Setting Variables
 Values of shell variable are all character-
based: A value is formally defined to be a
list of zero or more
 elements, and an element is formally
defined to be a character string. In other
words, a shell variable
 consists of an array of strings.
 For example,
set X
Command Line Arguments as a variable
 treated as special variables within the script
 the reason I am calling them variables is because they
can be changed with the shift command
 The command line arguments are enumerated in the
following manner $0, $1, $2, $3, $4,$5, $6, $7, $8 and
$9
 $0 is special in that it corresponds to the name of the
script itself.
 $1 is the first argument, $2 is the second argument
and so on.
 To reference after the ninth argument you must
enclose the number in brackets like this ${nn}.
 You can use the shift command to shift the arguments
1 variable to the left so that $2 becomes $1, $1
becomes $0 and so on,
There are some special built in variables
(command line argument):
1. $# -represents the parameter count.
-Useful for controlling loop constructs that need to
process each parameter.
1. $@ -expands to all the parameters separated by
spaces.
-Useful for passing all the parameters to some other
function or program.
1. $ - expands to the flags (options) the shell was
invoked with.
-Useful for controlling program flow based on the flags
set.
1. $$ - expands to the process id of the shell
innovated to run the script.
-Useful for creating unique temporary filenames relative
to this instantiation of the script.
Notes on expr
 expr supports the following operators:
– arithmetic operators: +,-,*,/,%
– comparison operators: <, <=, ==, !=, >=, >
– boolean/logical operators: &, |
– parentheses: (, )
– precedence is the same as C, Java
Arithmetic Expansion
 Arithmetic expansion is also allowed and comes
in the form:
Syntax $((expression))
 The value of the expression will replace the
substitution.
Eg:
!#/bin/sh
echo $((1 + 3 + 4))

 Output - Will echo "8" to stdout


Control statements
 Without control statements, execution
within a shell scripts flows from one
statement to the next in succession.
 Control statements control the flow of
execution in a programming language.
Control statements
 The three most common types of control
statements:
– conditionals: if/then/else, case, ...
– loop statements: while, for, until, do, ...
– branch statements: subroutine calls (good
programming practice), goto (usage not
recommended).
Conditionals
 Conditionals are used to “test” something.
– In Java or C, they test whether a Boolean
variable is true or false.
– In a Bourne shell script, the only thing you can
test is whether or not a command is
“successful”.
Conditionals
 Every well behaved command returns back
a return code.
– 0 if it was successful
– Non-zero if it was unsuccessful (actually
1..255)
– This is different from C.
The if command
 Importance of having then on the next line:
– Each line of a shell script is treated as one
command.
– then is a command in itself
• Even though it is part of the if structure, it is
treated separately.
if … then
 Structure
if test-command
then
commands
fi

Example:
if test “$word1” = “$word2”
then
echo “Match”
fi
Example

grep returns 0 if it finds something


returns non-zero otherwise

if grep unix myfile >/dev/null


then
echo "It's there"
fi redirect to /dev/null so that
"intermediate" results do not get
printed
if…then…else
 Structure
if test-command
then
commands
else
commands
fi

– You can use semicolon (;) ends a command the same way a
NEWLINE does.
if [ … ]; then
……
fi

e.g. if [ 5 = 5 ]; then echo "equal"; fi


Using elif with if
#! /bin/bash
if grep "UNIX" myfile >/dev/null
then
echo UNIX occurs in myfile
elif grep “DOS” myfile > /dev/null
then
echo DOS appears in myfile not UNIX
else
echo nobody is here in myfile
fi
Using else with if
 Example:

#! /bin/bash
if grep "UNIX" myfile >/dev/null
then
echo UNIX occurs in myfile
else
echo No!
echo UNIX does not occur in myfile
fi
Example
nested if…then…else if…then…else
#!/bin/sh
if [ "$1" = "1" ]
then
echo "The first choice is nice"
elif [ "$1" = "2" ]
then
echo "The second choice is just as nice"
elif [ "$1" = "3" ]
then
echo "The third choice is excellent"
else
echo "I see you were wise enough not to choose"
echo "You win"
fi
Using colon in shell scripts
 Sometimes, we do not want a
statement to do anything.
– In that case, use a colon ‘:’
• if grep UNIX myfile > /dev/null
• then
•:
• fi
• Does not do anything when UNIX is found
in myfile .
Debugging Shell Scripts
 Display each command before it runs the
command
– Set the –x option for the current shell
• $set –x
– Use the –x to invoke the script
• $sh –x command arguments
– Add the set command at the top of the script
• set –x
 Then each command that the script executes
is preceded by a plus sign (+)
– Distinguish the output of trace from any output
that the script produces
 Turn off the debug with set +x
Do...While

 The Do...While takes the following


generic form:

while list
do list
done
Do...While example
Example –

#!/bin/sh
count=$1 # Initialise count to first parameter
while [ $count -gt 0 ] # while count is greater than 10 do
do
echo $count seconds till supper time!
count=$(expr $count -1) # decrement count by 1
sleep 1 # sleep for a second using the Unix sleep command
done
echo Supper time!!, YEAH!! # were finished

Output -
If called from the commandline with an argument of 4 this script will
output
 4 seconds till supper time!
 3 seconds till supper time!
 2 seconds till supper time!
 1 seconds till supper time!
 Supper time!!, YEAH!!
for loops
 for loops allow the repetition of a command for
a specific set of values.
 Syntax:
for var in value1 value2 ...
do
command_set
done
– command_set is executed with each value of var
(value1, value2, ...) in sequence
for… in
 Structure
for loop-index in argument_list
do
commands
done

Example:
for file in *
do
if [ -d “$file” ]; then
echo $file
fi
done
Example for and for in
#!/bin/sh
fruitlist="Apple Pear Tomato Peach Grape"
for fruit in $fruitlist
do
if [ "$fruit" = "Tomato" ] || [ "$fruit" = "Peach" ]
then
echo "I like ${fruit}es"
else
Unix Shell Scripting Tutorial
5
echo "I like ${fruit}s"
fi
done

Output
 I like Apples
 I like Pears
 I like Tomatoes
 I like Peachs
 I like Grapes
The while loop
 While loops repeat statements as long as
the next Unix command is successful.
 Works similar to the while loop in C.
while
 Structure
while test_command
do
commands
done

Example:
while [ “$number” –lt 10 ]
do
……
number=`expr $number + 1`
done
The until loop
 Until loops repeat statements until the
next Unix command is successful.
 Works similar to the do-while loop in C.
until
 Structure
until test_command
do
commands
done

Example:
secretname=jenny
name=noname
until [ “$name” = “$secretname” ]
do
echo “ Your guess: \c”
read name
done
Example

#! /bin/bash
x=1
until [ $x -gt 3 ]
do
echo x = $x
x=`expr $x + 1`
done

NOTE: The value of x is tested in the until to see if


it is greater than 3.
break and continue
 Interrupt for, while or until loop
 The break statement
– transfer control to the statement AFTER the
done statement
– terminate execution of the loop
 The continue statement
– Transfer control to the statement TO the done
statement
– Skip the test statements for the current
iteration
– Continues execution of the loop
Example:
for index in 1 2 3 4 5 6 7 8 9 10

do
if [ $index –le 3 ]; then
echo continue
continue
fi
echo $index
if [ $index –ge 8 ]; then
echo “break”
break
fi
done
case
 Structure
case test_string in
pattern-1 )
commands_1
;;
pattern-2 )
commands_2
;;
……
esac
 default case: catch all pattern
*)
case
 Special characters used in patterns

Pattern Matches

* Matches any string of characters.

? Matches any single character.

[…] Defines a character class. A hyphen


specifies a range of characters

| Separates alternative choices that satisfy a


particular branch of the case structure
Example ---
#!/bin/sh
echo “\n Command MENU\n”
echo “ a. Current data and time”
echo “ b. Users currently logged in”
echo “ c. Name of the working directory\n”
echo “Enter a,b, or c: \c”
read answer
echo
case “$answer” in
a)
date
;;
b)
who
;;
c)
pwd
;;
*)
echo “There is no selection: $answer”
;;
esac
The test command
 Use for checking validity.
 Three kinds:
– Check on files.
– Check on strings.
– Check on integers
Notes on test
 Testing on files.
– test –f file: does file exist and is not a
directory?
– test -d file: does file exist and is a directory?
– test –x file: does file exist and is executable?
– test –s file: does file exist and is longer than 0
bytes?
Example
#!/bin/bash
count=0
for i in *; do
if test –x $i
then
count=`expr $count + 1`
fi
done
echo Total of $count files executable
NOTE: expr $count + 1 serves the purpose
of count++
Notes on test
 Testing on strings.
– test –z string: is string of length 0?
– test string1 = string2: does string1 equal
string2?
– test string1 != string2: not equal?
Example
#! /bin/bash
if test -z $REMOTEHOST
then
:
else
DISPLAY="$REMOTEHOST:0“
export DISPLAY
fi

NOTE: This example tests to see if the value of


REMOTEHOST is a string of length > 0 or not,
and then sets the DISPLAY to the appropriate value.
Notes on test
 Testing on integers.
– test int1 –eq int2: is int1 equal to int2 ?
– test int1 –ne int2: is int1 not equal to int2 ?
– test int1 –lt int2: is int1 less than to int2 ?
– test int1 –gt int2: is int1 greater than to int2 ?
– test int1 –le int2: is int1 less than or equal to int2 ?
– test int1 –ge int2: is int1 greater than or equal to int2 ?
Example
#!/bin/bash
smallest=10000
for i in 5 8 19 8 7 3
do
if test $i -lt $smallest
then
smallest=$i
fi
done
echo $smallest

NOTE: This program calculates the smallest among


the numbers 5, 8, 19, 8, 3.
Notes on test
 The test command has an alias ‘[]’.
– Each bracket must be surrounded by spaces
#!/bin/bash
smallest=10000
for i in 5 8 19 8 7 3
do
if [ $i -lt $smallest ]
then
smallest=$i
fi
done
echo $smallest
Example
#! /bin/bash
i=1
sum=0
while [ $i -le 100 ]
do
sum=`expr $sum + $i`
i=`expr $i + 1`
done
echo The sum is $sum.

NOTE: The value of i is tested in the while to see if


it is less than or equal to 100.

You might also like