date and time created 88/07/21 17:32:09 by marc
authorMarc Teitelbaum <marc@ucbvax.Berkeley.EDU>
Fri, 22 Jul 1988 08:32:09 +0000 (00:32 -0800)
committerMarc Teitelbaum <marc@ucbvax.Berkeley.EDU>
Fri, 22 Jul 1988 08:32:09 +0000 (00:32 -0800)
SCCS-vsn: local/toolchest/ksh/sh.memo 1.1

usr/src/local/toolchest/ksh/sh.memo [new file with mode: 0644]

diff --git a/usr/src/local/toolchest/ksh/sh.memo b/usr/src/local/toolchest/ksh/sh.memo
new file mode 100644 (file)
index 0000000..ba7f65d
--- /dev/null
@@ -0,0 +1,2178 @@
+.nr N 2
+.PF "'Copyright (c) 1984, 1985, 1986, 1987''AT&T All Rights Reserved'"
+.SA 1  \"  right justified
+.TL "311531-0101" "49059-6"  \" charging case filing case 
+Introduction to KSH-I ( Issue 3)
+.AU "David G. Korn" DGK MH 59554 7975 5D-112 "(ulysses!dgk)"
+.TM  59554-860602-04  \"  technical memo + TM numbers
+.AS 1   \" abstract start for TM 
+Ksh-i is a command language (shell) for the UNIX*\ 
+.FS  *
+UNIX is a trademark of Bell Laboratories.
+.FE
+operating system.
+It is essentially compatible with the System V version of the Bourne shell\*(Rf ,
+.RS
+S. R. Bourne,
+.I "An Introduction to the UNIX
+Shell,"
+BSTJ - Vol. 57, No. 6 part 2, pages 1947-1972.
+.RF
+has many additional features,
+such as those found in
+.IR Csh\*(Rf ,
+.RS
+W. Joy,
+.I "An Introduction to the C Shell,"
+University of California, Berkeley, 1980.
+.RF
+and executes faster than either of these shells.
+This memo introduces many of the additional features
+and explains some of the reasons for the better
+performance.
+This memo
+assumes that the reader is already familiar with the Bourne shell.
+The Appendix contains
+a sample script written in Ksh-i.
+The manual page for the current version is also included.
+.AE   \" abstract end
+.OK Shell "Command interpreter" Language UNIX  \" keyword
+.MT 1  \"  memo type
+.H 1 "Introduction"
+.P
+Over the past several years several papers
+have been written describing new command interpreters
+for the UNIX system.
+These papers can be divided into two categories:
+Those that improve the shell as a programming language,
+and those that improve the shell as a command interpreter.
+Most of the papers fall into the latter category.
+In particular,
+.IR vicmd \*(Rf
+.RS
+S. L. Arnold,
+.I "Vicmd a Visual Shell for Video Terminals,"
+TM-81-54533-12, 1981.
+.RF
+preserves the friendly environment of
+.I vi
+(from which this memo was entered),
+and adds a facility for convenient command entry.
+An
+.I emacs
+oriented shell
+has also been written by Veach\*(Rf.
+.RS
+J. L. Steffen and
+M. T. Veach,
+.I "The Edit Shell - Connecting Screen Editing with the History List,"
+USENIX Association Toronto Proceedings, 1983.
+.RF
+The
+.IR 2dsh \*(Rf
+.RS
+M. J. Rochkind,
+.I "2dsh - An Experimental Shell for Connecting Processes With Multiple Data Streams,"
+TM-80-9323-3.
+.RF
+shell allows the setup of more complicated networks of processes than
+just pipelines.
+The never developed
+.IR See-shell \*(Rf
+.RS
+Wayne T. Wilner,
+.I "See-Shell: a Graphical User-Interface for UNIX Systems,"
+Bell Laboratories internal memorandum, 1982.
+.RF
+proposes a Small-Talk like interface\*(Rf
+.RS
+D. C. Smith, C. Irby, R. Kimball, and B. Verplank,
+.I "Designing the Star User Interface,"
+BYTE, April, 1982, pp. 242-282.
+.RF
+suitable for bit-mapped terminals such as the BLIT\*(Rf
+.RS
+R. Pike,
+.I "The Blit Programmer's manual,"
+Bell Labs, 1982.
+.RF
+and the Apollo\*(Rf.
+.RS
+P. J. Leach,
+P. H. Levine,
+B. P. Douros,
+J. A. Hamilton,
+D. L. Nelson,
+and B. L. Stumfp,
+.I "The Architecture of an Integrated Local Network,"
+IEEE Journal of Selected Areas in Communications,
+Local Area Networks Special Issue, November 1983.
+.RF
+Perhaps the most widely used shell,
+other than the Bourne shell, is
+.IR Csh ,
+which runs under the Berkeley UNIX operating system.
+Csh has many attractive command interpreter features
+not currently in the Bourne shell;
+most notably, job control,
+history,
+arithmetic,
+and command name aliasing.
+On the other hand,
+many people (including this author),
+think that the Bourne shell is superior as a programming language.
+The history mechanism of Csh has recently been added as a local modification
+to the Bourne shell by
+J. L. Steffen\*(Rf.
+.RS
+J. L. Steffen,
+.I "An Input History for the Bourne Shell,"
+TM-82-55426-3, 1982.
+.RF
+.P
+The use of the shell as a programming language has been
+described by Dolotta and Mashey\*(Rf
+.RS
+T. A. Dolotta and J. R. Mashey,
+.I "Using the shell as a Primary Programming Tool,"
+Proc. 2nd. Int. Conf. on Software Engineering, 1976,
+pages 169-176.
+.RF
+and has been used by many people here
+at Bell Laboratories.
+Kolettis\*(Rf
+.RS
+N. J. Kolettis.
+.I "Extended Shell - A Potential Real Time Interpreter,"
+TM-77-4145-01, 1977.
+.RF
+presented extensions to the Bourne shell to provide
+message passing facilities and other inter-process communication and
+synchronization features.
+The Form shell\*(Rf
+.RS
+D. G. Korn and D. A. Lambeth,
+.I "Form Shell,"
+TM-80-9224-3, 1980.
+.RF
+added form entry/edit capabilities to the Bourne shell.
+A proposal for a more programming language oriented shell has
+been proposed by Sturzenbecker\*(Rf.
+.RS
+M. C. Sturzenbecker,
+.I "A New Command Language for UNIX and related systems,"
+TM-82-45192-3.
+.RF
+.P
+This memo describes
+.IR Ksh-i ,
+aka Korn shell-international.
+This memo is not a tutorial, only an introduction.
+A description of the
+.IR Korn shell
+can be found in Kochan and Wood\*(Rf.
+.RS
+S. G. Kochan and P. H. Wood,
+"Unix Shell Programming,"
+Hayden Book Company, 1985.
+.RF
+Ksh-i is a direct descendant of the
+Form shell
+with most of the
+form entry/edit features removed and with many new
+features added.
+The primary focus of this work has been to provide an
+enhanced programming environment in addition
+to the major command entry features of
+.IR Csh .
+Improved performance has been a major objective.
+Many of the additions have been provided so that
+medium sized programming tasks can be written
+at the shell level without a serious performance
+penalty.
+A concerted effort has been made to achieve System V Bourne shell
+compatibility so that scripts written for the Bourne shell
+can run without modification with Ksh-i.
+The description of features in this memo assumes
+that the reader is already familiar with the Bourne shell.
+.P
+A version of Ksh-i has been run on several machines
+including but not limited to VAXEN , PDP-11's, IBM-370's,
+AT&T 3B's, UNIX-PC, PC-6300+, Suns, Alliant, CCI, Sequent,
+Pyramid, and Apollo Domain.
+It has been run on top of several versions of the UNIX operating system including
+Venix, Xenix, System III, System V, UTS,
+BSD 4.1, 4.2, 4.3, 8th. Edition, and DOMAIN/IX.
+The shell is in use in several centers at AT&T Bell Laboratories,
+and has been installed as
+.I /bin/sh
+on  VAXEN running System V, BSD 4.1., BSD 4.2,
+3B's, PC-6300+,  and UNIX-PC's running System V.
+.H 1 "Shell Variables"
+.P
+The ability to define and use variables to store and retrieve values
+is an important feature in most programming languages.
+Ksh-i has variables with
+.I identifier
+names that follow the
+same rules as the Bourne shell.
+Since all variables have string representations,
+there is no need to specify the
+.I type
+of each variable in the shell.
+In Ksh-i,
+each variable can have one or more
+.I attributes
+that control the internal representation of the variable,
+the way the variable is printed, and its access or
+scope.
+Two of the attributes,
+.I readonly
+and
+.IR export ,
+are available in the Bourne shell.
+The
+.B typeset
+built-in command of Ksh-i
+assigns attributes to variables.
+The complete list of attributes,
+some of which are discussed here,
+appears in the manual page.
+The
+.B unset
+built-in of the Ksh-i removes
+values and attributes of parameters.
+.P
+Whenever a value is assigned to a variable,
+the value is transformed according to the attributes of the variable.
+Changing the attribute of a variable can change its value.
+There are three attributes for field justification,
+as might be needed for formatting a report.
+For each of these attributes, a width can be defined explicitly  or else
+it is defined the first time an assignment is made to the variable it
+Each assignment causes justification of the field, truncating
+if necessary.
+Assignment to fixed sized variables
+provides a simple way to generate a substring consisting of
+a fixed number of characters from
+the beginning or end of a string.
+.P
+The attributes
+.B \-u
+and
+.BR \-l ,
+are used for upper case and lower case
+formatting respectively.
+Since it makes no sense to have both attributes on simultaneously,
+turning on either of these attributes turns the other off.
+The following script provides an example of the use of shell variables
+with attributes.
+This script reads a file of lines each consisting of five fields separated by
+.B :
+and prints fields 4 and 2 in upper case in columns 1-15, left justified,
+and columns 20-25 right-justified respectively.
+.sp
+.nf
+.in .5i
+.ta 3.4i
+.B
+typeset \-L15u f4              # 15 character left justified
+typeset \-R6u f2               # 6 character right justified
+IFS=:
+set \-f                        # skip file name generation
+while   read \-r f1 f2 f3 f4 f5        # read line, split into fields
+do      print \-r "$f4    $f2"         # print fields 4 and 2
+done
+.fi
+.ta
+.in
+.sp
+.R
+.P
+The integer attribute,
+.BR \-i ,
+causes the variable to be internally represented as an integer.
+The
+.B i
+can be followed by a number representing the numeric base for printing, otherwise
+the first assignment to an
+.I integer
+variable defines the output
+.I base
+(see below).
+This base will be used
+whenever the variable is printed.
+Assignment to
+.I integer
+typed variables result in arithmetic evaluation,
+as described below,
+of the right hand side.
+.P
+Ksh-i allows one-dimensional
+.I arrays
+in addition to simple variables.
+Any variable can become an array
+by referring to it with
+a
+.IR subscript .
+All elements of an array need not exist.
+Subscripts for arrays
+must evaluate to an
+integer between 0 and 511, otherwise
+an error results.
+Evaluation of subscripts is described in
+the next section.
+Attributes apply to the whole array.
+.P
+Assignments to array variables can be made with parameter assignment statements
+or with the
+.B typeset
+built-in.
+Referencing of subscripted variables requires the character
+.BR $ ,
+but also requires braces around the array element name.
+The braces are needed to avoid conflicts with the
+file name generation mechanism.
+The form of any array element reference is:
+.ce
+.BI ${ name [ subscript ]} .
+A subscript value of
+.B *
+or
+.B @
+can be used to generate all elements of an array,
+as they are used for expansion of positional parameters.
+.P
+A few additional operations are available on shell variables.
+\f3${#\fP\f2name\fP\f3}\fP
+will be the length in bytes of
+\f3$\fP\f2name\fP.
+For an array variable
+\f3${#\fP\f2name\fP\f3[*]}\fP
+gives the number of elements in the array.
+.P
+There are four parameter substitution modifiers that
+have been added to strip off leading and trailing substrings
+during parameter substitution.
+The modifier
+.BR # ( ## )
+strips off the smallest (largest) matching pattern from the left
+and the modifier
+.BR % ( %% )
+strips off the smallest (largest) matching pattern from the right.
+For example, if the shell variable
+.B i
+has value
+.BR file.c ,
+then the expression
+.B ${i%.c}.o
+has value
+.BR file.o .
+.H 1 "Arithmetic Evaluation"
+.P
+The built-in command,
+.B let ,
+provides the ability to do integer arithmetic.
+All arithmetic evaluations are performed using
+.I long
+arithmetic.
+Arithmetic constants are written as
+.br
+.ce
+.IB base # number
+where
+.I base
+is a decimal integer between
+two and thirty-six and
+.I number
+is any non-negative number.
+Anything after a decimal point is truncated.
+Base ten is used
+if no base is specified.
+.P
+Arithmetic expressions are made from constants,
+variables, and one or more of the fourteen operators
+listed in the manual page.
+Operators are evaluated in order of precedence.
+Parentheses may be used for grouping.
+A variable does not have to have an integer attribute
+to be used within an arithmetic expression.
+The name of the variable is replaced
+by its value within an arithmetic
+expression.
+The statement
+.ce
+.B
+let x=x+1
+.R
+can be used to
+increment a variable
+.BR x .
+Note that there is no space before or after the operators
+.B +
+and
+.BR = .
+This is because each argument to
+.B let
+is an expression to evaluate.
+The last expression determines
+the value returned by
+.BR let .
+Let returns true
+if the last expression evaluates to a non-zero value.
+Otherwise,
+.B let
+returns false.
+.P
+Many of the arithmetic operators have special meaning
+to the shell and must be quoted.
+Since this can be burdensome, an alternate form of arithmetic
+evaluation syntax has been provided.
+For any command that begins with
+.BR (( ,
+all the characters until the matching
+.B ))
+are treated as a quoted arithmetic expression.
+The double parentheses 
+usually avoids incompatibility with the Bourne shell's use of
+parentheses for grouping a set of commands
+to be run in a sub-shell.
+Expressions inside double parentheses can contain blanks
+and special characters without quoting.
+More precisely,
+.ce
+.B
+(( ... ))
+.R
+is equivalent to
+.ce
+.B
+let " ... "
+.R
+.P
+The following script prints the first
+.I n
+lines of its standard input onto its standard output,
+where
+.I n
+can be supplied as an optional argument whose default value is 20.
+.B
+.sp
+.nf
+.in .5i
+.ta 4i
+typeset \-i n=${1-20}                          # set n
+while   read \-r line && (( (n=n\-1)>=0 ))     # at most n lines
+do      print \-r \- "$line"                   
+done
+.fi
+.ta
+.in
+.sp
+.R
+.H 1 "Functions and Command Aliasing"
+.P
+Two new mechanisms have been provided for creating
+pseudo-commands, i. e.,
+things that look like commands,
+but do not always create a process.
+The first technique is called command name
+.IR aliasing .
+.P
+As a command is being read,
+the command name is checked against a list of
+.I alias
+names.
+If it is found,
+the name is replaced by the text associated with the
+.I alias
+and then rescanned.
+The text of an alias is not checked for aliases
+so recursive definitions are not allowed.
+However, if the value of an alias ends in a space,
+then the word following the alias is also checked for alias substitution.
+.P
+Aliases are defined with the
+.B alias
+built-in.
+The form of an
+.B alias
+command definition is:
+.ce
+.BI "alias " name = value
+The first character of an
+.I alias
+name can be any non-special printable character, while all remaining characters
+must be  alpha-numeric.
+The replacement text,
+.I value,
+can contain any valid shell script,
+including meta-characters such as pipe symbols and i/o-redirection.
+Unlike
+.BR csh ,
+aliases in
+.B Ksh-i
+cannot take arguments.
+Aliases can be used to redefine built-in commands so that
+the alias
+.ce
+.B "alias test=./test"
+can be used to look for
+.I test
+in your current working directory rather than
+using the built-in
+.B test
+command.
+Keywords such as
+.B for
+and
+.B while
+cannot be changed by aliasing.
+The command
+.BR alias ,
+without arguments, generates
+a list of aliases and corresponding texts.
+The
+.B unalias
+command removes the name and text of an alias.
+.P
+Aliases are used to save typing and to improve readability of scripts.
+For example, the alias
+.B
+alias integer=\(fmtypeset \-i\(fm
+.R
+allows integer the variables
+.B i
+and
+.B j
+to be declared and initialized with the command
+.BR "integer i=0 j=1" .
+.P
+Aliases can be used to bind program names to the
+full path-name of the program.  This eliminates the path search
+but requires knowledge of where that program will be stored.
+.I Tracked
+aliases
+make this use for aliasing automatic.
+A tracked alias is not given a value.  Its value is
+defined at the first
+reference by a path-search as the full path-name equivalent of the name, and
+remains defined until the
+.B PATH
+variable is changed.
+Programs found in directories that do not begin with
+.B /
+that occur earlier in the path-search than the value of the
+tracked alias, take precedence over tracked aliases.
+.P
+Tracked aliases provide an alternative to the
+.I Csh
+command hashing facility. Tracked aliases do not require time for
+initialization and allow for new commands to be introduced
+without the need for re-hashing.
+The
+.B \-h
+option to the shell allows all command names that are
+valid alias names to become tracked aliases.
+This option is automatically turned on for non-interactive shells.
+.P
+.I Functions
+are more general than aliases but also more costly.
+Functions definitions are of the form
+.sp
+.in +.5i
+.BI "function " name
+.br
+.B {
+.br
+       any shell script
+.br
+.B }
+.sp
+.in
+The function is invoked by writing
+.I name
+and optionally following it with arguments.
+Positional parameters are saved before each
+function call and restored when completed.
+Functions are executed in the current shell environment
+and can share named variables with the calling program.
+Options, other than execution trace
+.BR \-x ,
+set by the calling program are
+passed down to a function.
+The option flags are
+not shared with
+the function so that any options set within a function are
+restored when the function exits.
+All traps other than
+.B EXIT
+and
+.B ERR
+(described later)
+are also inherited.
+A trap on
+.B EXIT
+within a function will execute after the function completes but
+before the caller resumes.
+Therefore,
+any variable assignments and
+any options set as part of a trap action will be effective
+after the caller resumes.
+The
+.B return
+built-in can be used to cause the function to return to
+the statement following
+the point of invocation.
+.P
+By default, variables are inherited by the function and shared
+by the calling program.
+However,
+environment substitutions preceding the function call
+apply only to the scope of the function call.
+Also, variables defined with the
+.BR typeset ,
+built-in command are local to the function that they are declared in.
+Thus, for the function defined
+.B
+.sp
+.nf
+.in .5i
+function  name
+{
+     typeset \-i x=10
+     let z=x+y
+     print $z
+}
+.fi
+.ta
+.in
+.sp
+.R
+invoked as
+.BR "y=13 name" ,
+.B x
+and
+.B y
+are local variables with respect to the function
+.B name
+while
+.B z
+is global.
+.P
+Alias and function names are never directly carried across separate
+invocations of Ksh-i, but can be passed down to sub-shells.
+Ordinarily, shell scripts invoked by name are executed in a sub-shell while
+scripts invoked as
+.B ksh
+.I script
+and shell escapes from other programs
+are carried out by a separate shell invocation.
+The
+.B \-x
+flag is used with
+.B alias
+to carry aliases to sub-shells while the
+.B \-fx
+flags of
+.B typeset
+are used to do the same for functions.
+.P
+Each user can create a startup file for aliases and functions or
+any other commands.
+Aliases and functions that are to be available for all shell invocations
+should be put into this file.
+Aliases and functions which should apply to 
+scripts, as well as interactive use, should be set with the
+.B \-x
+flag.
+Setting this flag to redefine the semantics of a command
+can have undesired side effects.
+For example,
+.B "alias \-x ls='ls \-l'"
+will cause shell procedures which use the
+.B ls
+command within a pipeline to break.
+By setting and exporting the environment variable,
+.BR ENV ,
+to the name of this file,
+the aliases and functions will be defined each time Ksh-i
+is invoked.
+The value of the
+.B ENV
+variable undergoes parameter substitution prior to its use.
+.P
+Several of the UNIX commands can be aliased to Ksh-i built-ins.
+Some of these are automatically set each time the shell is invoked.
+In addition,
+about twenty frequently used UNIX commands are set as tracked aliases.
+.P
+The location of an alias command can be important
+since aliases are only processed when a command is read.
+A
+.B .
+procedure is read all at once (unlike
+.I profiles
+which are read a command at
+a time) so that any aliases defined there will not effect any commands
+within this script.
+.P
+A name is checked to see if it is a built-in command before checking to see
+if it is a function.  To write a function to replace a built-in command
+you must define a function with a different name and alias the
+built-in name to this function.
+For example to write a
+.B cd
+function which changes the directory and prints out the directory name,
+you can write,
+.B
+.sp
+.nf
+.in .5i
+alias cd=_cd
+function  _cd
+{
+     if      'cd'  "$@"
+     then    echo  $PWD
+     fi
+}
+.fi
+.ta
+.in
+.sp
+.R
+The single quotes around
+.B cd
+within the function prevents alias substitution.
+The
+.B PWD
+variable is described below.
+.P
+The combination of aliases and functions can be used
+to do things that can't be done with either of these
+separately.  For example, the function and aliases
+defined as
+.B
+.sp
+.nf
+.in .5i
+function _from # i=start to finish [ by incr]
+{
+        typeset var=${1%%=*}
+               integer incr=${5\-1} $1
+               while   (( $var <= $3 ))
+               do      _repeat
+                       let $var=$var+incr
+               done
+}
+alias repeat='function _repeat {'  from='}; _from'
+.fi
+.ta
+.in
+.sp
+.R
+allow you to write loops such as
+.B
+.sp
+.nf
+.in .5i
+repeat
+        any script command
+from i=1 to 13 by 3
+.fi
+.ta
+.in
+.sp
+.R
+with the expected behavior.
+.H 1 "Input and Output"
+.P
+An extended I/O capability has been added
+to enhance the
+use of the shell as a programming language.
+The Bourne shell has a built-in
+.B read
+for reading lines from file descriptor 0,
+but does not have any internal output mechanism.
+As a result, the
+.B echo(1)
+command has been used to produce output for a shell procedure.
+This is inefficient and also restrictive.
+For example, there is no way to read in a line
+from a terminal and to
+.I echo
+the line exactly as is.
+In the Bourne shell,
+the
+.B read
+built-in cannot be used to read lines that end in
+.BR `\e'  ,
+and the
+.B echo
+command will treat certain sequences as control sequences.
+In addition,
+there is no way to have more than one file open
+at any time for reading.
+.P
+Ksh-i has options on the
+.B read
+command to specify the file
+descriptor for the input.
+The
+.B exec
+built-in can be used to open, close, and duplicate file streams.
+The
+.B \-r
+option allows a
+.B `\e'
+at the end of an input line to be treated as a regular
+character rather than the line continuation character.
+The first argument of the
+.B read
+command can be followed by a
+.B ?
+and a prompt to produce a prompt at the
+terminal before the read.
+If the input is not from a terminal device then
+the prompt is not issued.
+.P
+The Ksh-i built-in,
+.BR print ,
+is used to output characters to the terminal or to a file.
+Again, it is possible to specify the file descriptor number
+as an option to the command.
+Ordinarily, the arguments to this command are processed
+the same as for
+.BR echo(1) .
+However, the
+.B \-r
+flag can be used to output the arguments without any special meaning.
+The
+.B \-n
+flag can be used here to suppress the trailing new-line
+that is ordinarily appended.
+.P
+To improve performance of existing shell programs,
+the
+.B echo
+command is built into Ksh-i.
+For the System V version of Ksh-i, the built-in
+.B echo
+is equivalent
+.ce
+\f3print \-\fR,
+where the
+.B \-
+signifies that there are no more options permitted.
+On the Berkeley UNIX version the value of the
+.B PATH
+variable determines the behavior of the built-in
+.B echo
+command.
+If
+.B echo
+would resolve to
+.B /bin/echo
+with a path search, then
+.B echo
+is equivalent to
+.ce
+\f3print \-R\fR.
+The
+.B \-R
+option allows only the
+.B \-n
+flag to be recognized as the next argument.
+Otherwise,
+.B echo
+behaves like the System V
+.B echo
+command.
+.P
+The shell is frequently used as a programming language for
+interactive dialogues.
+The
+.B select
+statement has been added to the language
+to make it easier to
+present menu selection alternatives to the
+user and evaluate the reply.
+The list of alternatives is numbered and put in columns.
+A user settable prompt,
+.BR PS3 ,
+is issued and if the answer is
+a number corresponding to one of the alternatives,
+the select loop variable is set to this value.
+In any case, the
+.B REPLY
+variable is used to store the user entered reply.
+The shell variables
+.B LINES
+and
+.B COLUMNS
+are used to control the layout of select lists.
+.H 1 "Command Re-entry"
+.P
+An interactive shell saves the
+commands you type at a terminal in a file.
+If the variable
+.B HISTFILE
+is set to the name of a file to which the user
+has write access,
+then the commands are stored in this
+.I history
+file.
+Otherwise the file
+.B $HOME/.sh_history
+is checked for write access and if this fails
+an unnamed file is used to hold the history lines.
+This file may be truncated if this is a top level shell.
+The number of commands accessible to the user, is determined by the value of the
+.B HISTSIZE
+variable at the time the shell is invoked.
+The default value is 128.
+A command may consist of one or more lines since a compound
+command is considered one command.
+If the character
+.B !
+is placed within the
+.I "primary prompt"
+string,
+.BR PS1 ,
+then it is replaced by the command number each time the prompt is given.
+Whenever the history file is named,
+all shells which use this file share access to the same history.
+.P
+A built-in command
+.B fc
+(fix command) is used to list and/or edit
+any of these saved commands.
+The command can always be specified with
+a range of one or more commands.
+The range can be specified by giving the command
+number, relative or absolute, or by giving
+the first character or characters of the command.
+The option
+.B \-l
+is used to specify listing of previous commands.
+When given without specifying the range,
+the last 16
+commands are listed, each
+preceded by the command number.
+.P
+If the listing option is not selected,
+then the range of commands specified,
+or the last command if no range is given,
+is passed to an editor program before
+being re-executed by Ksh-i.
+The editor to be used may be specified
+with the option
+.B \-e
+and following it with the editor name.
+If this option is not specified, the
+value of the shell variable
+.B FCEDIT
+is used as the name of the editor,
+providing that this variable has non-null value.
+If this variable is not set, or is null,
+and the
+.B \-e
+option has not been selected,
+then
+.B /bin/ed
+is used.
+When editing has been complete,
+the edited text automatically becomes
+the input for Ksh-i.
+As this text is read by Ksh-i, it is echoed onto the terminal.
+.P
+An editor name of
+.B \-
+is used to bypass the editing and just re-execute the command.
+In this case only a single command can be specified as the range
+and an optional argument of the form
+\f2old\fP\f3=\fP\f2new\fP
+may be added which requests a simple string substitution
+prior to evaluation.
+A convenient alias,
+.ce
+.B
+alias r=\(fmfc \-e \-\(fm
+.R
+has been pre-defined so that
+the single key-stroke
+.B r
+can be used to re-execute the previous command
+and the key-stroke sequence,
+.B
+r abc=def c
+.R
+can be used to re-execute the last command that starts with
+the letter
+.B c
+with the first occurrence of the string
+.B abc
+replaced with the string
+.BR def .
+Typing
+.B
+r c > file
+.R
+re-executes the most recent command starting with the letter
+.BR c ,
+with standard output redirected to
+.IR file .
+.H 1 "In-line editing"
+.P
+Lines typed from a terminal frequently need changes made
+before entering them.
+With the Bourne shell the only method to fix up commands
+is by backspacing or killing the whole line.
+Ksh-i offers options that allow the user to edit parts of the
+current command line before submitting the command.
+The in-line edit options make the command line into a single
+line screen edit window.
+When the command is longer than the width of the terminal,
+only a portion of the command is visible.
+Moving within the line automatically makes that portion visible.
+Editing can be performed on this window until the
+.I return
+key is pressed.
+The editing modes have commands that access the history file
+in which previous commands are saved.
+A user can copy any of the most recent
+.B HISTSIZE
+commands from this file into the input edit window.
+You can locate commands by searching or by position.
+.P
+The in-line editing options do not use the
+.I termcap
+database.
+They work on most standard terminals.
+They only require that the backspace character moves the cursor left
+and the space character overwrites the current character on the screen
+and moves the cursor to the right.
+.P
+There is a choice of editor options.
+The
+.IR emacs ,
+.IR gmacs ,
+or
+.I vi
+option is selected by turning on the
+corresponding
+option of the
+.B set
+command.
+If the value of the
+.B EDITOR
+or
+.B VISUAL
+ends any of these suffixes
+the corresponding options is turned on.
+A large subset of each of each of these editors'
+features are available within the shell.  Additional
+functions, such as file name completion, have also been added.
+.P
+The code for the
+.I emacs
+and
+.I gmacs
+editing option was supplied by Mike Veach.
+In the
+.I emacs
+or
+.I gmacs
+mode the user positions the cursor to the point
+needing correction and inserts, deletes, or replaces
+characters as needed.
+The only difference between these two modes is the
+meaning of the command
+.BR ^T .
+Control keys and escape sequences are used for cursor
+positioning and control functions.
+The available editing functions are listed in the manual page.
+.P
+The code for the
+.I vi
+editing option was supplied by Pat Sullivan.
+The
+.I vi
+editing mode
+starts in insert mode and enters control mode when the
+user types
+.BR ESC (
+.BR 033 ).
+The
+.I return
+key, which submits the current command for processing,
+can be entered from either mode.
+The cursor can be anywhere on the line.
+A subset of commonly used
+.I vi
+commands are available.
+The
+.B k
+and
+.B j
+command that normally move up and down by one
+.IR line ,
+move up and down one
+.I command
+in the history file,
+copying the command into the input edit window.
+For reasons of efficiency,
+the terminal is kept in canonical mode until an
+.B ESC
+is typed.
+On some terminals,
+and on earlier versions of the UNIX operating system,
+this doesn't work correctly.
+The
+.B viraw
+option
+of the
+.B set
+command, which always uses
+.B raw
+or
+.B cbreak
+mode,
+must be used in this case.
+.P
+Most of the code for the editing options does not rely on the
+Ksh-i code and be used in a stand-alone mode with most any command
+to add in-line edit capability.
+However,
+all versions of the in-line editors have some features that
+use some shell specific code.  For example,
+.B ESC-=
+in all edit modes prints the names of files that match the current
+word and
+.B ESC-*
+adds the expanded list of matching files to the command line.
+A trailing
+.B *
+is added to the word if it doesn't contain any file pattern matching
+characters before the expansion.
+.H 1 "Job Control"
+.P
+The job control mechanism 
+is almost identical to the version found in
+.I Csh
+of the Berkeley UNIX operating system,
+version 4.1.
+The job control feature allows the user to stop and
+restart programs, and to move programs to and from the
+foreground and the background.
+It will only work on systems that provide support for
+these features.
+However,
+even systems without job control have a
+.B monitor
+option which when enabled will report the progress
+of background jobs and enable the user to
+.B kill
+jobs by job number or job name.
+.P
+An interactive shell associates a
+.I job
+with each pipeline typed in from the terminal
+and assigns them a small integer number
+called the job number.
+If the job is run asynchronously,
+the job number is printed at the terminal.
+At any given time, only one job owns the terminal,
+i. e., keyboard signals are only sent to the processes in one job.
+When Ksh-i creates a foreground job,
+it gives it ownership of the terminal.
+If you are running a job and wish to stop
+it you hit the key
+.B ^Z
+(control-Z)
+which sends a
+.B STOP
+signal to all processes in the current job.
+The shell receives notification that the processes
+have stopped and takes back control of the terminal.
+.P
+There are commands to continue programs in the foreground
+and background.
+There are several ways to refer to jobs.
+The character
+.B %
+introduces a job name.
+You can refer to jobs by name or number as described in the manual page.
+The built-in command
+.B bg
+allows you to continue a job in the background,
+while the built-in command
+.B fg
+allows you to continue a job in the foreground even
+though you may have started it in the background.
+.P
+A job being run in the background will stop if it tries
+to read from the terminal.
+It is also possible to stop background jobs that try to write on
+the terminal by setting the terminal options
+appropriately.
+.P
+There is a built-in command
+.B jobs
+that lists the status of all running and stopped jobs.
+In addition,
+you are notified of the change of state of any background
+jobs just before each prompt.
+When you try to leave the shell while jobs are stopped or running,
+you will receive a message from Ksh-i.
+If you ignore this message and try to leave again,
+all stopped processes will be terminated.
+.P
+A built-in version of
+.B kill
+makes it possible to use
+.I job
+numbers as targets for signals.
+Signals can be selected by number or name.
+The name of the signal is the name found in the
+.I include
+file
+.B /usr/include/signal.h
+with the prefix
+.B SIG
+removed.
+The
+.B \-l
+flag of
+.B kill 
+generates list of valid signal numbers and names.
+.H 1 Security
+There are several documented problems associated with the security of
+shell procedures\*(Rf.
+.RS
+F. T. Grampp and R. H. Morris,
+.I "UNIX Operating System Security,"
+AT&T Bell Labs Tech. Journal, Vol. 63, No. 8, Part 2, pp.1649-1671, 1984.
+.RF
+These security holes occur primarily because a user can manipulate the
+.I environment
+to subvert the intent of a
+.I setuid
+shell procedure.
+Frequently, shell procedures are initiated from 
+binary programs, without the author's
+awareness, by library routines which invoke shells to carry out
+their tasks.
+When the binary program is run
+.I setuid
+then the shell procedure runs with the permissions afforded to the
+owner of the binary file.
+.P
+In the Bourne shell,
+the
+.B IFS
+parameter is used to split each word into separate command arguments.
+If a user knows that some
+.I setuid
+program will run
+.B "sh \-c /bin/pwd"
+(or any other command in
+.BR /bin )
+then the user sets and exports
+.BR IFS=/ .
+Instead of running
+.B /bin/pwd
+the shell will run
+.B bin
+with
+.B pwd
+as an argument.
+The user puts his or her own
+.B bin
+program into the current directory.
+This program can
+create a copy of the shell,
+make this shell
+.IR setuid ,
+and then run the
+.B /bin/pwd
+program so that the original program continues to run successfully.
+This kind of penetration is not possible with
+.I Ksh-i
+since the
+.B IFS
+parameter only splits arguments that result from command or parameter
+substitution.
+.P
+Some
+.I setuid
+programs run programs using
+.I system()
+without giving the full path name.
+If the
+user sets the
+.B PATH
+variable so that the desired command will be found
+in his or her local bin, then the same technique described above can
+be employed to compromise the security of the system.
+To close up this and other security holes,
+.I Ksh-i
+goes into a
+.I protected
+mode whenever the real and effective user or group id are not the same.
+In this mode, the
+.B PATH
+variable is reset to a default value and the
+.B .profile
+and
+.B ENV
+files are not processed.
+Instead, the file
+.B /etc/suid_profile
+is read and executed.
+This gives an administrator control over the
+environment to set the
+.B PATH
+variable or to log setuid shell invocations.
+Clearly security of the system is compromised if
+.B /etc
+or this file is publicly writable.
+.P
+In BSD UNIX the operating system looks for the characters
+.B #!
+as the first two characters of an executable file.
+If these characters are found, then the next word on this line is taken
+as the interpreter to
+.I exec
+for this command and the interpreter is
+.IR exec ed
+with the name of the script as argument zero and argument one.
+If the
+.I setuid
+or
+.I setgid
+bits are on for this file, then the interpreter
+is run with the effective uid and/or gid set accordingly.
+This scheme has two major drawbacks.
+First of all, using the
+.B #!
+notation forces an
+.B exec
+of the interpreter even when the call is invoked from the interpreter
+which it must exec.  This is inefficient since
+the interpreter can handle a failed exec much faster than starting up
+again.
+More importantly,
+.I setuid
+and
+.I setgid
+procedures provide an easy target for intrusion.
+By linking a
+.I setuid
+or
+.I setgid
+procedure to a name beginning with a
+.B \-
+the interpreter is fooled into thinking that is being invoked with
+a command line option rather than the name of a file.
+When the interpreter is the shell, the user gets a privileged
+interactive shell.
+There is code in
+.I Ksh-i
+to guard against this simple form of intrusion.
+.P
+A more reliable way to handle
+.I setuid
+and
+.I setgid
+procedures is provided with
+.IR Ksh-i .
+The technique does not require any changes to the operating system
+and provides better security.
+Another advantage to this method is that it also allows scripts which
+have execute premission but no read permission to run.  Taking away read
+permission makes scripts more secure.
+.P
+The method relies on a setuid
+.B root
+program to authenticate the
+request and exec the shell with the correct mode bits to carry out
+the task.  This shell is invoked with the requested file already open
+for reading.  A script which cannot be opened for reading or which
+has its suid and/or setgid bits turned on causes this setuid
+.B root
+program to get execed.
+For security reasons, this program is given the full
+pathname
+.BR /etc/suid_exec .
+A description of the implementation of the
+.B suid_exec
+program can be found in
+a separate paper\*(Rf.
+.RS
+D. G Korn
+.I "Parlez-vous Kanji?"
+TM-59554-860602-03, 1986.
+.RF
+.H 1 "Miscellaneous"
+.P
+Ksh-i has several additional features to enhance functionality and performance.
+This section lists most of these features.
+.H 2 "Tilde substitution"
+The character
+.B \(ap
+at the beginning of a word has special meaning to Ksh-i.
+If the characters after the
+.B \(ap
+up to a
+.B /
+match a user login name in the
+.B /etc/passwd
+file, then the
+.B \(ap
+and the name are replaced by
+that user's login directory.
+If no match is found, the original word
+is unchanged.
+A
+.B \(ap
+by itself, or in front of a
+.BR / ,
+is replaced by the value of the
+.B HOME
+parameter.
+A
+.B \(ap
+followed by a
+.B +
+or
+.B \-
+is replaced by the value of
+the parameter
+.B PWD
+and
+.B OLDPWD
+respectively.
+Tilde substitution takes place when the script is read,
+not while it is executed.
+.H 2 "Built-in I/O Redirection"
+.P
+All built-in commands can be redirected.
+Compound commands which are redirected are not carried out in
+a separate process.
+.H 2 "Added options"
+.P
+Several options have been added to the shell and
+all options have names
+that can be used in place of flags for setting and resetting options.
+The command
+.B "set \-o"
+will list the current option settings.
+.P
+The option,
+.B \-f
+or
+.BR noglob ,
+is used to disable file name generation.
+.P
+The option
+.B ignoreeof
+can be used to prevent
+.B ^D
+from exiting the shell and possibly logging you out.
+You must type
+.B exit
+to log out.
+.P
+The
+.B \-h
+or
+.B trackall
+option will cause all commands whose name is a valid alias
+name to become a
+.I tracked
+alias.
+This option is automatically turned on for non-interactive shells.
+.P
+The job
+.B monitor
+option will cause a report to be printed
+before issuing the next prompt
+when each background job completes.
+It is automatically enabled for systems that have
+job control.
+.P
+If the
+.B bgnice
+option is set,
+background jobs are run at a lower priority.
+.P
+The option
+.B markdirs
+causes a trailing
+.B /
+to be appended on every directory name resulting from a pattern match.
+.P
+The
+.B protected
+or
+.B \-p
+options provides additional security by disabling the
+.B ENV
+from being executed and by resetting the
+.B PATH
+variable to the default value.
+Whenever a shell is run with the effective uid (gid) not equal to
+the real uid (gid) then this option is implicitly enabled.
+Instead of the
+.B ENV
+file, the file
+.B /etc/suid_profile
+is read so that administrators can have control over setuid scripts.
+.H 2 "Built-in pwd"
+The
+.B pwd
+command is built-into Ksh-i and therefore much faster.
+.H 2 "Logical naming"
+The
+.B cd
+command will take you where you expect to go even if you cross
+symbolic links.  Thus,
+.B "cd .."
+will move you up one level closer to the root even if your
+current directory is a symbolic link.
+.H 2 "Previous Directory"
+.P
+Ksh-i remembers your last directory
+in the variable
+.BR OLDPWD .
+The
+.B cd
+built-in can be given with argument
+.B \-
+to return to the previous directory
+and prints the name of the directory.
+Note that
+.B "cd \-"
+done twice returns you to the starting directory,
+not the second previous directory.
+A directory
+.I stack
+manager has been written as shell
+.I functions
+to
+.I push
+and
+.I pop
+directories from the stack.
+.H 2 "Additional Variables and Parameters"
+.P
+Several new parameters have special meaning to Ksh-i.
+The variable
+.B PWD
+is used to hold the current working directory of the shell.
+The variable
+.B OLDPWD
+is used to hold the previous working directory of the shell.
+.P
+The variable
+.B FCEDIT
+is used by the
+.B fc
+built-in described above.
+The variables
+.B VISUAL
+and
+.B EDITOR
+are used for determining the edit modes as described above.
+.P
+The variable
+.B ENV
+is used to define the startup file for non-login
+Ksh-i invocations.
+.P
+The variables
+.B HISTSIZE
+and
+.B HISTFILE
+control the size and location of the file containing
+commands entered at a terminal.
+.P
+The parameter
+.B MAILPATH
+is a colon (
+.B :
+) separated list of file names to be checked for changes
+periodically. The user is notified
+before the next prompt.
+Each of the names in this list can be followed by a
+.B ?
+and a prompt to be given when a change has been detected in the file.
+The prompt will be evaluated for parameter substitution.
+The parameter
+.B $_
+within a mail message will evaluate to the name of the file that
+has changed.
+The parameter
+.B MAILCHECK
+is used to specify the minimal interval in seconds before
+new mail is checked for.
+.P
+The variable
+.B RANDOM
+produces a random number each time it is referenced.
+Assignment to this variable sets the seed for the
+random number generator.
+.P
+The variable
+.B SECONDS
+is incremented every second.
+In a roundabout way, this variable
+can be used to generate a time stamp into the
+.B PS1
+prompt.
+The following code explains how you can do this on
+System V.  On BSD you need another command to initialize
+the
+.B SECONDS
+variable.
+.B
+.sp
+.nf
+.in .5i
+# If you . this script then you can use $TIME as part of your PS1 string to get
+#   the time of day in your prompt
+typeset \-RZ2  _x1 _x2 _x3
+let SECONDS=$(date  '+3600*%H+60*%M+%S')
+_s='(_x1=(SECONDS/3600)%24)==(_x2=(SECONDS/60)%60)==(_x3=SECONDS%60)'
+TIME='"${_d[_s]}$_x1:$_x2:$_x3"'
+# PS1=${TIME}whatever
+.fi
+.ta
+.in
+.sp
+.R
+.P
+The parameter
+.B PPID
+is used to generate the process id of the process which invoked this shell.
+.P
+The value of the parameter
+.B _
+is the last argument of the previous foreground command.
+Before execing each command this parameter is set to the file
+name of the command and placed in the environment.
+.P
+The parameter
+.B TMOUT
+can be set to be the number of seconds that the shell will wait for
+input before terminating.  A 60 second warning message is printed
+before terminating.
+.P
+The
+.B COLUMNS
+variable can be used to adjust the width of the edit window for
+the in-line edit modes.  It is also used by the
+.B select
+command to present menu choices.
+.P
+The
+.B LINES
+variable controls how many rows a select list will take up on the screen.
+Select lists will try to occupy no more then two-thirds of
+.B LINES
+lines on the screen.
+.H 2 "Modified variables"
+.P
+The input field separator parameter,
+.BR IFS ,
+is only used to split words that have undergone parameter or command
+substitution.
+In addition, adjacent non-blank delimiters separate
+null fields in Ksh-i.
+.P
+The
+.B PS1
+parameter is evaluated for parameter substitution and a
+.B !
+is replaced by the current command number.
+.H 2 "Timing Commands"
+.P
+A keyword
+.B time
+has been added to replace
+the
+.B time
+command.
+Any function, command or pipeline can be preceded by this keyword
+to obtain information about the elapsed, user and system times.
+Since I/O redirection bind to the command, not to
+.BR time ,
+parenthesis should be used to redirect the timing information which
+is normally printed on file descriptor 2.
+.H 2 "Co-process"
+Ksh-i can spawn a
+.I co-process
+by adding a
+.B "|&"
+after a command.
+This process will be run with its standard input and its
+standard output connected to the shell.  The built-in command
+.B print
+with the
+.B \-p
+option will write into the standard input of this
+process and
+the built-in command
+.B read
+with the
+.B \-p
+option will read from the output of this process.
+Only one such process can exist at any time.
+.H 2 "Process Substitution"
+.P
+This feature is only available
+on versions of the UNIX operating system which support the
+.B /dev/fd
+directory for naming open files.
+Each command argument of the form
+\f3(\fP\f2list\^\fP\f3)\fP,
+\f3<(\fP\f2list\^\fP\f3)\fP,
+or
+\f3>(\fP\f2list\^\fP\f3)\fP
+will run process
+.I list
+asynchronously connected to some file in the
+.B /dev/fd
+directory.
+The name of this file will become the argument to the command.
+If the form with
+.B >
+is selected then writing on this file will provide input for
+.IR list .
+If
+.B <
+is used or omitted,
+then the file passed as an argument will contain the output of the
+.I list
+process.
+For example,
+.B
+.sp
+.nf
+.in .5i
+paste  (cut \-f1 \f2file1\fP)  (cut \-f3 \f2file2\fP) | tee >(\f2process1\fP)  >(\fP\f2process2\fP)
+.fi
+.ta
+.in
+.sp
+.R
+.I cuts
+fields 1 and 3 from
+the files
+.I file1
+and
+.I file2
+respectively,
+.I pastes
+the results together, and
+sends it
+to the processes
+.I process1
+and
+.IR process2 ,
+as well as putting it onto the standard output.
+Note that the file which is passed as an argument to the command is
+a UNIX
+.IR pipe (2)
+so that the programs that expect to
+.IR lseek (2)
+on the file will not work.
+.H 2 "Command Substitution"
+.P
+Command substitution ( \fB\(ga\(ga\fR)
+in the Bourne shell suffers from some
+complicated quoting rules.
+It is hard to write a
+.B sed
+pattern which contains back slashes within command substitution.
+Putting the pattern is single quotes doesn't help much.
+Ksh-i leaves the Bourne shell command substitution alone and adds
+a newer and easier to use command substitution syntax.
+All the characters between a
+.B $(
+and a matching
+.B )
+are evaluated as a command the output is substituted just as
+with  \fB\(ga\(ga\fR.
+The
+.B $
+means
+.I "value of"
+and the
+.B ()
+denotes a command.
+The command itself can contain quoted strings even if the substitution
+occurs within double quotes. Nesting is legal.  You can use
+unbalanced parenthesis within the command providing that they are
+quoted.
+.P
+The special command substitution of the form
+\fB$(cat file)\fR
+can be replaced by
+\fB$(< file)\fR,
+which is faster because no separate process is created.
+.H 2 "Whence"
+.P
+The addition of
+.IR aliases ,
+.IR functions ,
+and more built-ins
+has made it substantially more difficult to know what
+a given command word really means.
+A built-in command,
+.B whence
+when used with the
+.B \-v
+option has been provided to answer this question.
+A line is printed for each argument to
+.B whence
+telling what would happen if this argument were used as a command name.
+It reports on keywords, aliases, built-ins, and
+functions.
+If the command is none of the above,
+it follows the path search rules and prints the full path-name,
+if any, otherwise it prints an error message.
+.H 2 "Additional test operators"
+.P
+The binary operators
+.B \-ot
+and
+.B \-nt
+can be used to compare the modification times
+of two files to see which is file is
+.I "older than"
+or
+.I "newer than"
+the other.
+The binary operator
+.B \-ef
+is used to see if two files
+have the same device and i-node number,
+i.\ e., a link to the same file.
+.P
+The unary operator
+.B \-L
+returns true for a symbolic link.
+.H 2 "Added Trap"
+All traps can be given by name in Ksh-i.  The names of traps
+corresponding to signals are the same as the signal name with
+the
+.B SIG
+prefix removed.
+The trap
+.B 0
+is named
+.B EXIT
+and a new trap named
+.B ERR
+has been added.
+This trap is invoked whenever the shell would exit if the
+.B \-e
+flag were set.
+This trap is used by
+Fourth Generation Make\*(Rf
+.RS
+G. S. Fowler,
+"The Fourth Generation Make,"
+Proceedings of the Portland USENIX meeting, pp. 159-174, 1985.
+.RF
+which runs Ksh-i
+as a co-process.
+.H 2 "Shell Accounting"
+.P
+There is a compile time option to the shell to generate
+an accounting message for each shell script.
+The changes needed to provide this feature were supplied
+by Foregger\*(Rf
+.RS
+T. H. Foregger,
+.I "Shell Accounting,"
+Case 40094-21, July 1982.
+.RF
+and have been adopted as described in his memo.
+.H 2 "Coded in Standard C"
+.P
+Early versions of Bourne shell were coded in an ALGOL-68 like dialect of C.
+Ksh-i is coded in standard C.
+It tries to adapt itself to the environment when it is compiled
+taking advantages of the features of the host environment when possible.
+There are far fewer
+.I lint
+messages from Ksh-i then for the Bourne shell.
+Ksh-i does not catch the segmentation violation signal, SIGSEGV,
+so that it can run on machines that can't recover from these traps.
+.H 2 Internationization
+Ksh-i treats eight bit characters transparently without stripping off the
+leading bit.
+There is also a compile time switch to enable handling multi-byte
+and multi-width characters sets.
+.H 2 "No special meaning for ^"
+The Bourne shell uses
+.B ^
+as an archaic synonym for
+.B | .
+The
+.B ^
+is not a special character to Ksh-i.
+.H 2 "Added conveniences"
+You can refer to multi-digit positional parameters in Ksh-i by putting
+the number in braces.  Thus,
+.B ${12}
+is legal in Ksh-i but illegal in the Bourne shell.
+.P
+Ksh-i will perform file name expansion of file name arguments if the
+expansion is unique.  Thus,
+.B "cat < file*"
+will expand the file name if the expansion is unique.
+.P
+If you invoke the shell as
+.B "ksh script"
+then Ksh-i will do a path search on script.
+.P
+Unbalanced quotes will cause the shell to print an
+error message giving the type of quote and the line number
+on which the opening quote occurs.
+.P
+Run time error messages detected by the shell will print the
+line number within a function or script where the error was
+detected.
+.H 1 "Example"
+.P
+An example of a Ksh-i script is included
+in the Appendix.
+This one page program is a variant of the UNIX
+.I grep(1)
+program.
+Pattern matching for this version of
+.I grep
+means shell patterns consisting of
+.BR ? ,
+.BR * ,
+and
+.BR [] .
+.P
+The first half examines option flags.
+Note that all options except
+.B \-b
+have been implemented.
+The second half goes through each line of each file
+to look for a pattern match.
+.P
+This program is not intended to serve as a
+replacement for
+.BR grep ;
+just as an illustration of the programming power of Ksh-i.
+Note that no auxiliary processes are spawned by this script.
+It was written and debugged in under two hours.
+While performance is acceptable for small programs,
+this program runs at only one tenth
+the speed of
+.B grep
+for large files.
+.H 1 "Performance"
+.P
+Ksh-i executes many scripts faster than the System V Bourne shell.
+One major reason is that many of the functions provided by
+.I echo(1)
+and
+.I expr(1)
+are built-in.
+The time to execute a built-in function is one or two
+orders of magnitude faster than performing a fork and
+execute of the shell.
+Command substitution of built-ins is performed without
+creating another process, and often without even
+creating a temporary file.
+.P
+Another reason for improved performance is that all I/O is buffered.
+Output buffers are flushed only when required.
+Several of the internal algorithms have been changed
+so that the number of subroutine calls has been
+substantially reduced.
+Ksh-i uses hash tables for variables.
+Scripts that rely heavily on referencing variables execute faster.
+More processing is performed while reading the script
+so that execution time is saved while running loops.
+.P
+Scripts that do little internal processing and create many processes
+may run a little slower on System V because the time to
+.I fork
+Ksh-i is slightly slower than for the Bourne shell.
+On BSD Unix, Ksh-i can be compiled with a
+.B VFORK
+option which uses
+.I vfork
+whenever possible.
+In this case, binary programs startup somewhat faster but shell
+script files start a little slower since a separate invocation
+of the Ksh-i in required.
+.P
+The
+.B ENV
+file can have an undiserable effect on performance.
+Even if this file is small, the shell must perform an open of this
+file.  If large functions are placed in
+the
+.B ENV
+file they must be read in and compiled even if they are never referenced.
+If you only need the startup file for interactive shells only, then set your
+.B ENV
+variable to a
+value which evaluates to a file name for interactive shells and to
+the null string otherwise.  If you export the startup file name
+in the variable
+.BR START ,
+then setting
+.B
+.sp
+.nf
+.in .5i
+ENV='${START[(_$\-=1)+(_=0)\-(_$\-!=_${\-%%*i*})]}'
+.fi
+.ta
+.in
+.sp
+.R
+will only invoke the startup file for interactive shells
+since the subscript evaluates to 0
+only if the shell is interactive.
+.P
+If you need a startup
+.B ENV
+file for all shells
+then use a
+.I case
+statement on the
+.B $\-
+parameter to distinguish which actions only apply to interactive shells.
+The
+.B ENV
+file should look like
+.B
+.sp
+.nf
+.in .5i
+# options aliases and functions for all shell invocations
+case    $\- in
+*i*)
+        # options aliases and functions for interactive only
+        ;;
+esac
+.fi
+.ta
+.in
+.sp
+.R
+.P
+If there are functions which are only occasionally referenced, put them
+into a separate file
+.B $HOME/functions
+or any name you prefer
+and put aliases in the
+.B ENV
+file for each function name of the form
+.B
+.sp
+.nf
+.in .5i
+alias \f2function_name\fP='. $HOME/functions;\f2function_name\fP'
+.fi
+.ta
+.in
+.sp
+.R
+In the beginning of the
+.B $HOME/functions
+file you must unalias each of the function names defined in the
+file.
+The first reference to any
+.I function_name
+in the function file
+causes the function file to get read in and the functions compiled.
+.H 1  "Conclusion"
+.P
+Ksh-i has several thousand regular users.
+Ksh-i is a suitable replacement for the Bourne shell.
+It offers new features,
+better performance,
+and is essentially upward compatible with the Bourne shell.
+.SG dgk \"  signature typist initials 
+.NS 0 \" start notation 
+Members of Center 5954
+Laboratory 4542 Supervision
+J. W. Gross
+N. J. Kolettis
+J. L. Steffen
+P. D. Sullivan
+M. T. Veach
+.NE  \" end notation
+.CS 14 24 38 0 0 16  \" cover sheet for TM
+.bp
+.ce
+APPENDIX
+.nf
+       #
+       #       SHELL VERSION OF GREP
+       #
+       vflag= xflag= cflag= lflag= nflag=
+       set \-f
+       while   ((1))                   # look for grep options
+       do      case    "$1" in
+               \-v*)   vflag=1;;
+               \-x*)   xflag=1;;
+               \-c*)   cflag=1;;
+               \-l*)   lflag=1;;
+               \-n*)   nflag=1;;
+               \-b*)   print \(fmb option not supported\(fm;;
+               \-e*)   shift;expr="$1";;
+               \-f*)   shift;expr=$( < $1 );;
+               \-*)    print $0: \(fmunknown flag\(fm;exit 2;;
+               *)      if      test "$expr" = \(fm\|\(fm
+                       then    expr="$1";shift
+                       fi
+                       test "$xflag" |\|| expr="*${expr}*"
+                       break;;
+               esac
+               shift                   # next argument
+       done
+       noprint=$vflag$cflag$lflag      # don't print if these flags set
+       integer n=0 c=0 tc=0 nargs=$#   # initialize counters
+       for i in "$@"                   # go through the files
+       do      if      ((nargs<=1))
+               then    fname=\(fm\|\(fm
+               else    fname="$i":
+               fi
+               test "$i"  &&  exec 0< $i       # open file if necessary
+               while   read \-r line           # read in a line
+               do      let n=n+1
+                       case    "$line" in
+                       $expr)                  # line matches pattern
+                               if      test "$noprint" = ""
+                               then    print \-r "$fname${nflag:+$n:}$line"
+                               fi
+                               let c=c+1 ;;
+                       *)                      # not a match
+                               if      test "$vflag"
+                               then    print \-r "$fname${nflag:+$n:}$line"
+                               fi;;
+                       esac
+               done
+               if      test "$lflag" && ((c))
+               then    print \- $i
+               fi
+               let tc=tc+c n=0 c=0
+       done
+       test "$cflag" && print $tc      #  print count if cflag is set
+       let tc                          #  set the exit value
+.fi