16 The Environment



16.1 CDPATH

The CDPATH
variable is provided to make directory navigation easier. It contains a
list of colon-separated directories to check when a full pathname is
not given to the cd command. Each directory in CDPATH is searched from
left-to-right for a directory that matches the cd argument. A : alone
in CDPATH stands for the current directory.


16.2 PATH

The PATH
variable contains a list of colon-separated directories to check when a
command is invoked. Each directory in PATH is searched from
left-to-right for a file whose name matches the command name. If not
found, an error message is displayed. A : alone in PATH specifies to
check the current directory.


16.3 TMOUT

The TMOUT variable specifies the number of seconds that the Korn shell
will wait for input before displaying a 60-second warning message and
exiting. If not set, the default used is 0, which disables the timeout
feature. To set a 10-minute timer, set TMOUT to 600:
    $ TMOUT=600
This variable is usually set by the system administrator in the /etc/profile file.


16.4 MAILCHECK


The
MAILCHECK variable specifies how often, in seconds, to check for new
mail. If not set, or set to zero, new mail is checked before each new
prompt is displayed. Otherwise, the default setting is 600 seconds (10
minutes).


16.5 MAIL


The MAIL variable contains the name of a single mailbox file to check for new mail. It is not used if MAILPATH is set.


16.6 MAILPATH


The
MAILPATH variable contains a colon-separated list of mailbox files to
check for new mail and is used if you want to read multiple mailboxes.
It overrides the MAIL variable if both are set. This MAILPATH setting
specifies to check two mailbox files, /home/anatole/mbox and /news/mbox.
    $ print $MAILPATH

    MAILPATH=/home/anatole/mbox:/news/mbox

Just
so you don't think you can go snooping around someone else's mailbox,
this only works if you have read permission on the mailbox file.
If MAILPATH is not set, there is no default.


16.7 TERM


The
TERM variable specifies your terminal type, and is usually set by your
system administrator in the global /etc/profile file. If it's not set
there, then it's probably in your ~/.profile file.


16.8 Enabling/Disabling Options


Korn shell options are enabled with the set -ooption or set -option command. For example, the noglob option disables file name substitution and can be set using either of these commands :
    $ set —f

or

    $ set —o noglob
Options can also be enabled by specifying them on the ksh command line.
Here, a Korn subshell is started with the emacs option enabled:
    $ ksh —o emacs
Options can be disabled with the set +o option or set +option command. In this example, the noglob option is disabled:
    $ set +o noglob


16.9 Displaying the Current Settings


The setting of the current options is displayed with the set -o command.


16.10 Aliases


Aliases
are command name macros used as shorthand for other commands,
especially frequently used ones. This saves a lot of typing time.
Aliases are defined with the alias name=value
command.Make sure to
enclose the value in quotes if it contains whitespace. Here we create
an alias l that is set to the ls -Fac command:
    $ alias l="ls —Fac"
Now when you type in l, ls -Fac is executed:
    $ l

    ./

    ../

    compress.Z*

    func.Z*

    test/

    uncompress.Z*
    . . .

Alias values can contain any text, including special characters, like wild-cards, pipes, or I/O redirection operators.

Here we set two aliases: p and h. When invoked, we get h instead of Hello.
    $ alias p='print' h=Hello

    $ p h

    h
After the p alias is reset with a trailing blank, h gets substituted in the next command correctly:
    $ alias p='print ' h=Hello

    $ p h

    Hello


16.10.1 Displaying Current Aliases


A list of the current aliases is displayed using the alias command without arguments.


16.10.2 Removing Aliases


Aliases are removed with the unalias command. Let's try it with the l alias:
    $ unalias l


17 Korn Shell Scripts



17.1 Positional Parameters


Positional
parameters are special variables used to keep track of arguments to the
Korn shell, scripts, and functions. Positional parameter names contain
only digits and cannot be set directly using variable=value syntax. By default, parameter zero (or $0) is set to the name of the shell, script or function.
    $ print $0

    /bin/ksh
The remaining parameters 1 to n are set to each of the arguments passed
to the shell, script or function. For example, if you invoke a Korn
shell script called ptest and pass the arguments A, B, and C, then in the script ptest, $0 would be set to ptest, $1 to A, $2 to B, and $3 to C.

There are three special Korn shell variables that provide information about the current positional parameters. The first is $#, and it contains the number of positional parameters. The other two are $@ and $*, and they both contain all the positional parameters.
So in the above ptest example, $# would be 3, and both $* and $@ would
be A B C. Here is a Korn shell script that manipulates positional
parameters. It displays the name of the current script, the number of
positional parameters, and the value of each of the positional
parameters:
    $ cat check_params

    print "Script name: $0"

    print "Number of args passed: $#"

    print "Arguments passed: $*"

    print "Arg 1=$1, Arg 2=$2, Arg 3=$3"


