The more useful functions in ksh I find are:
val=1 func(){ typeset val=2 echo val in func is $val } func echo after func, top level val is still $val
will set the variableread varname
varname
to have the value of the next
line read in from standard input.
What often comes next, is
This sets the argument variables $1, $2, etc to be set as if the program were called with $varname as the argument string to the shellscript. So, if the value of varname is "first second third", then $1="first", $2="second", and $3="third".set $varname
Note that if you want to access "double-digit" arguments, you cannot use "$10". it will get interpreted as "$1,""0". To access argument #10 and higher you must explicitly define the limits of the variable string, with braces:
echo ${10}This is also good to know, if you wish to follow a variable immediately followed by a string. Compare the output from the following lines:
a="A " echo $astring echo ${a}string
if [[ $? -ne 0 ]] ; then echo status is bad ; fi if [[ "$var" != "good" ]] ; then echo var is not good ; fi if [[ ! -f /file/name ]] ; then echo /file/name is not there ; fi if [[ ! -d /dir/name ]] ; then echo /dir/name is not a directory ; fi
One large difference is that filename wildcard expansion will be done with the standard test. In contrast, filename wildcard expansion does not work within [[]]. It does string wildcarding instead, and only on the right side. Additionally, it must not be quoted in any way (unlike case statements)
Examples:
if [[ a* == "astring" ]] ; then echo this does not work ; fi if [[ "astring" == "a*" ]] ; then echo this does not work ; fi if [[ "astring" == 'a*' ]] ; then echo this does not work ; fi if [[ "astring" == a* ]] ; then echo this works ; fi if [[ "astring" = a* ]] ; then echo this works ; fi
The math evaluator is very useful. Everything inside the double-parens gets evaluated with basic math functions. For example;
four=$((2 + 2)) eight=$(($four + 4)) print $(($four * $eight)) # Inside (()), the $ is optional, so the following works... # but you might want to keep them for assorted reasons.. print $((four * eight)) # even hex to decimal conversions print $((0xff))
This next example isnt exactly a math routine, but it is a very handy and fast builtin method to go the other way, from decimal to hex (since 'printf' is a ksh builtin function):
Warning #1: Some versions of ksh allow you to use floating point with $(()). Most do NOT. Warning #2: ksh is very strict about what goes inside the (( )). Every variable you use must have a value, and it must be a numeric value. Otherwise, ksh will most likely treat that line in your script as a failed function call.printf "%x\n" 255 #this prints out "ff" printf "%.4x\n" 255 #or if you need a fixed field width number use this
# function to emulate awk '{print $2}' sh_awk(){ while read one two three ; do print $two done } # and now, compare the speed of the two methods time sh_awk </usr/dict/words >/dev/null time awk '{print $2}' </usr/dict/words >/dev/null
The awk version will be much much faster. This is because ksh scripts are interpreted, each and every time it executes a line. AWK, however, loads up its programming in one go, and figures out what it is doing ONE TIME. Once that overhead has been put aside, it then can repeat its instructions very fast.