One line of shell code can be "commented out" using the
"#" character. Sometimes however it would be nice to "comment out"
more than one line of code, like the C "/* */" comments.
One way to comment out multiple lines is this:
: '
,,,,,,
'
After the ":" command (that returns "true") the rest of the code
is a large string constant enclosed within 'single quotes'.
Of course this works only if the code "commented-out" does
not contain single quotes.

Another way to comment out multiple lines of code is the "here document"
way:
: << --END-COMMENT--
your comment here
--END-COMMENT--
This way, there is no restriction with single quotes. Note that any delimiter
can be used in place of "--END-COMMENT--".
(tested with bash 2.05a)

I've seen too many scripts using massive number of tmp files, which
is wrong in its self.
But not only that, people tend to clean them up one at a time in a fashion
such as
if [ -a ${tmpFile} ]; then
rm ${tmpFile};
fi
This, when you use up to 10 or even 5 tmp files gets nasty. A quicker way
of cleaning
up such tmp files is to use a simple loop, I even perfer to use array's
which are
availible in Korn shell. Here is an example.
clean()
{
tmpfiles[0]=${temp1}
tmpfiles[1]=${temp2}
for file in ${tmpfiles[*]}
do
if [ -a ${file} ]; then
rm ${file}
fi
done
This way, as you accumulate more and more tmp files, you need only to add
one line to get it cleaned up.

[This tip was first published within the SHELLdorado Newsletter 1/99]
For some shell scripts it would be desirable, if the script
could position the cursor to arbitrary (row, column) pairs
(i.e. to display a status line, ...)
The following shell function uses the "tput" command to
move the cursor to the specified (row, column) position:
# move cursor to row $1, col $2 (both starting with zero)
# usage: writeyx message rowno colno
writeyx () {
tput cup $2 $3
echo "$1"
}
Example usage:
clear # clear the screen
writeyx "This is a centered message" 11 26
writeyx "press any key to continue..." 22 0
read dummy
The "tput" comm!
and looks up the escape command sequence for
a feature needed for the current terminal. You can use it
for other terminal related things, too:
tput smso # "start mode shift out": usually
# reverse
echo "This is printed reverse"
tput rmso # "reset mode shift out"
All available capability names are listed on the terminfo(5)
manual page.
Portability:
The "tput" command is available with the "terminfo"
terminal information database

In shell scripts it's often useful to
provide default values for script variables, i.e.
if [ -z "$Host" ]
then
Host=`uname -n`
fi
For this kind of assignment the shell
has a shorthand:
: ${Host:=`uname -n`}
This means: if the variable "Host" is
not already set, execute the command
"uname -n" and set the variable to
the returned value.

Sometimes its convienient to have a file
read into memory to work on it. The
form that you take to accomplish this is
an array data structure. In ksh88 the
maximum is 1024 elements, however, on
some of the more modern versions you can
go much higher.
To do this the following can be done:
#/usr/bin/ksh
typeset -i cnt=0
while read line
do
myarray[$cnt]=$line
((cnt = cnt + 1))
done < myfile
# end of file---------
Now, if I want to access any line of that
file, I simply use:
${<arrayname>[<subscript>]}
echo ${myarray[4]}
This is useful for parsing, or for interactive
use of of the file's contents. I have
all !
of the lines of the file available in
the array, and I can move around in them,
select the ones I want.
Look at the following example:
#!/usr/bin/ksh
typeset -i cnt=0
while read line
do
myarray[$cnt]=$line
((cnt = cnt + 1))
done < myfile
PS3="Select a number: "
select linefromfile in ${myarray[@]}
do
echo $linefromfile
done
# end of file------------
There are many other uses for this techique.
Dynamic menus
numeric error message reference
getting mulitple specific lines of a file
in a single pass
Have fun.

The full name of each user is available in the /etc/passwd file. If you
would like to use the full name in your script instead of $LOGNAME,
which simply returns the user's login name, you can declare the following
variable in your script:
fullname=`grep $LOGNAME /etc/passwd | cut -f 5 -d :`
If you only want the first name, you would declare this variable:
firstname=`grep $LOGNAME /etc/passwd | cut -f 5 -d : | cut -f 1 -d " "`

Since the full name is the 5th column
of the file /etc/passwd, it's easy
to look up the full name for a
login name like "joe":
awk -F: '$1 == name {print $5}' name=joe /etc/passwd
The option "-F" tells awk to use ":" als field
separator (instead of whitespace).

[Note: the following examples will work only with standard
ksh implementations. They will not work with the Linux Korn
Shell pdksh.]
Most Korn Shells (/bin/ksh) have sparsely documented, build-in
networking functions.
Example:
$ date=
$ read date < /dev/tcp/127.0.0.1/13
$ echo $date
Wed Feb 10 00:45:39 MET 1999
This command opens a TCP connection to the IP address 127.0.0.1
(the local loopback IP address), and connects to the port "13"
(daytime, see /etc/services). The current date and time is
returned, and assigned to the variable "date".
Note that the "/dev/tcp/*" directories do not have to exist;
the file names are special to the Korn Shell and are interpre!
ted
by the shell internally. Only numerical ip addresses and port
numbers are supported; "read date < /dev/tcp/localhost/daytime"
does not work.

Script programmers sometimes have to process input that consists
of fields separated by whitespace, i.e.
field1 field 2 <TAB> <TAB> field3
This input has the disadvantage that it uses different combinations
of blank and TAB characters as input, and is hard to process using
"cut" and "sort", because these commands expect exactly one
field separator character.
The following "sed" line "normalizes" this input replacing each
sequence of two or more whitespace characters with exactly one
<TAB> character:
sed 's/ [ <TAB>][ <TAB>]*/<TAB>/g'
Substitute the five characters "<TAB>" with a "real" TAB character
(ASCII 9).
Further processing can be done using this <TAB> character
as field separator.

Most shell script programmers know the command
set -vx
to print each script command before execution. Sometimes
the following flags are useful, too:
set -e # terminate the script at first error
set -u # unset variables are fatal errors

Tracing can be enabled for a
KornShell script by using "set -x", but
this will have no effect on functions
within the script.
The following line will enable tracing
for all functions in a script:
typeset -ft $(typeset +f)
Note that this will not work for BASH.
[Idea is from Dan Mercer <dmercer@mn.rr.com>,
news group comp.unix.shell]

#!/usr/bin/ksh
#set -x
#-----VARIABLES
# You must comment out one of the two VAR lines below depending on whether
you want comments turned on or off in front of all your executable commands.
# The VAR line below, when uncommented, will comment out all commands with
$VAR in front of them
#VAR=": #"; export VAR
# The VAR line below, when uncommented, will allow execution of all commands
with $VAR in fron of them.
VAR=""; export VAR
#-----MAIN
$VAR date

A simple way, to find out yesterdays date:
#!/usr/bin/ksh
############################
### set the TZ env variable
############################
TZ=GMT+24
/usr/bin/date +%m%d%Y
TZ specifies the time zone in which the time and date are written. If you
set the time zone 24 hours forward, date will give yesterdays date back