KSH Description (1200+ Lines)
Bill Wisner
bdw at chinet.UUCP
Fri Feb 14 12:39:12 AEST 1986
We have ksh on chinet, and this document has been floating around for a
while. It is a description/abstract/explanation of ksh, the Korn Shell.
It does NOT include information on licensing, etc, but I may be able to
post that within a few days (after talking to root)..
--cut here---------------------and here--------------------here, too--
1. Introduction
Over the past two or three 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,
vicmd[3] preserves the friendly environment of vi (from
which this memo was entered), and adds a facility for
convenient command entry. An emacs oriented shell has also
been written by Veach[4]. The 2dsh[5] shell allows the
setup of more complicated networks of processes than just
pipelines. The See-shell[6] proposes a Small-Talk like
interface[7] suitable for bit-mapped terminals such as the
BLIT[8] and the Apollo[9]. Perhaps the most widely used
shell, other than the Bourne shell, is 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[10].
The use of the shell as a programming language has been
described by Dolotta and Mashey[11] and has been used by
many people here at Bell Laboratories. Kolettis[12]
presented extensions to the Bourne shell to provide message
passing facilities and other inter-process communication and
synchronization features. The Form shell[13] added form
entry/edit capabilities to the Bourne shell. A proposal for
a more programming language oriented shell has been proposed
by Sturzenbecker[14].
- 2 -
This memo describes Ksh, aka the Korn-shell. This memo is
not a tutorial, only an introduction. Ksh 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 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. The
description of features in this memo assumes that the reader
is already familiar with the Bourne shell.
A version of Ksh has been run on several machines including
a VAX 11/780, VAX 11/750, PDP-11/70, PDP-11/23, IBM-370,
AT&T 3B20, and Apollo Domain. It has been run on top of
several versions of the UNIX operating system including
System III, System V, BSD 4.1, BSD 4.1c, 4.2, and Apollo
UNIX. The shell is in use in several centers at AT&T Bell
Laboratories, and has been installed as /bin/sh on VAXEN
running System V, BSD 4.1., BSD 4.2 and on a 3B-20 running
System V.
2. Shell Variables
The ability to define and use variables to store and
retrieve values is an important feature in most programming
languages. Ksh has variables with identifiers that follow
the same rules as the Bourne shell. Since all variables
have string representations, there is no need to specify the
type of each variable in the shell. In Ksh, each variable
can have one or more attributes that control the internal
representation of the variable, the way the variable is
printed, and its access or scope. Two of the attributes,
readonly and export, are available in the Bourne shell. The
typeset built-in command of Ksh assigns attributes to
variables. The list of attributes appears in the manual
page. The unset built-in of the Ksh 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, the first time an assignment is made to the
variable its size is remembered. Each assignment causes
- 3 -
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.
The attributes -u and -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 : and prints fields 4
and 2 in upper case in columns 1-15, left justified, and
columns 20-25 right-justified respectively.
typeset -Lu f4=123456789012345 # 15 character left justified
typeset -Ru f2=123456 # 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
The integer attribute, -i, causes the variable to be
internally represented as an integer. The first assignment
to an integer variable determines the output base (see
below). This base will be used whenever the variable is
printed. Assignment to integer typed variables result in
arithmetic evaluation, as described below, of the right hand
side.
Ksh allows one-dimensional arrays in addition to simple
variables. Any variable can become an array by referring to
it with a subscript. All elements of an array need not
exist. Subscripts for arrays must evaluate to an integer
between 0 and 127, otherwise an error results. Evaluation
of subscripts is described in the next section. Attributes
apply to the whole array.
Assignments to array variables are made with the typeset
built-in. 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:
${name[subscript]}.
A subscript value of * or @ can be used to generate all
elements of an array, as they are used for expansion of
positional parameters.
- 4 -
A few additional operations are available on shell
variables. ${#name} will be then length in bytes of $name.
For an array variable ${#name[*]} gives the number of
elements in the array.
There are two parameter substitution modifiers that have
been added to strip off leading and trailing substrings
during parameter substitution. The modifier # strips off
from the left and the modifier % strips off from the right.
For example, if the shell variable i has value file.c, then
the expression ${i%.c} has value file. The substring
built-in has been added to Ksh to enable the user to
generate a substring of a given string. The built-in allows
the user to specify an expression to be deleted from the
left and right ends of the string. The resulting substring
is printed out. Command substitution can be used to assign
the output of substring to a shell variable.
3. Arithmetic Evaluation
The built-in command, let, provides the ability to do
integer arithmetic. All arithmetic evaluations are
performed using long arithmetic. Arithmetic constants are
written as
base#number
where base is a decimal integer between two and thirty-six
and number is any positive integer. Base ten is used if no
base is specified.
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
let x=x+1
can be used to increment a variable x. Note that there is
no space before or after the operators + and =. This is
because each argument to let is an expression to evaluate.
The last expression determines the value returned by let.
If the last expression evaluates to a non-zero value, the
let returns true. Otherwise, let returns false.
Note that 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
- 5 -
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,
(( ... ))
is equivalent to
let " ... "
The following script prints the first n lines of its
standard input onto its standard output, where n is supplied
as an argument or is 20 if omitted.
typeset -i n=${1-20} # set n
while read -r line && (( (n=n-1)>=0 ))# at most n lines
do print -r - "$line"
done
4. Functions and Command Aliasing
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 aliasing.
As a command is being read, the command name is checked
against a list of alias names. If it is found, the name is
replaced by the text associated with the alias and then
rescanned. The text of an alias is not checked for aliases
so recursive definitions are not allowed.
Aliases are defined with the alias built-in. The form of an
alias command is:
alias name=value
Except for the first character, which must be printable, the
alias name must be a valid identifier. The replacement
text, value, can contain any valid shell script, including
metacharacters such as pipe symbols and i/o-redirection.
Aliases can be used to redefine built-in commands so that
the alias
alias test=./test
can be used to look for test in your current working
directory rather than using the built-in test command.
Keywords such as for and while cannot be changed by
aliasing. The command alias, without arguments, generates a
list of aliases and corresponding texts. The unalias
command removes the name and text of an alias.
- 6 -
Aliases are used to save typing and to improve readability
of scripts. For example, the alias alias integer='typeset
-i' allows integer the variables i and j to be declared and
initialized with the command integer i=0 j=1.
One frequent use of aliases is to alias a command name to
the full path-name of the program. This eliminates the path
search but requires knowledge of where that program will be
stored. To reduce the amount of path searching, tracked
aliases have been introduced. 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 PATH variable is changed.
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 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. An option to the shell
allows all command names that are valid alias names to
become tracked aliases.
Functions are more general than aliases but also more
costly. Functions definitions are of the form
function name
{
any shell script
}
The function is invoked by writing 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. The
return built-in can be used to cause the function to return
to the statement following the point of invocation.
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 typeset, built-in command are local to the function that
they are declared in. Thus, for the function defined
function name
{
typeset -i x=10
let z=x+y
- 7 -
print $z
}
invoked as y=13 name, x and y are local variables with
respect to the function name while z is global.
Alias and function names are never directly carried across
separate invocations of Ksh, but can be passed down to sub-
shells. The -x flag is used with alias to carry aliases to
sub-shells while the -fx flags of typeset are used to do the
same for functions.
Several of the UNIX commands can be aliased to Ksh 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. Each user can
create a file for aliases and functions. Aliases and
functions that are to be available for all shell invocations
should be put into the Ksh startup file. By setting and
exporting the environment variable, ENV, to the name of this
file, the aliases and functions will be defined each time
Ksh is invoked. The value of the ENV variable undergoes
macro and command substitution prior to its use. Since the
ENV file is not invoked automatically for a log in shell, it
is usually necessary to include the line eval . $ENV in your
.profile file.
5. Input and Output
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 read for reading lines from file descriptor
0, but does not have any internal output mechanism. As a
result, the 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 echo the line exactly as is. In the
Bourne shell, the read built-in cannot be used to read lines
that end in `\', and the 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.
Ksh has options on the read command to specify the file
descriptor for the input. The exec built-in can be used to
open and close file streams. The -r option allows a `\' 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 read 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
- 8 -
prompt is not issued.
The Ksh built-in, 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 echo(1). However, the -r flag can be used to
output the arguments without any special meaning. The -n
flag can be used here to suppress the trailing new-line that
is ordinarily appended.
To improve performance of existing shell programs, an alias
for echo is defined by the shell when it is invoked. For
the AT&T-UNIX version, the alias is
alias echo='print -',
where the - signifies that there are no more options, while
for the Berkeley UNIX version
alias echo='print -R',
where the -R option allows only the -n flag to be recognized
as the next argument, gives the desired result.
The shell is frequently used as a programming language for
interactive dialogues. The 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, 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 REPLY
variable is used to store the user entered reply.
6. Command Re-entry
An interactive shell saves the commands you type at a
terminal in a file. If the variable HISTFILE is set to the
name of a file to which the user has write access, then the
commands are stored in this history file. Otherwise the
file $HOME/.history is checked for write access and if this
fails an unnamed file is used to hold the history lines.
This file is truncated if this is a top level shell. The
number of commands accessible to the user, is determined by
the value of the HISTSIZE variable at the time the shell is
invoked. The default value is 64. A command may consist of
one or more lines since a compound command is considered one
command. If the character ! is placed within the primary
prompt string, then it is replaced by the command number
each time the prompt is given. Whenever the file is named,
all shells which use this file share access to the same
history.
- 9 -
A built-in command 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 -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.
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. The editor to be used may be specified
with the option -e and following it with the editor name.
If this option is not specified, the value of the shell
variable 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 -e option has not been
selected, then /bin/ed is used. When editing has been
complete, the edited text automatically becomes the input
for Ksh. As this text is read by Ksh, it is echoed onto the
terminal.
An editor name of - 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 old=new may be added which requests a simple string
substitution prior to evaluation. A convenient alias,
alias r='fc -e -'
has been pre-defined so that the single key-stroke r can be
used to re-execute the previous command and the key-stroke
sequence, r abc=def c can be used to re-execute the last
command that starts with the letter c with the first
occurrence of the string abc replaced with the string def.
Typing r c > file re-executes the most recent command
starting with the letter c, with standard output redirected
to file.
7. In-line editing
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 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
- 10 -
portion visible. Editing can be performed on this window
until the 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
HISTSIZE 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 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.
There is a choice of editor options. The emacs, gmacs, or
vi option is selected by turning on the corresponding option
of the set command. If the value of the EDITOR or 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.
The code for the emacs and gmacs editing option was supplied
by Mike Veach. In the emacs or 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 ^T. Control keys and escape sequences are used
for cursor positioning and control functions. The available
editing functions are listed in the manual page.
The code for the vi editing option was supplied by Pat
Sullivan. The vi editing mode starts in insert mode and
enters control mode when the user types ESC( 033). The
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 vi
commands are available. The k and j command that normally
move up and down by one line, move up and down one command
in the history file, copying the command at into the input
edit window. For reasons of efficiency, the terminal is
kept in canonical mode until an ESC is typed. On some
terminals, and on earlier versions of the UNIX operating
system, this doesn't work correctly. The viraw option of
the set command, which always uses raw or cbreak mode, must
be used in this case.
- 11 -
8. Job Control
The job control mechanism is almost identical to the version
found in 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 monitor option which when
enabled will report the progress of background jobs and
enable the user to kill jobs by job number or job name.
An interactive shell associates a 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 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 ^Z (control-Z) which sends a 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
and background. There are several ways to refer to jobs.
The character % introduces a job name. You can refer to
jobs by name or number as described in the manual page. The
built-in command bg allows you to continue a job in the
background, while the built-in command fg 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 appropriately.
There is a built-in command 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. If
you ignore this message and try to leave again, all stopped
processes will be terminated.
A built-in version of kill makes it possible to use 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 include file /usr/include/signal.h with the prefix SIG
- 12 -
removed. The list of valid signal names can be generated
with the -l flag of kill.
9. Miscellaneous
Ksh has several additional features to enhance functionality
and performance. This section lists most of these features.
9.1 Tilde substitution
The character 8 at the beginning of a word has special
meaning to Ksh. If the characters after the 8 up to a /
match a user login name in the /etc/passwd file,9then the 8
and the name are replaced by that user's login directory.
If no match is found, the original word is unchanged. A 8
by itself, or in front of a /, is replaced by the value of
the HOME parameter. A 8 followed by a + or - is replaced by
the value of the parameter PWD and OLDPWD respectively.
Tilde substitution takes place when the script is read, not
while it is executed.
9.2 Built-in I/O Redirection
All built-in commands can be redirected.
9.3 Added options
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 set -o will list the
current option settings.
The option, -f or noglob is used to disable file name
generation. It can be applied at invocation or as an option
to the set command.
The option ignoreeof can be used in a top-level shell to
prevent ^D from logging you out. You must type exit to log
out.
The -h or trackall option will cause all commands whose name
is a valid alias name to become a tracked alias.
The job monitor option will cause a report to be printed
when each background job completes. It is automatically
enabled for systems that have job control.
If the bgnice option is set, background jobs are run at a
lower priority.
- 13 -
9.4 Previous Directory
Ksh remembers your last directory in the variable OLDPWD.
The cd built-in can be given with argument - to return to
the previous directory. Note that cd - done twice returns
you to the starting directory, not the second previous
directory. A directory stack can be implemented with shell
internals by using an array and writing shell functions to
push and pop directories from the stack.
9.5 Additional Variables and Parameters
Several new parameters have special meaning to Ksh. The
variable PWD is used to hold the current working directory
of the shell. The command, pwd, is aliased to print - $PWD
for better response. The variable OLDPWD is used to hold
the previous working directory of the shell.
The variable FCEDIT is used by the fc built-in described
above. The variables VISUAL and EDITOR are used for
determining the edit modes as described above.
The variable ENV is used to define the startup file for
non-login Ksh invocations.
The variables HISTSIZE and HISTFILE control the size and
location of the file containing commands entered at a
terminal.
The parameter MAILPATH is a colon ( : ) 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 ? and a prompt to be given
when a change has been detected in the file. The prompt
will be evaluated for macro and command substitution. The
parameter MAILCHECK is used to specify the minimal interval
in seconds before new mail is checked for.
The variable RANDOM produces a random number each time it is
referenced. Assignment to this variable sets the seed for
the random number generator.
The parameter PPID is used to generate the parent process id
of the shell.
The value of the parameter _ is the last argument of the
previous command.
The parameter TMOUT can be set to be the number of seconds
that the shell will wait for input before terminating.
- 14 -
The COLS variable can be used to adjust the width of the
edit window for the in-line edit modes.
9.6 Modified variables
The input field separator parameter, IFS, has meaning for
the read built-in, for the set built-in, and while expanding
for and select lists. In all other instances it is ignored.
9.7 Timing Commands
A keyword time has been added to replace the 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 time, parenthesis should be used to redirect the
timing information which is normally printed on file
descriptor 2.
9.8 Command Substitution
The special command substitution of the form `cat file` can
be replaced by `< file`, which is faster because no separate
process is created.
9.9 Whence
The addition of aliases, functions, and more built-ins has
made it substantially more difficult to know what a given
command word really means. A built-in command, whence when
used with the -v option has been provided to answer this
question. A line is printed for each argument to 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.
9.10 Additional test operators
The operators -ot and -nt can be used to compare the
modification times of two files to see which is file is
older than or newer than the other. The operator -ef is
used to see if two files have the same device and i-node
number, i. e., a link to the same file.
- 15 -
9.11 Shell Accounting
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[15]
and have been adopted as described in his memo.
9.12 Coded in Standard C
The Bourne shell is coded in an ALGOL-68 like dialect of C.
Ksh is coded in standard C.
9.13 No special meaning for ^
The Bourne shell uses ^ as an archaic synonym for |. The ^
is not a special character to Ksh.
10. Example
An example of a Ksh script is included in the Appendix.
This one page program is a variant of the UNIX grep(1)
program. Pattern matching for this version of grep means
shell patterns consisting of ?, *, and [].
The first half examines option flags. Note that all options
except -b have been implemented. 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 replacement for
grep; just as an illustration of the programming power of
Ksh. 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 grep for large
files.
11. Performance
Ksh executes many scripts faster than the System V Bourne
shell. One major reason is that many of the functions
provided by echo(1) and 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.
Another reason for improved performance is that all I/O is
buffered. Output buffers are flushed only when required.
- 16 -
Several of the internal algorithms have been changed so that
the number of subroutine calls has been substantially
reduced. Ksh 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 run a little slower because the time to fork Ksh
is slower than for the Bourne shell.
12. Conclusion
More than one thousand people have tried Ksh and use it
regularly. Ksh is a suitable replacement for the Bourne
shell. It offers new features, better performance, and is
essentially upward compatible with the Bourne shell. Many
of the known bugs of the Bourne shell have been eliminated.
MH-59545-DGK-dgk D. G. Korn
Copy to
Members of Center 5954
Laboratory 4542 Supervision
D. A. Lambeth
N. J. Kolettis
W. P. Weber
E. G. Bradford
J. L. Steffen
S. L Arnold
M. C. Sturzenbecker
M. T. Veach
J. Krist
- 17 -
References
1. S. R. Bourne, An Introduction to the UNIX Shell," BSTJ -
Vol. 57, No. 6 part 2, pages 1947-1972.
2. W. Joy, An Introduction to the C Shell, University of
California, Berkeley, 1980.
3. S. L. Arnold, Vicmd a Visual Shell for Video Terminals,
TM-81-54533-12, 1981.
4. J. L. Steffen and M. T. Veach, The Edit Shell -
Connecting Screen Editing with the History List, USENIX
Association Toronto Proceedings, 1983.
5. M. J. Rochkind, 2dsh - An Experimental Shell for
Connecting Processes With Multiple Data Streams, TM-80-
9323-3.
6. Wayne T. Wilner, See-Shell: a Graphical User-Interface
for UNIX Systems, Bell Laboratories internal memorandum,
1982.
7. D. C. Smith, C. Irby, R. Kimball, and B. Verplank,
Designing the Star User Interface, BYTE, April, 1982,
pp. 242-282.
8. R. Pike, The Blit Programmer's manual, Bell Labs, 1982.
9. P. J. Leach, P. H. Levine, B. P. Douros, J. A. Hamilton,
D. L. Nelson, and B. L. Stumfp, The Architecture of an
Integrated Local Network, IEEE Journal of Selected Areas
in Communications, Local Area Networks Special Issue,
November 1983.
10. J. L. Steffen, An Input History for the Bourne Shell,
TM-82-55426-3, 1982.
11. T. A. Dolotta and J. R. Mashey, Using the shell as a
Primary Programming Tool, Proc. 2nd. Int. Conf. on
Software Engineering, 1976, pages 169-176.
12. N. J. Kolettis. Extended Shell - A Potential Real Time
Interpreter, TM-77-4145-01, 1977.
13. D. G. Korn and D. A. Lambeth, Form Shell, TM-80-9224-3,
1980.
- 18 -
14. M. C. Sturzenbecker, A New Command Language for UNIX and
related systems, TM-82-45192-3.
15. T. H. Foregger, Shell Accounting, Case 40094-21, July
1982.
ABSTRACT
Ksh is a command language (shell) for the UNIX* operating
system. It is essentially [1]patible with the System V
version of the Bourne shell [2]has many additional
features, such as those found in Csh , 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. The manual page
for the current version is also included.
_____________________________________________________________________
APPENDIX
#
# 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 'b option not supported';;
-e*) shift;expr="$1";;
-f*) shift;expr`< $`;;
-*) print $0: 'unknown flag';exit 2;;
*) if test "$expr" = ''
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 thru the files
do if ((nargs<=1))
then fname=''
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
--
Bill Wisner / The Computer Connection
UUCP: ihnp4!chinet!bdw
CIS: 76474,1213
USNail: 6290 Highway 44
Star, ID 83669
Witty Quote: If you owned the universe, where would you put it?
Witty Disclaimer: When I want your opinion, I'll give it to you.
More information about the Comp.unix
mailing list