.PF "'Copyright (c) 1984, 1985, 1986, 1987''AT&T All Rights Reserved'"
.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*\
UNIX is a trademark of Bell Laboratories.
It is essentially compatible with the System V version of the Bourne shell\*(Rf ,
.I "An Introduction to the UNIX
BSTJ - Vol. 57, No. 6 part 2, pages 1947-1972.
has many additional features,
.I "An Introduction to the C Shell,"
University of California, Berkeley, 1980.
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
assumes that the reader is already familiar with the Bourne shell.
a sample script written in Ksh-i.
The manual page for the current version is also included.
.OK Shell "Command interpreter" Language UNIX \" keyword
Over the past several years several papers
have been written describing new command interpreters
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.
.I "Vicmd a Visual Shell for Video Terminals,"
preserves the friendly environment of
(from which this memo was entered),
and adds a facility for convenient command entry.
has also been written by Veach\*(Rf.
.I "The Edit Shell - Connecting Screen Editing with the History List,"
USENIX Association Toronto Proceedings, 1983.
.I "2dsh - An Experimental Shell for Connecting Processes With Multiple Data Streams,"
shell allows the setup of more complicated networks of processes than
.I "See-Shell: a Graphical User-Interface for UNIX Systems,"
Bell Laboratories internal memorandum, 1982.
proposes a Small-Talk like interface\*(Rf
D. C. Smith, C. Irby, R. Kimball, and B. Verplank,
.I "Designing the Star User Interface,"
BYTE, April, 1982, pp. 242-282.
suitable for bit-mapped terminals such as the BLIT\*(Rf
.I "The Blit Programmer's manual,"
.I "The Architecture of an Integrated Local Network,"
IEEE Journal of Selected Areas in Communications,
Local Area Networks Special Issue, November 1983.
Perhaps the most widely used shell,
other than the Bourne shell, is
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,
and command name aliasing.
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
.I "An Input History for the Bourne Shell,"
The use of the shell as a programming language has been
described by Dolotta and Mashey\*(Rf
T. A. Dolotta and J. R. Mashey,
.I "Using the shell as a Primary Programming Tool,"
Proc. 2nd. Int. Conf. on Software Engineering, 1976,
and has been used by many people here
.I "Extended Shell - A Potential Real Time Interpreter,"
presented extensions to the Bourne shell to provide
message passing facilities and other inter-process communication and
synchronization features.
D. G. Korn and D. A. Lambeth,
added form entry/edit capabilities to the Bourne shell.
A proposal for a more programming language oriented shell has
been proposed by Sturzenbecker\*(Rf.
.I "A New Command Language for UNIX and related systems,"
aka Korn shell-international.
This memo is not a tutorial, only an introduction.
can be found in Kochan and Wood\*(Rf.
S. G. Kochan and P. H. Wood,
"Unix Shell Programming,"
Hayden Book Company, 1985.
Ksh-i is a direct descendant of the
form entry/edit features removed and with many new
The primary focus of this work has been to provide an
enhanced programming environment in addition
to the major command entry features of
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
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.
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
on VAXEN running System V, BSD 4.1., BSD 4.2,
3B's, PC-6300+, and UNIX-PC's running System V.
The ability to define and use variables to store and retrieve values
is an important feature in most programming languages.
same rules as the Bourne shell.
Since all variables have string representations,
there is no need to specify the
of each variable in the shell.
each variable can have one or more
that control the internal representation of the variable,
the way the variable is printed, and its access or
are available in the Bourne shell.
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.
built-in of the Ksh-i removes
values and attributes of parameters.
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
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.
are used for upper case and lower case
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
This script reads a file of lines each consisting of five fields separated by
and prints fields 4 and 2 in upper case in columns 1-15, left justified,
and columns 20-25 right-justified respectively.
typeset \-L15u f4 # 15 character left justified
typeset \-R6u f2 # 6 character right justified
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
causes the variable to be internally represented as an integer.
can be followed by a number representing the numeric base for printing, otherwise
the first assignment to an
variable defines the output
whenever the variable is printed.
typed variables result in arithmetic evaluation,
Ksh-i allows one-dimensional
in addition to simple variables.
Any variable can become an array
All elements of an array need not exist.
integer between 0 and 511, otherwise
Evaluation of subscripts is described in
Attributes apply to the whole array.
Assignments to array variables can be made with parameter assignment statements
Referencing of subscripted variables requires the character
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:
.BI ${ name [ subscript ]} .
can be used to generate all elements of an array,
as they are used for expansion of positional parameters.
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\f3[*]}\fP
gives the number of elements in the array.
There are four parameter substitution modifiers that
have been added to strip off leading and trailing substrings
during parameter substitution.
strips off the smallest (largest) matching pattern from the left
strips off the smallest (largest) matching pattern from the right.
For example, if the shell variable
.H 1 "Arithmetic Evaluation"
provides the ability to do integer arithmetic.
All arithmetic evaluations are performed using
Arithmetic constants are written as
is a decimal integer between
is any non-negative number.
Anything after a decimal point is truncated.
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
Note that there is no space before or after the operators
This is because each argument to
is an expression to evaluate.
The last expression determines
if the last expression evaluates to a non-zero value.
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
all the characters until the matching
are treated as a quoted arithmetic expression.
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.
The following script prints the first
lines of its standard input onto its standard output,
can be supplied as an optional argument whose default value is 20.
typeset \-i n=${1-20} # set n
while read \-r line && (( (n=n\-1)>=0 )) # at most n lines
.H 1 "Functions and Command Aliasing"
Two new mechanisms have been provided for creating
things that look like commands,
but do not always create a process.
The first technique is called command name
As a command is being read,
the command name is checked against a list of
the name is replaced by the text associated with the
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.
Aliases are defined with the
.BI "alias " name = value
The first character of an
name can be any non-special printable character, while all remaining characters
can contain any valid shell script,
including meta-characters such as pipe symbols and i/o-redirection.
Aliases can be used to redefine built-in commands so that
in your current working directory rather than
cannot be changed by aliasing.
without arguments, generates
a list of aliases and corresponding texts.
command removes the name and text of an alias.
Aliases are used to save typing and to improve readability of scripts.
alias integer=\(fmtypeset \-i\(fm
allows integer the variables
to be declared and initialized with the command
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.
make this use for aliasing automatic.
A tracked alias is not given a value. Its value is
reference by a path-search as the full path-name equivalent of the name, and
remains defined until the
Programs found in directories that do not begin with
that occur earlier in the path-search than the value of the
tracked alias, take precedence over tracked aliases.
Tracked aliases provide an alternative to the
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.
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.
are more general than aliases but also more costly.
Functions definitions are of the form
The function is invoked by writing
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
set by the calling program are
passed down to a function.
the function so that any options set within a function are
restored when the function exits.
within a function will execute after the function completes but
before the caller resumes.
any variable assignments and
any options set as part of a trap action will be effective
after the caller resumes.
built-in can be used to cause the function to return to
By default, variables are inherited by the function and shared
environment substitutions preceding the function call
apply only to the scope of the function call.
Also, variables defined with the
built-in command are local to the function that they are declared in.
Thus, for the function defined
are local variables with respect to the function
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
and shell escapes from other programs
are carried out by a separate shell invocation.
to carry aliases to sub-shells while the
are used to do the same for functions.
Each user can create a startup file for aliases and functions or
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
Setting this flag to redefine the semantics of a command
can have undesired side effects.
.B "alias \-x ls='ls \-l'"
will cause shell procedures which use the
command within a pipeline to break.
By setting and exporting the environment variable,
to the name of this file,
the aliases and functions will be defined each time Ksh-i
variable undergoes parameter substitution prior to its use.
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.
about twenty frequently used UNIX commands are set as tracked aliases.
The location of an alias command can be important
since aliases are only processed when a command is read.
procedure is read all at once (unlike
which are read a command at
a time) so that any aliases defined there will not effect any commands
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.
function which changes the directory and prints out the directory name,
within the function prevents alias substitution.
variable is described below.
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
function _from # i=start to finish [ by incr]
alias repeat='function _repeat {' from='}; _from'
allow you to write loops such as
with the expected behavior.
An extended I/O capability has been added
use of the shell as a programming language.
The Bourne shell has a built-in
for reading lines from file descriptor 0,
but does not have any internal output mechanism.
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
built-in cannot be used to read lines that end in
command will treat certain sequences as control sequences.
there is no way to have more than one file open
command to specify the file
descriptor for the input.
built-in can be used to open, close, and duplicate file streams.
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
command can be followed by a
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.
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
flag can be used to output the arguments without any special meaning.
flag can be used here to suppress the trailing new-line
that is ordinarily appended.
To improve performance of existing shell programs,
command is built into Ksh-i.
For the System V version of Ksh-i, the built-in
signifies that there are no more options permitted.
On the Berkeley UNIX version the value of the
variable determines the behavior of the built-in
flag to be recognized as the next argument.
behaves like the System V
The shell is frequently used as a programming language for
statement has been added to the language
present menu selection alternatives to the
user and evaluate the reply.
The list of alternatives is numbered and put in columns.
is issued and if the answer is
a number corresponding to one of the alternatives,
the select loop variable is set to this value.
variable is used to store the user entered reply.
are used to control the layout of select lists.
An interactive shell saves the
commands you type at a terminal in a file.
is set to the name of a file to which the user
then the commands are stored in this
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
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.
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.
(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.
is used to specify listing of previous commands.
When given without specifying the range,
commands are listed, each
preceded by the command number.
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
and following it with the editor name.
If this option is not specified, the
value of the shell variable
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,
option has not been selected,
When editing has been complete,
the edited text automatically becomes
As this text is read by Ksh-i, it is echoed onto the terminal.
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
alias r=\(fmfc \-e \-\(fm
has been pre-defined so that
can be used to re-execute the previous command
and the key-stroke sequence,
can be used to re-execute the last command that starts with
with the first occurrence of the string
re-executes the most recent command starting with the letter
with standard output redirected to
Lines typed from a terminal frequently need changes made
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
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
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
commands from this file into the input edit window.
You can locate commands by searching or by position.
The in-line editing options do not use the
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.
There is a choice of editor options.
option is selected by turning on the
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.
editing option was supplied by Mike Veach.
mode the user positions the cursor to the point
needing correction and inserts, deletes, or replaces
The only difference between these two modes is the
Control keys and escape sequences are used for cursor
positioning and control functions.
The available editing functions are listed in the manual page.
editing option was supplied by Pat Sullivan.
starts in insert mode and enters control mode when the
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
command that normally move up and down by one
copying the command into the input edit window.
For reasons of efficiency,
the terminal is kept in canonical mode until an
and on earlier versions of the UNIX operating system,
this doesn't work correctly.
command, which always uses
must be used in this case.
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.
all versions of the in-line editors have some features that
use some shell specific code. For example,
in all edit modes prints the names of files that match the current
adds the expanded list of matching files to the command line.
is added to the word if it doesn't contain any file pattern matching
characters before the expansion.
The job control mechanism
is almost identical to the version found in
of the Berkeley UNIX operating system,
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
even systems without job control have a
option which when enabled will report the progress
of background jobs and enable the user to
jobs by job number or job name.
An interactive shell associates a
with each pipeline typed in from the terminal
and assigns them a small integer 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
signal to all processes in the current job.
The shell receives notification that the processes
have stopped and takes back control of the terminal.
There are commands to continue programs in the foreground
There are several ways to refer to jobs.
You can refer to jobs by name or number as described in the manual page.
allows you to continue a job in the background,
while the built-in command
allows you to continue a job in the foreground even
though you may have started it in the background.
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
There is a built-in command
that lists the status of all running and stopped jobs.
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.
numbers as targets for signals.
Signals can be selected by number or name.
The name of the signal is the name found in the
generates list of valid signal numbers and names.
There are several documented problems associated with the security of
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.
These security holes occur primarily because a user can manipulate the
to subvert the intent of a
Frequently, shell procedures are initiated from
binary programs, without the author's
awareness, by library routines which invoke shells to carry out
When the binary program is run
then the shell procedure runs with the permissions afforded to the
owner of the binary file.
parameter is used to split each word into separate command arguments.
If a user knows that some
then the user sets and exports
The user puts his or her own
program into the current directory.
create a copy of the shell,
program so that the original program continues to run successfully.
This kind of penetration is not possible with
parameter only splits arguments that result from command or parameter
programs run programs using
without giving the full path name.
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,
mode whenever the real and effective user or group id are not the same.
variable is reset to a default value and the
This gives an administrator control over the
variable or to log setuid shell invocations.
Clearly security of the system is compromised if
or this file is publicly writable.
In BSD UNIX the operating system looks for the characters
as the first two characters of an executable file.
If these characters are found, then the next word on this line is taken
for this command and the interpreter is
with the name of the script as argument zero and argument one.
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.
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
procedures provide an easy target for intrusion.
procedure to a name beginning with a
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
to guard against this simple form of intrusion.
A more reliable way to handle
procedures is provided with
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.
The method relies on a setuid
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
For security reasons, this program is given the full
A description of the implementation of the
TM-59554-860602-03, 1986.
Ksh-i has several additional features to enhance functionality and performance.
This section lists most of these features.
.H 2 "Tilde substitution"
at the beginning of a word has special meaning to Ksh-i.
If the characters after the
match a user login name in the
and the name are replaced by
that user's login directory.
If no match is found, the original word
by itself, or in front of a
is replaced by the value of the
is replaced by the value of
Tilde substitution takes place when the script is read,
not while it is executed.
.H 2 "Built-in I/O Redirection"
All built-in commands can be redirected.
Compound commands which are redirected are not carried out in
Several options have been added to the shell and
that can be used in place of flags for setting and resetting options.
will list the current option settings.
is used to disable file name generation.
from exiting the shell and possibly logging you out.
option will cause all commands whose name is a valid alias
This option is automatically turned on for non-interactive shells.
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
background jobs are run at a lower priority.
to be appended on every directory name resulting from a pattern match.
options provides additional security by disabling the
from being executed and by resetting the
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.
is read so that administrators can have control over setuid scripts.
command is built-into Ksh-i and therefore much faster.
command will take you where you expect to go even if you cross
will move you up one level closer to the root even if your
current directory is a symbolic link.
.H 2 "Previous Directory"
Ksh-i remembers your last directory
built-in can be given with argument
to return to the previous directory
and prints the name of the directory.
done twice returns you to the starting directory,
not the second previous directory.
manager has been written as shell
directories from the stack.
.H 2 "Additional Variables and Parameters"
Several new parameters have special meaning to Ksh-i.
is used to hold the current working directory of the shell.
is used to hold the previous working directory of the shell.
built-in described above.
are used for determining the edit modes as described above.
is used to define the startup file for non-login
control the size and location of the file containing
commands entered at a terminal.
) separated list of file names to be checked for changes
periodically. The user is notified
Each of the names in this list can be followed by a
and a prompt to be given when a change has been detected in the file.
The prompt will be evaluated for parameter substitution.
within a mail message will evaluate to the name of the file that
is used to specify the minimal interval in seconds before
produces a random number each time it is referenced.
Assignment to this variable sets the seed for the
is incremented every second.
In a roundabout way, this variable
can be used to generate a time stamp into the
The following code explains how you can do this on
System V. On BSD you need another command to initialize
# 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"'
is used to generate the process id of the process which invoked this shell.
The value of the parameter
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.
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
variable can be used to adjust the width of the edit window for
the in-line edit modes. It is also used by the
command to present menu choices.
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
.H 2 "Modified variables"
The input field separator parameter,
is only used to split words that have undergone parameter or command
In addition, adjacent non-blank delimiters separate
parameter is evaluated for parameter substitution and a
is replaced by the current command number.
has been added to replace
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
parenthesis should be used to redirect the timing information which
is normally printed on file descriptor 2.
This process will be run with its standard input and its
standard output connected to the shell. The built-in command
option will write into the standard input of this
option will read from the output of this process.
Only one such process can exist at any time.
.H 2 "Process Substitution"
This feature is only available
on versions of the UNIX operating system which support the
directory for naming open files.
Each command argument of the form
\f3(\fP\f2list\^\fP\f3)\fP,
\f3<(\fP\f2list\^\fP\f3)\fP,
\f3>(\fP\f2list\^\fP\f3)\fP
asynchronously connected to some file in the
The name of this file will become the argument to the command.
is selected then writing on this file will provide input for
then the file passed as an argument will contain the output of the
paste (cut \-f1 \f2file1\fP) (cut \-f3 \f2file2\fP) | tee >(\f2process1\fP) >(\fP\f2process2\fP)
the results together, and
as well as putting it onto the standard output.
Note that the file which is passed as an argument to the command is
so that the programs that expect to
on the file will not work.
.H 2 "Command Substitution"
Command substitution ( \fB\(ga\(ga\fR)
in the Bourne shell suffers from some
complicated quoting rules.
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
are evaluated as a command the output is substituted just as
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
The special command substitution of the form
which is faster because no separate process is created.
has made it substantially more difficult to know what
a given command word really means.
option has been provided to answer this question.
A line is printed for each argument to
telling what would happen if this argument were used as a command name.
It reports on keywords, aliases, built-ins, and
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"
can be used to compare the modification times
of two files to see which is file is
is used to see if two files
have the same device and i-node number,
i.\ e., a link to the same file.
returns true for a symbolic link.
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
This trap is invoked whenever the shell would exit if the
Fourth Generation Make\*(Rf
"The Fourth Generation Make,"
Proceedings of the Portland USENIX meeting, pp. 159-174, 1985.
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
Case 40094-21, July 1982.
and have been adopted as described in his memo.
.H 2 "Coded in Standard C"
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.
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.
Ksh-i treats eight bit characters transparently without stripping off the
There is also a compile time switch to enable handling multi-byte
and multi-width characters sets.
.H 2 "No special meaning for ^"
as an archaic synonym for
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,
is legal in Ksh-i but illegal in the Bourne shell.
Ksh-i will perform file name expansion of file name arguments if the
expansion is unique. Thus,
will expand the file name if the expansion is unique.
If you invoke the shell as
then Ksh-i will do a path search on script.
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.
Run time error messages detected by the shell will print the
line number within a function or script where the error was
An example of a Ksh-i script is included
This one page program is a variant of the UNIX
Pattern matching for this version of
means shell patterns consisting of
The first half examines option flags.
Note that all options except
The second half goes through each line of each file
to look for a pattern match.
This program is not intended to serve as a
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
Ksh-i executes many scripts faster than the System V Bourne shell.
One major reason is that many of the functions provided by
The time to execute a built-in function is one or two
orders of magnitude faster than performing a fork and
Command substitution of built-ins is performed without
creating another process, and often without even
creating a temporary file.
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
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.
Scripts that do little internal processing and create many processes
may run a little slower on System V because the time to
Ksh-i is slightly slower than for the Bourne shell.
On BSD Unix, Ksh-i can be compiled with a
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.
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
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
value which evaluates to a file name for interactive shells and to
the null string otherwise. If you export the startup file name
ENV='${START[(_$\-=1)+(_=0)\-(_$\-!=_${\-%%*i*})]}'
will only invoke the startup file for interactive shells
since the subscript evaluates to 0
only if the shell is interactive.
parameter to distinguish which actions only apply to interactive shells.
# options aliases and functions for all shell invocations
# options aliases and functions for interactive only
If there are functions which are only occasionally referenced, put them
file for each function name of the form
alias \f2function_name\fP='. $HOME/functions;\f2function_name\fP'
file you must unalias each of the function names defined in the
The first reference to any
causes the function file to get read in and the functions compiled.
Ksh-i has several thousand regular users.
Ksh-i is a suitable replacement for the Bourne shell.
and is essentially upward compatible with the Bourne shell.
.SG dgk \" signature typist initials
Laboratory 4542 Supervision
.CS 14 24 38 0 0 16 \" cover sheet for TM
vflag= xflag= cflag= lflag= nflag=
while ((1)) # look for grep options
\-b*) print \(fmb option not supported\(fm;;
\-f*) shift;expr=$( < $1 );;
\-*) print $0: \(fmunknown flag\(fm;exit 2;;
*) if test "$expr" = \(fm\|\(fm
test "$xflag" |\|| expr="*${expr}*"
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
test "$i" && exec 0< $i # open file if necessary
while read \-r line # read in a line
$expr) # line matches pattern
then print \-r "$fname${nflag:+$n:}$line"
then print \-r "$fname${nflag:+$n:}$line"
if test "$lflag" && ((c))
test "$cflag" && print $tc # print count if cflag is set
let tc # set the exit value