17.2 Modifying Positional Parameters


By default, $0 is set to the name of the shell, script or function. It cannot be set or modified. The remaining parameters from $1 to $n can be reassigned with the shift
command. The shift command, with no arguments, shifts positional
parameters left once, so that $1 takes the value of $2, $2 takes the
value of $3, and so on. The original value of $1 is lost.
 
Let's change the check_params script so that it shifts the positional
parameters left once:
    $ cat check_params

    print "Script name: $0"

    print "Number of args passed: $#"

    print "Arguments passed: $*"

    print "Arg 1=$1, Arg 2=$2, Arg 3=$3"

    shift

    print "Number of remaining args: $#"

    print "Remaining args: $*"

    print "Arg 1=$1, Arg 2=$2, Arg 3=$3"
When we run it again with the arguments A B:
    $ check_params A B

    Script name: check_params

    Number of args passed: 2

    Arguments passed: A B

    Arg 1=A, Arg 2=B, Arg 3=

    Number of remaining args: 1

    Remaining args: B

    Arg 1=B, Arg 2=, Arg 3=
After the shift command, $1 is set to B and $2 is unset. The original value of $1 is lost.

The positional parameters can be shifted left more than once by providing an integer argument to the shift command: shift n.


17.3 The exit command


The exit command allows you to terminate execution from anywhere in a Korn shell script and return an exit value using this format:
        exit
or
        exit n
where n is the exit status to return. If n is not specified, the exit status of the previous command is used. If you don't use exit, then scripts finish after the last command is executed.


17.4 The [[...]] Command


The
[[...]] command is used to evaluate conditional expressions with file
attributes, strings, integers, and more. The basic format is:
        [[ expression ]]
where
expression
is the condition you are evaluating. There must be whitespace after the
opening brackets, and before the closing brackets. Whitespace must also
separate the expression arguments and operators. For example, these are
incorrect:
    [[$X=$Y]]

    [[$X = $Y]]
while this is correct:
    [[ $X == $Y ]]
Notice that there is white space between $X, $Y, and the = operator.

If the expression evaluates to true, then a zero exit status is
returned, otherwise the expression evaluates to false and a non-zero
exit status is returned.

If you are familiar with the test and [...]
commands, then you'll recognize that [[...]] is just a new and improved
version of the same commands. It basically functions the same way,
except that a number of new operators are available.


17.4.1 Checking Strings

We could use the [[...]] command to check if a variable is set to a
certain value. Here, variable X is assigned abc, then evaluated in this
expression:
    $ X=abc

    $ [[ $X = abc ]] && print "X is set to abc"

    X is set to abc
Using the test and [...] commands, the same command could be written as:
    test "$X" = abc && print "X is set to abc"
or
    [ "$X" = abc ] && print "X is set to abc"

To check if a variable is set to null, the -z option can be used:
    [[ —z $VAR ]] && print "VAR is set to null"
or it could be compared to the null string like this:
    [[ $VAR = "" ]] && "VAR is set to null"



17.4.2 Checking Patterns


The Korn shell also lets you compare strings to patterns. We could check if X begins with a 'a' like this:
    $ X=abc

    $ [[ $X = a* ]] && print "$X matches a*"

    abc matches a*

Using the +([0–9]) pattern, we could check if X is set to a number:
    $ X=123

    $ [[ $X = +([0—9]) ]] && print "$X is a number"

    123 is a number


17.4.3 Checking File Attributes


The most basic operation to perform on a file is to see if it exists, and that can be done using the -a operator.
    $ touch tmp

    $ [[ —a tmp ]] && print "File tmp exists"

    File tmp exists

This only indicates that it exists, but not much else. It may be a
directory, or a symbolic link, but using this operator, that's all we
know. If we wanted more information, the -f or -d operators could tell
us if a file existed and was a regular file (-f) or if it was just a
directory (-d).


17.4.4 Checking Integer Attributes

