UNIX / Korn Shell programming

Home | UNIX | Practical

Korn Shell programming

KSH common : pbraun.nethence.com/doc/shells/ksh.html
KSH93 : pbraun.nethence.com/doc/shells/ksh93.html
KSH88 : pbraun.nethence.com/doc/shells/ksh88.html
PDKSH : pbraun.nethence.com/doc/shells/pdksh.html
KSH programming : pbraun.nethence.com/doc/devel/ksh.html


KSH menus
Intead of dealing with the menu numbers, do something like this,
select CHOICE in SystemBackup ListActiveUsers ManageDatabase MonitorPerformance Quit
do
case $CHOICE in
SystemBackup) mksysb -i /dev/rmt0;;
ListActiveUsers) who;;
ManageDatabase) svrmgr;;
MonitorPerformance) topas;;
Quit) exit;;
*) echo "\nInvalid Choice\n";;
esac
done
Use e.g. choice 2 when trying it out.
Note this should work for any version of KSH, even KSH88.
Ref. users.ca.astound.net/baspence/AIXtip/select.htm


Note you may do curse menus with KSH93, but this may not work with KSH88 (HP/UX & AIX),
www.ibm.com/developerworks/aix/library/au-shellcurses/
www.mtxia.com/css/Downloads/Scripts/Korn/Functions/
Shell Curses Source : www.mtxia.com/css/Downloads/Scripts/Korn/Functions/shcurses/
French menus source : www.mtxia.com/css/Downloads/Scripts/Korn/Functions/frenchMenus/


KSH programming tips
ksh93 understands "==",
[[ ${entries[0]} == $'*' ]] && return 2

The well known bashian roulette also works with ksh93 (without the first $),
((RANDOM%6)) || echo ok


Visual effects
For a white prompt background,
PS1=$'\e[7m$(hostname -s)\e[0m '
Colors,
g=$(printf '\33[1m\33[32m')  # similar to g=$(tput bold; tput setaf 2)
n=$(printf '\33[m')    # similar to n=$(tput sgr0)
${g}Green Light$n
Ref. home.nyc.rr.com/computertaijutsu/ksh.html


Propellers and progress bars
a) Propellers
Good thing with a propeller, you don't need to know the end marker, for example how many lines you're expecting.
Here's an awk script to turn the propeller for each line, and print a dot on each 1000 lines,
fprop() {
awk '
BEGIN {split("|#/#-#\\", p, "#"); i = 1; x = 1}
{
x++
if (x > 1000) {printf("."); x = 1};
printf("%c\b", p[i++]);
if (i > 4) {i = 1;};
}
END {printf(" termine\n");}'
}
Here's the original propeller function (I don't remember where I've got it from. From GNU sh-tools I think,
fpropdist() {
prefix=$1
awk '
BEGIN {split("|#/#-#\\", p, "#"); i = 1;}
{printf("%s%c\b", prefix, p[i++]); if (i > 4) {i = 1;}}
END {printf("%s \n", prefix);}' "prefix=$1"
}
Ref. www.gnu.org/software/shtool/ & ftp.gnu.org/pub/gnu/shtool/

Another way to do it (thanks #awk chan on freenode),
function fprop2 {
twirl_loop=0
while true; do
twirl_loop=`expr $twirl_loop + 1`
case $twirl_loop in
1) echo "|\b\c";;
2) echo "/\b\c";;
3) echo "-\b\c";;
4) echo "\0134\b\c"; twirl_loop=0;;
esac
sleep 1
done
return $twirl_loop
}

b) Progress bars
NetBSD : progress.unixdev.net/ & cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/progress/
clpbar.sourceforge.net/
Perl : search.cpan.org/dist/Term-ProgressBar/
www.theiling.de/projects/bar.html
progress.unixdev.net/

wget like progress bar for cp,
#!/bin/sh
cp_p()
set -e
strace -q -ewrite cp -- "$ 1 " "$ 2 " 2>&1 \
awk '
   count += $NF
if (count % 10 == 0)
percent = count / total_size * 100
printf "%3d%% [", percent
for (i=0;i<=percent;i++)
printf "="
printf ">"
for (i=percent;i<100;i++)
printf " "
printf "]\r"
END print "" ' total_size=$(stat -c '%s' "$ 1 ") count=0
Ref. chris-lamb.co.uk/2008/01/24/can-you-get-cp-to-give-a-progress-bar-like-wget/

Another one,
#!/bin/sh
#
# cpbar -- era 2008-05-21 for unix.com
#
# Depends:
# stat
# cp
# awk

syntax () {
echo "Syntax: $0 srcfile destfile" >&2
echo " " "$@" >&2
exit 1
}

test -r "$1" || syntax "File '$1' not found"
test -d "$2" && syntax "Must name destination file ('$2' is a directory)"

size=`stat -c %s "$1"`

cp "$1" "$2" &
cppid=$!

trap 'echo; kill $cppid; rm -f "$2"; exit 127' 1 2 3 5 15

while true; do
nsize=`stat -c %s "$2"`
awk -v f1="$1" -v f2="$2" -v size=$size -v nsize=$nsize '
  BEGIN { printf "Copying %s to %s: %4.2f%%\r", f1, f2, 100*nsize/size }'
case $nsize in $size) break ;; esac
sleep 1
done

echo

wait $cppid

Another way, www.linuxquestions.org/questions/programming-9/dialog-gauge-how-to-display-progress-of-compile-broken-pipe-problem-200614/


Misc tips
Debugging,
set -x
# or -o xtrace
Time,
CMD="echo PWET | bzip2 > /tmp/export.bz2"
/usr/bin/time -p $CMD
Note there's no 'source' command with KSH. You need to source like for example,
. ./.profile


References
Resources : www.shelldorado.com/links/
Guide : www.dartmouth.edu/~rc/classes/ksh/
KSH88 Manual : www.cs.princeton.edu/~jlk/kornshell/doc/man88.html
KSH93 Manual : www.cs.princeton.edu/~jlk/kornshell/doc/man93.html
PDKSH Manual : www.cs.mun.ca/~michael/pdksh/pdksh-man.html


Sat Nov 8 12:19:47 CET 2008
       © 2008 Pierre-Philipp Braun