Contents
Principle of Script
Variables
Branching
Looping
Command line Arguments
Comparisons
Variable Manipulations
ksh Regular Expressions
Functions
Data Redirection
Pipes
Co-processes
Read Input from User and from Files
Special Variables
Action on Success or Failure of a Command
Trivial Calculations
Numerical Calculations using "bc"
"grep"
"sed"
"awk"
"perl"
Principle of Script
Defining the Shell Type
To make a ksh script (which is a ksh program) crate a new file with a starting line like:
#!/usr/bin/ksh
It is important that the path to the ksh is proper and that the line doesn’t not have more
than 32 characters. The shell from which you are starting the script will find this line and
hand the whole script over to ksh. Without this line the script would be interpreted by the
same typ of shell as the one, from which it was started. But since the syntax is different
for all shells, it is necessary to define the shell with that line.
#!/usr/bin/ksh
# Commentary......
file=/path/file
if [[ $file = $1 ]];then
command
fi
One can continue commands over more than one line with a "\" immediately followed by
a newline sign which is made be the return key:
grep filename | sort -u | awk '{print $4}' | \
uniq -c >> /longpath/file
Variables
Filling in
When filling into a variable then one uses just its name: state="US" and no blanks. There
is no difference between strings and numbers: price=50.
Using
When using a variable one needs to put a $ sign in front of it: print $state $price.
Arrays
Set and use an array like:
arrname[1]=4 To fill in
print ${arraname[1]} To print out
${arrname[*]} Get all elements
${#arrname[*]} Get the number of elements
Declaration
There are happily no declarations of variables needed in ksh. One cannot have decimals
only integers.
Branching
if then fi
if [[ $value -eq 7 ]];then
print "$value is 7"
fi
or:
if [[ $value -eq 7 ]]
then
print "$value is 7"
fi
or:
if then else fi
if [[ $name = "John" ]];then
print "Your welcome, ${name}."
else
print "Good bye, ${name}!"
fi
case esac
case $var in
john|fred) print $invitation;;
martin) print $declination;;
*) print "Wrong name...";;
esac
Looping
while do done
while [[ $count -gt 0 ]];do
print "\$count is $count"
(( count -= 1 ))
Done
until do done
until [[ $answer = "yes" ]];do
print -n "Please enter \"yes\": "
read answer
print ""
done
continue...break
One can skip the rest of a loop and directly go to the next iteration with: "continue".
while read line
do
if [[ $line = *.gz ]];then
continue
else
print $line
fi
done
One can also prematurely leave a loop with: "break".
while read line;do
if [[ $line = *!(.c) ]];then
break
else
print $line
fi
done
The single Arguments are stored in $1, ....$n and all are in $* as one string. The
arguments cannot directly be modified but one can reset the whole command line for
another part of the program.
If we need a first argument $first for the rest of the program we do:
if [[ $1 != $first ]];then
set $first $*
fi
One can iterate over the command line arguments with the help of the shift command.
Shift indirectly removes the first argument.
until [[ $# -qe 0 ]];do
# commands ....
shift
done
One can also iterate with the “for” loop, the default with for is $*:
for arg;do
print $arg
done
Comparisons
To compare strings one uses "=" for equal and "!=" for not equal.
To compare numbers one uses "-eq" for equal "-ne" for not equal as well as "-gt" for
greater than and "-lt" for less than.
if [[ $name = "John" ]];then
# commands....
fi
if [[ $size -eq 1000 ]];then
# commands....
fi
With "&&" for "AND" and "||" for "OR" one can combine statements:
if [[ $price -lt 1000 || $name = "Hanna" ]];then
# commands....
fi
if [[ $name = "Fred" && $city = "Denver" ]];then
# commands....
fi
Variable Manipulations
Removing something from a variable
Variables that contain a path can very easily be stripped of it: ${name##*/} gives you just
the filename.
Or if one wants the path: ${name%/*}. % takes it away from the left and # from the right.
%% and ## take the longest possibility while % and # just take the shortest one.
Functions
Description
A function (= procedure) must be defined before it is called, because ksh is interpreted at
run time.
It knows all the variables from the calling shell except the command line arguments. But
has it's own command line arguments so that one can call it with different values from
different places in the script. It has an exit status but cannot return a value like a c
function can.
Making a Function
One can make one in either of the following two ways:
function foo {
# commands...
}
foo(){
# commands...
}
Return
The return statement exits the function immediately with the specified return value as an
exit status.
Data Redirection
General
Data redirection is done with the following signs: "> >> < <<". Every program has at
least a standardinput, standardoutput and standarderroroutput. All of these can be
redirected.
From eof to eof all is fed into the above mentioned command.
Pipes
For a serial processing of data from one command to the next do:
command1 | command2 | command3 ...
e.g. last | awk '{print $1}' | sort -u.
Co-processes
One can have one background process with which one can communicate with read -p and
print -p. It is started with command |&. If one uses: ksh |& then this shell in the
background will do everything for us even telnet and so on: print -p "telnet hostname".
Special Variables
$# Number of arguments on command line.
$? Exit status of last command.
$$ Process id of current program.
$! Process id of last background job or background function.
$0 Program name including the path if started from another directory.
$1..n Command line arguments, each at a time.
$* All command line arguments in one string.
Trivial Calculations
Simple calculations are done with either a "let" in front of it or within (( ... )). One can
increment a variable within the (( )) without a "$": (( a+=1 )) or let a+=1.
"sed"
Sed means stream line editor. It searches like grep, but is then able to replace the found
pattern. If you want to change all occurrences of "poor" with "rich", do: sed -e
's/poor/rich/g' filename. Or what is often seen in software packages, that have to be
compiled after getting a proper configuration, is a whole file stuffed with replacements
patterns like: /@foo@/s;;king;g. This file with innumerable lines like that has to be given
to sed with: sed -f sedscript filename. It then processes each line from file with all the sed
commands in the sed script. (Of course sed can do much more:-))
"awk"
Awk can find and process a found line with several tools: It can branch, loop, read from
files and also print out to files or to the screen, and it can do arithmetics.
For example: We have a file with lines like: Fred 300 45 70 but hundreds of them. But
some lines have a "#" as the first sign of them and we have to omit these ones for both,
processing and output. And we want to have lines as output like: 415 Fred where 415 is
the sum of 300, 45 and 70. Then we call on awk:
awk '$1 !~ /^#/ && $0 ~ /[^ ]/ {print $2+$3+$4,"\t",$1}' filename.
This ignores lines with a "#" at the beginning of the first field and also blank lines. It then
prints the desired sum and the $1 ist only printed after a tab. This is the most trivial use of
awk only.
"perl"
Perl is a much richer programming language then ksh, but still one can do perl commands
from within a ksh script. This might touch Randal, but it's true. Let's say you want to
remove all ^M from a file, then take perl for one line in your ksh script:
perl -i -ep 's/\015//g' filename.
Perl can do an infinite amount of things in many different ways. For anything bigger, use
perl instead of a shell script.