Script arguments are the same as in Bourne shell:
$0 |
command name |
$1...$n |
arguments 1 to n |
$# |
no. of arguments |
$? |
exit status |
Arguments can be shifted as in Bourne shell. Script execution can terminate at
any place and return an optional exit value:
exit [n]
Checks are enabled either by test or [...] (same as test) or by [[...]]. The expression is separated from brackets by leading and trailing blanks. The double brackets form is a Korn shell enhancement.
[ "$X" = abc ] && echo string is "abc" # tcsh test "$X" = abc && echo string is "abc" # tcsh [[ $X = abc ]] && echo korn # korn
| Korn Shell String Operators | |
| -n str | true if len(str) != 0 |
| -o opt | true if opt set |
| -z str | true if len(str) = 0 |
| str1=str2 | true if equal strings |
| str1!=str2 | true if .not.equal strings |
| str1=pattern | true if pattern match |
| str1!=pattern | true if pattern .not.match |
| str1<str2 | true if str1 less than str2 |
| str1>str2 | true if str1 greater than str2 |
Example:
> cat kstr #!/bin/ksh #-----------kstr: string test with Korn shell # echo Proc $0: strings in Korn shell echo # set -x #uncomment to debug script X=nice_dog Y=bad_cat [[ $X = *dog* ]] && print $X is a nice doggie [[ $Y = ??????? ]] && print $Y is 7 chars long X=123 [[ $X = +([0-9]) ]] && print $X is digit [[ $Y = +([0-9)] ]] || print $Y is alpha # #----------end script------------------ > kstr Proc kstr: strings in Korn shell nice_dog is a nice doggie bad_cat is 7 chars long 123 is digit bad_cat is alpha >-----------------------File testing is performed by the following operators prefixed to the file name:
> ksh -c "[[ -a kvar ]] && echo exists" exists $ ksh -c "[[ -a kls.ksh ]] || echo no such file" no such file $ [[ -a kls.ksh ]] || print no such file no such fileThe ksh -c syntax in the above example is used when executing Ksh commands from another shell and is omitted when the test is performed with Ksh shell.
| Korn Shell Test Operators | |
| -a | exists |
| -b | block special file |
| -c | character special file |
| -d | is directory |
| -e | exists |
| -f | is regular |
| -g | setgid bit set |
| -G | matches group ID of current process |
| -k | sticky bit set |
| -L | symbolic link |
| -n | nonzero length string |
| -o | true if named option is on |
| -O | same UID as process |
| -p | FIFO special file |
| -r | readable |
| -s | size > 0 |
| -S | socket |
| -t | open and associate to terminal file descriptor |
| -u | user-id bit is set |
| -w | writable |
| -x | executable |
| -z | zero length string |
| -ef | file1 is another name for file2 |
| -nt | file1 newer than file2 |
| -ot | file1 older than file2 |
Test can be done also on open files using file descriptor:
$ [[ -r /dev/fd/0 ]] && print read read $ exitKorn shell supports also Fortran like test operators for integer variables:
-eq -ne -le -lt -ge -gt
Ksh control structures are:
case value in # Bourne compatible case
pat1: ...
... ;;
::::
patn: ...
... ;;
esac
Match patterns can be used in case structures. Supported patterns are:
Multiple patterns are specified as (@([a-z])a lowercase character@([1-9])*([0-9])any number starting with 1
pat1 | pat2 | pat3), match
criteria are:
for var in word1 word2 .... wordn?zero or one occurence*zero or more occurences@exactly one occurence+one or more occurences! all strings except pattern
#Bourne compatible
for
......
for var in $* for var in "$@" for varOne line for abbreviated form is:
for var in ....; do .....; doneExamples of for and if:
> cat kgrep
#!/bin/ksh
#-----------kgrep: search string in all files with header
#-----------usage: kgrep "search string" files
#
echo
PWD=`pwd`
SRC=$1 #set SRC="search string"
shift #shift 1 argument
for FILE #loop over files pointed by the for variable FILE
do
FOUND=`grep "$SRC" $FILE`
if [[ $? = 0 ]]
then
print "*********************"
print $PWD"/"$FILE
print ""
print $FOUND
print ""
fi
done
#----------end script------------------
> kgrep include *.f
*********************
/user/james/fdev/init.f
include 'COM.INC'
include 'DAT.INC'
*********************
/user/james/fdev/array.f
include 'COM.INC'
> grep -l ksh d* ka*
init.f
array.f
Compare kgrep output with grep -l output that is more brief and
easy to read, but prints only routine names missing multiple lines matching the
search substring.
In the if command the conditional clause is expressed in the double
bracket form and execution is triggered by the true (=0) or
false (=1) result of the condition.
Do not forget <space> separators with square
brackets operators.
if [[ .... ]]
then
.....
fi
One line if is achieved with one of the forms:
if [[ cond ]] ; then ......; fi
((cond)) && { ....; ....; }
[[ cond ]] && { ....; ....; }
The two forms differ for the usage of the <space> characters to delimit
test fields. An example of test on numargs with
the two syntax forms is:
(($# < 1)) && { print "Usage: $0 args"; exit 1; }
[[ $# < 1 ]] && { print "Usage: $0 args"; exit 1; }
The full if form is:
if ((...))
then
.....
elif ((...))
then
.....
else
.....
fi
Other Korn shell loop commands are while and until that operates
the reverse test. The while and until syntax is explained below.
while ((cond)) until [[ cond ]] do do ..... ...... done doneThe one line while and until forms for the loop forever condition are:
while true; do ....; done until false; do ....; doneLoop conditions are exited with break n where
for i in a b c
do
for j in x y
do
((i == b && j == y))
then
break 2
else
.....
fi
done
done
label: .....
#---------------end script-------------
In the above example break 2 transfers control to label:. To interrupt only the inner loop use break. If only a warning condition is detected, use continue instead of break. When implementing loops insert a read statement in critical points to enable loop interruption and script check in case of errors generating endless loops. An example of break and continue is given below.
#!/bin/ksh
#-----------kcond: job control commands with Korn shell
echo Proc $0: if/while/... in Korn shell
echo
(($# >= 1)) && { print "Logged users:\n`who`"; exit 0; }
#
nus=$(who | wc -l)
if ((nus == 1))
then
print "1 user logged"
elif ((nus == 2))
then
print "2 users logged"
else
print ">2 users logged"
fi
#----------------B R E A K-------------------
echo ""
#
set +x #set trace off
#
set -A rgb R G B Y M C
echo "while example on rgb array ${rgb[*]} - <ret> for next item - break at Y"
((i=0))
while true
do
read RET
if ((i == 3))
then
print "break point reached: i should be = 3 and rgb = Y"
print "break values are: rgb[$i] --> ${rgb[i]}"; break
else
print {$i}-eth RGB item is ${rgb[i]}; ((i=i+1));
fi
done
#----------------C O N T I N U E-------------------
echo "--------------------------"
echo "while example on rgb array ${rgb[*]} - <ret> for next - continue at Y"
((i=0))
while ((i <= 5))
do
read RET
if ((i == 3))
then
print "continue point reached: i should be = 3 and rgb = Y !!!!!"
print "continue loop for remaining colors\n";
print {$i}-ETH rgb ITEM IS ${rgb[i]}; ((i=i+1)); continue
else
print {$i}-ETH rgb ITEM IS ${rgb[i]}; ((i=i+1));
fi
done
#---------------------------------------------------------
Command set +x can be changed in set -x to debug script. Note the
statements that protects script from infinite loops. A
<ret> is enough to procede, <ctrl>c interrupts the script. The
script produces the following output.
> kcond
Proc kcond: if/while/... in Korn shell
1 user logged
while example on rgb array R G B Y M C - <ret> for next item - break at Y
{0}-eth RGB item is R
{1}-eth RGB item is G
{2}-eth RGB item is B
break point reached: i should be = 3 and rgb = Y
break values are: rgb[3] --> Y
-----------------------------------
while example on rgb array R G B Y M C - <ret> for next - continue at Y
{0}-ETH rgb ITEM IS R
>
A very simple way to generate
select menu_var in CHOICE1 ..... CHOICEn do ...... doneThe select command displays the enumerated menu item list followed by the
#? prompt waiting for item value. Prompt value can be set:
$ typeset -x PS3="my pmpt>"
The user types the no. corresponding to the menu item. The typed number is
stored in the builtin variable REPLY, while the select menu item is
stored in the user variable of the select command.
Example:
#--------------------------------------------------------------
> cat kmenu
echo "Proc $0: select (menu) in Korn shell"
echo
typeset -x PS3="Command: "
select i in PAGE PWD DIRSIN DIR END
do
if [[ $i = END ]]
then
print "Exit option"; exit 0
fi
print "Selection item $REPLY: $i"
case $i in
PAGE*) page $0;;
PWD*) pwd;;
DIRSIN*) dirsin;;
DIR*) dir;;
esac
done
#----------------------------------------------------------------
> kmenu
Proc kmenu: select (menu) in Korn shell
1) PAGE
2) PWD
3) DIRSIN
4) DIR
5) END
Command: 3
Selection item 3: DIRSIN
Mar 10
-rwxr-xr-x 1 mary users 380 Mar 10 12:03 kgrep
Total of 1 files, 0 blocks
Command: 5
Exit option
>
The menu choice list can be given as script arguments with:
select menu_var; do ....; done or select menu_var in "$@"; do ....; done
| Korn Shell Print Escape Characters | |
\a |
bell |
\b |
backspace |
\c |
do not write newline (use for prompts) |
\f |
formfeed |
\n |
linefeed |
\r |
return |
\t |
tab |
\v |
vertical tab |
\\ |
backslash |
\0x |
up to 3 digits octal no. |
| Print Options | |
| - | treat eveything following - as an argument |
| -n | do not add newline |
| -p | redirect arguments to co-process |
| -r | ignore escape conventions |
| -R | ignore escape; do not interpret -args as options (except -n) |
| -s | redirect arguments to history |
| -un | redirect arguments to file descriptor n |
| (default 1, if >3 must be first opened with exec) | |