The [[...]] command provides a few integer operators that allow
integers to be compared. It is frequently used to check the number of
command-line arguments. This expression evaluates to true if there are
less than or equal to three positional parameters set:
[[ $# —le 3 ]] && print "3 or less args given"


The ((...)) command offers the same arithmetic comparison operators as
the [[...]] command, plus many others. Besides offering more arithmetic
operators, the ((...)) command provides substantial performance
improvements over the [[...]] and test commands.


17.4.5 The ! Operator


The ! operator negates the result of any [[...]] expression when used like this:
[[ ! expression ]]
For example, to check if X is not equal to abc:
    $ X=xyz

    $ [[ ! $X = abc ]] && print "$X not equals abc"

    xyz not equals abc

There is one logical operator that can only be implemented with the !
operator. There is no [[...]] file operator that will evaluate to true
on a zero-length file.
    $ >emptyfile

    $ [[ ! —s emptyfile ]] && print "emptyfile is empty"

    emptyfile is empty



17.4.6 Compound Expressions


(1) && - The AND Operator
The && operator is used with the [[...]] command to test if multiple expressions are true using this format:
    [[ expression1 && expression2 ]]


This expression checks if the noglob and noclobber options are set:
    [[ —o noglob && —o noclobber ]]

(2) || - The OR Operator
The | | operator is used with the [[...]] command to test if expression1 OR expression2 are true using this format:
    [[ expression1 | | expression2 ]]


17.4.7 [ [...] ] vs test and [...]

The [[...]] command is preferred to test and [...], since many of the errors associated with test and [...] do not occur.



18 Control Commands

18.1 The case command

The case command provides multiple-branch capability. The syntax for the case command is:


where value is compared to pattern1, pattern2, ... patternn.

The
same patterns used in file name substitution can also be used in case
statements to match patterns. The new Korn shell pattern matching
formats also allow multiple case patterns to be given like this:

18.2 The for Command

The basic syntax for the for command is:
        for variable in word1  word2 . . . wordn
        do
                  
 commands
        done

File name substitution, command substitution, and variable substitution
can also be used to generate a list of word arguments for the for
command. The first line of the previous command could have been given
as:
    for FILE in chap[1-3]
or
    for FILE in $(ls chap[1-3])
or
    CHAPS=$(ls chap[1-3])
    for FILE in $CHAPS

The $* and $@ variables can be used to loop on command-line arguments like this:
        for variable in $*
        do
                commands
        done

The for command can also be used without the list of word arguments:
        for variable

        do

                commands

        done

The commands are executed once for each positional parameter, and variable is set to each successive positional parameter. It is equivalent to:
       for variable in $@

        do

                commands

        done


18.3 The if Command

The basic syntax of the if command is:
        if command1
        then
                
commands
       
elif command2
        
 then
                commands
        else
               
commands
        fi


18.4 The while Command

        while command1
        do
                commands
        done

18.5 The until Command

The
until command is another looping command. It's like the while command,
except that instead of looping while the condition is true, it loops
while the condition is false. The syntax for the until command is:
        until command1
        do
                
commands
        done

where commands are executed until command1 returns a zero exit status.

18.6 Breaking Out of Loops

break command  causes an exit from a loop-type command, but not from the entire script.

The break command can also be used to exit from a nested loop using this format:
        break n
where  n specifies the nth enclosing loop to exit from.
Here is a new version of the nloop script that breaks out of both loops if i equals 2 and j equals 0:
$ cat nloop
for i in 1 2 3
do
    for j in 0 5
    do
        if ((i == 2 && j == 0))
        then
            break 2
        else
            print "$i$j"
        fi
    done
done

Now the output would be:
    $ nloop
    10
    15
If
break was used instead of break 2, then only the inner for loop would
have been terminated, and execution would have continued with i set to
3 in the outer loop, and j set to 0 in the inner loop.


18.7 The continue Command

The continue command causes execution to continue at the top of the current loop.

18.8 The select Command
The select command
is used to display a simple menu that contains numbered items, and a
prompt message. The syntax for the select command is:

        select variable in word1 word2 . . . wordn
        do
                
commands
        done

where word1 through wordn are displayed as numbered menu choices followed by a prompt (default #?).

If the response is in the range 1 through n, then variable is set to the corresponding word, REPLY is set to the response, and the commands are executed. Execution continues until a break, exit, return, or EOF is encountered.

18.8 The select Command

The
select command is used to display a simple menu that contains numbered
items, and a prompt message. The syntax for the select command is:

        select variable in word1 word2 . . . wordn

        do

                commands

        done

where word1 through wordn are displayed as numbered menu choices followed by a prompt (default #?). If the response is in the range 1 through n, then variable is set to the corresponding word, REPLY is set to the response, and the commands are executed. Execution continues until a break, exit, return, or EOF is encountered.

The select command can also be used without the list of word arguments:

       select variable

        do

                commands

        done

It
functions the same way as the previous select syntax, except that the
positional parameters are displayed as numbered menu choices from 1 to
n, instead of the words from the word list. It is equivalent to:
       select variable in "$@"

        do

                commands

        done