Korn Shell Script Writing
Korn Shell Script Writing
1
Basic Shell Programming
• Creating a Shell Script • Null Variables
2
Creating a Shell Script
3
Executing a Shell Script
1."dot" method
$ . scriptname
4
Executing a Shell Script (cont.)
5
Executing a Shell Script (cont.)
cat list
# a simple little shell script
print "A listing of $PWD \n" > list.out
ls -l >> list.out
6
Functions
• Syntax:
function functname {
shell commands
}
or,
functname () {
shell commands
}
7
Functions (cont.)
$ unset -f functname
$ functions
8
Functions (cont.)
• Two important differences between functions and shell
scripts run by name (Method 2):
– functions do not run in a subprocess; behave more like a script run
by Method 1
– functions have precedence over scripts
9
Functions (cont.)
$ myrun ()
> {
>cd $WORKDIR
> a.out < data.in
> more data.out
> /bin/rm data.in
> mv data.out data.in
> }
10
Precedence of Commands
Now that we have discussed the various sources of
commands, let us show their order of precedence:
1.Keywords such as function, if and for (see later)
2.Aliases
3.Shell built-ins
4.Functions
11
eval
• Consider:
$ listpage="ls | more"
$ $listpage
ls: |: No such file or directory
ls: more: No such file or directory
12
eval
• The command
$ eval $listpage
13
Shell Variables
• The Korn shell includes the following types of variables:
– User-defined variables
– Special shell variables
14
Assigning Variable Names
= Operator:
Enter the name that you have chosen for the variable
followed by an equal sign and then
the value that you want to store in the variable.
$ my_card=ace
$ print $my_card
ace
$ my_name="Garth of Izar"
$ print $my_name
Garth of Izar
15
Assigning Variable Names
read command:
16
Null Variables
A variable can be set to a null value, even if previously
assigned, using any of the following methods. There
should be no spaces preceding or following the equal sign.
$ name=
$ name=''
$ name=""
$ unset varname
17
Null Variables (cont.)
All variables that don't exist are assumed null unless set -o
nounset is used. Then the shell will indicate an error when
an undefined variable is encountered
$ unset name
$ set -o nounset
$ print $name
ksh: name: parameter not set
$ set +o nounset
18
Special Shell Variables and Positional Parameters
• Other variables defined by the shell for the user are special
shell variables and "positional parameters."
19
Special Shell Variables and Positional Parameters
$ cat numargs
print The number of arguments is $#
$ numargs
The number of arguments is 0
$ numargs 1 2 3 4 5
The number of arguments is 5
$ numargs "Hello World"
The number of arguments is 1
20
Special Shell Variables and Positional Parameters
$ print $-
isxumh
$ set +u
isxmh
21
Special Shell Variables and Positional Parameters
$ ls
file1 data account.txt
$ rm file1
$ print $?
0
$ rm dataa
dataa: No such file or directory
$ print $?
2
22
Special Shell Variables and Positional Parameters
$ cat pid.test
print $$
$ print $$
454
$ pid.test
846
$ pid.test &
847
23
Special Shell Variables and Positional Parameters
• The variable $! contains the process ID number of the last
command sent to the background.
$ compress hugefile.tar &
[1] 8834
$ kill -9 $!
24
Special Shell Variables and Positional Parameters
$ cat args
print The arguments are: $*
25
Special Shell Variables and Positional Parameters
$ cat args
print The arguments are: "$@"
26
Special Shell Variables and Positional Parameters
27
Special Shell Variables and Positional Parameters
28
Special Shell Variables and Positional Parameters
Use the set command to change positional parameters. It
replaces existing positional parameters with new values.
$ cat newpos
print starting args are $*
print number of args is $#
print arg 1 is $1
print arg 2 is $2
set 3 4
print new args are $*
print number of args is $#
print arg 1 is $1
print arg 2 is $2
$ newpos 1 2
starting args are 1 2
number of args is 2
arg 1 is 1
arg 2 is 2
new args are 3 4
number of args is 2
arg 1 is 3
arg 2 is 4
29
Special Shell Variables and Positional Parameters
$ ten_args a b c d e f g h i j
arg 10 is a0
arg 10 is j
30
Special Shell Variables and Positional Parameters
31
Special Shell Variables and Positional Parameters
Example of shift:
$ cat shift_it
print $#: $0 $*
shift
print $#: $0 $*
shift
print $#: $0 $*
shift
print $#: $0 $*
$ shift_it 1 2 3 4 5 6 7 8 9 0 a b
12: shift_it 1 2 3 4 5 6 7 8 9 0 a b
11: shift_it 2 3 4 5 6 7 8 9 0 a b
10: shift_it 3 4 5 6 7 8 9 0 a b
9: shift_it 4 5 6 7 8 9 0 a b
$ cat ten_args
arg1=$1
shift
print $arg1 $*
$ ten_args 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
32
Parameter Substitution
• Notes on Variable Syntax
– Syntax $name is not quite accurate
– ${name} is more general
$ file=new;cp $file ${file}copy
– Curly braces can be omitted as long as name is followed by a
character that isn't a letter, digit, or underscore
– This syntax allows for parameter substitution: replacement of the
value of a variable with that of another based on specific
conditions and events.
33
Parameter Substitution (cont.)
${parameter:-value}
$ FOO=/usr/local/bin/xx
$ print edit file ${FOO:-$HOME/xx}
edit file /usr/local/bin/xx
$ print $FOO
/usr/local/bin/xx
34
Parameter Substitution (cont.)
${parameter:=value}
35
Parameter Substitution (cont.)
${parameter:+value}
• Examples:
$ trace=y
$ print ${trace:+"Trace mode on"}
Trace mode on
$ trace=""
$ print ${trace:+"Trace mode on"}
36
Parameter Substitution (cont.)
${parameter:?message}
• If parameter exists and isn't null, return its value; otherwise
print parameter: followed by message and abort the current
command or script. Omitting message produces the
default message parameter null or not set.
• Purpose: Catching errors that result from variables being
undefined.
• Examples:
$ count=""
$ print card '#'${count:?"deal!"}
ksh: count: deal!
$ count=5
$ print card '#'${count:?"deal!"}
card #5
NOTE: In all forms, the colon (:) is optional. If omitted, the operator tests for existence only, i.e., change
"exists and isn't null" to "exists" in each definition.
37
Special Pattern Matching Features
• We have seen the use of the wildcards *,? and []
Pattern Matches
x x
*(x) Null string, x, xx, xxx, ...
+(x) x, xx, xxx, ...
?(x) Null string, x
!(x) Any string except x
@(x|y|z|...) x or y or z or ...
38
Special Pattern Matching Features
$ ls *.?(e)ps
$ ls !(*.c|*.h|README|Makefile)
39
Command Substitution
• Two ways seen thus far for getting values into variables:
– assignment statements
– command-line arguments (positional parameters)
• Examples:
$ DAY=$(date +%A)
$ FILE_LIST=$(ls)
$ LOGGED_ON=$(who|cut -f1 -d' ')
$ FILE=$(< filename)
40
Exercises
1. Write a script called lsc which executes the command ls -C. To
execute this command you must give the full path name to your lsc
script. Make the lsc shell script executable and run it.
41
Korn Shell Flow Control
• Flow Control • Examples
• if / else • select
42
Flow Control
• Flow control gives a programmer the power to specify that
only certain portions of a program run, or that certain portions
run repeatedly.
43
Exit Status
• At the end of its execution, every UNIX command returns a
status number to the process that invoked it.
• The shell sets the $? variable to the exit status of the last
foreground command that was executed.
44
Exit Status
• The constructs if, while, until and the logical AND (&&)
and OR (||) operators use exit status to make logical
decisions:
• There are built-in true and false commands which you can
use.
45
Exit Status (cont.)
A shell, like any other process, sets an exit status when it finishes
executing. Shell scripts will finish in one of the following ways:
Abort - If the script aborts due to an internal error, the exit status is
that of the last command (the one that aborted the script).
End - If the script runs to completion, the exit status is that of the last
command in the script
Exit - If the script encounters and exit or return command, the exit
status is that set by those commands.
46
Logical Command Grouping
• Two special symbols enable you to execute a command based
on whether or not the preceeding command was successful:
&& is a logical AND || is a logical OR
• Usage:
statement1 && statement2
statement2 will execute only if statement1 was successful
(returned an exit status of 0)
statement1 || statement2
statement2 will execute only if statement1 was not
successful (returned a nonzero exit status).
47
Logical Command Grouping (cont.)
Example:
$ cat on
# a simple shell script to check
# if certain users are logged on
who | grep $1 > /dev/null \
&& print $1 logged on \
|| print $1 not logged on
$ on jason
jason logged on
$ on phantom
phantom not logged on
48
if / else
• Simplest type of flow control construct is the conditional
embodied in Korn shell's if statement.
• Syntax:
if condition
then
statements
[elif condition <-- can use multiple elif clauses
then statements . . .]
[else
statements]
fi <-- must be by itself on the final
line of the construct
49
if / else (cont.)
• If one or more elifs are used, the last else clause is an "if all
else fails" part.
50
Condition Tests
• The if construct can only test exit status but that doesn't limit
you to checking only whether commands ran properly or not.
51
Condition Tests (cont.)
• Conditional expressions inside [[ ]] can be combined
using the logical && and || operators.
52
Condition Tests (cont.)
String comparison operators:
53
Condition Tests (cont.)
File attribute checking:
Operator True if ...
-a file file exists
-d file file is a directory
-f file file is a regular file
-m file file is migrated (UNICOS extension)
-r file there is read permission on file
-s file file is not empty
-w file you have write permission on file
-x file you have execute permission on file, or
directory search permission if it is a directory
-O file you own file
-G file your group id is same as file's
file1 -nt file2 file1 is newer than file2
file1 -ot file2 file1 is older than file2
54
Condition Tests (cont.)
Integer Conditionals
Test Comparison
-lt less than
-le less than or equal
-eq equal
-ge greater than or equal
-gt greater than
-ne not equal
55
Condition Tests (cont.)
Examples
$ [[ -z "" ]]
$ print $?
0
$ [[ -z foo ]]
$ print $?
1
56
Condition Tests (cont.)
57
Condition Tests (cont.)
Examples
• The following script removes the first file if it's older than the
second file and the variable KEY is non-null:
if [[ $1 -ot $2 && -n $KEY ]]
then
/bin/rm $1
fi
58
Condition Tests (cont.)
The following script compares two files and if no differences are
found, removes the second file:
USAGE="Usage:\t$(basename $0) file1 file2"
if [[ $# -ne 2 ]]; then
print -u2 ${USAGE}\\n
exit 1
fi
59
for
• Previous tests only allow reporting on single files since tests
like -f and -x only take single arguments
• During each time through the iteration, the loop variable is set
to a different value.
60
for
• During each time through the iteration, the loop variable is set
to a different value.
61
for (cont.)
Syntax:
for name [in list]
do
statements that can use $name
done
62
for (cont.)
Examples
$ cat simple
for i in This is a test
do
print $i
done
$ simple
This
is
a
test <-- Omitting the in This is a test clause
and instead running the script as:
$ simple This is a test
would yield the same output.
63
for (cont.)
Examples
64
for (cont.)
list can contain shell wildcards and command substitution
as well:
$ cat file1
for i in *
do
print $i
done
$ file1
file1
file2
$ cat file2
for i in $(ls)
do
print $i
done
$ file2
file1
file2
65
case
• Syntax:
case expression in
pattern1)
statements ;;
pattern2)
statements ;;
...
esac
66
Case (cont.)
• If expression matches one of the patterns, its
corresponding statements are executed
67
Case (cont.)
Here's a simple script which moves C and fortran source files to
one directory and object code files to another:
68
Case (cont.)
69
Case (cont.)
*) print -n Date:
date +"%a %h %d" ;;
print -n Time:
date +"%T" ;;
esac
$ dt_fmat -y
Year: 1996
$ dt_fmat *
Date:Thu Oct 17
Time:14:33:36
70
select
• select allows you to generate simple menus easily.
• Syntax:
select name [in list]
do
statements that can use $name
done
• This is the same syntax as the for loop except for the keyword
select. As with for, in list defaults to "$@" if omitted.
71
Select (cont.)
• The selected choice is stored in name and the selected
number in REPLY
72
Select (cont.)
The following script termselect allows you to select a terminal
setting:
PS3='terminal? '
select term in vt100 vt220 xterm
do
if [[ -n $term ]]; then
TERM=$term
print TERM is $term
break
else
print invalid choice
fi
done
vt100 vt220 xterm <--- the list can be expanded for clarity
using continuation lines and quotes
73
Select (cont.)
$ termselect
1) vt100
2) vt220
3) xterm
terminal? 4
invalid choice
terminal? 3
TERM is xterm
74
while & until
• Allows a section of code to be run repetitively while a certain
condition holds true.
• Syntax:
while condition
do
statements ...
done
75
while & until (cont.)
Example: print out arguments
$ cat args
while [[ $# -ne 0 ]]; do
print $1
shift
done
a
1
76
Command-line Arguments
• We want to expand on our ability to use command-line options
to shell scripts
if [[ $1 = -o ]]; then
process the -o option
shift
fi
normal processing of arguments ...
77
Command-line Arguments (cont.)
Example:
• Suppose you keep a list of your home coin collection that keeps track
of how many coins you have in a given category. Lines in the list look
like:
62 U.S. proofs
11 U.S. pennies (1850-1908)
36 U.S. pennies (1909-1950)
9 U.S. nickels (1861-1938)
• You want to write a program that prints the N types of coins of which
you have the most. The default for N is 10. The program should take
one argument for the name of the input file and an optional argument
for how many lines to print.
78
Command-line Arguments (cont.)
• This script is usable but if no arguments are given to the script
it will appear to hang
• No useful error messages
• Doesn't conform to typical UNIX command syntax
filename=$1
sort -nr $filename | head $howmany
79
Command-line Arguments (cont.)
For multiple options, a general technique would be (assume
script named exo):
while [[ $1 = -* ]]; do
case $1 in
-a) process option -a ;;
-b) process option -b ;;
-c) process option -c ;;
* ) print usage: exo [-a] [-b] [-c] args; return 1 ;;
esac
shift
done
80
Command-line Arguments (cont.)
Suppose option b takes an argument itself:
while [[ $1 = -* ]]; do
case $1 in
-a) process option -a ;;
-b) process option -b
$2 is the option's argument
shift ;;
-c) process option -c ;;
* ) print usage: exo [-a] [-b option] [-c] args; return
1 ;;
esac
shift
done
81
Integer Variables & Arithmetic
• The shell interprets words surrounded by $ (( and )) as arithmetic
expressions.
• Variables in arithmetic expressions do not need to be preceded by
dollar signs.
Operator Meaning
+ addition
- subtraction
* multiplication
/ division with truncation
< less than
> greater than
<= less than or equal
>= greater than or equal
== equal
!= not equal
&&(||) logical and (or)
82
Integer Variables & Arithmetic (cont.)
• No need to backslash escape special characters within
$((...)) syntax.
• Examples:
$ print $ ((3 > 2 ))
1
$ print $ (( (3 > 2 ) || (4 <= 1) ))
1
$ print $ (( 2#1001 ))
9 <--using base 2
83
Integer Variables & Arithmetic (cont.)
84
Integer Variables & Arithmetic (cont.)
• "Truth" values:
$ (( 14 )) ;print $?
0
$ (( 0 )) ;print $?
1
• Assigning expressions to integer variables with the let
command:
let x= $x
1+4 5
'1 + 4’ 5
'(2+3) * 5’ 25
17/3 5
85
Exercises
1.Write a script called lis that uses a for loop to display all files and
directories in the current directory.
4.Write a script called mydir that prints the message File is a directory if
the file is a directory.
86
Exercises (cont.)
5.Write a script called ver that accepts one argument on the command
line indicating the name of a file. The file is copied to another file with
the same name with the addition of the extension .v2. Also, the line
#Version 2 is added to the top of the file.
6.Execute the ver script on itself, creating a new version of the file
called ver.v2.
87