## 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

## 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

$[[ —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 donewhere 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