xref: /original-bsd/local/toolchest/ksh/sh.memo (revision 31205e5f)
1.nr N 2
2.PF "'Copyright (c) 1984, 1985, 1986, 1987''AT&T All Rights Reserved'"
3.SA 1  \"  right justified
4.TL "311531-0101" "49059-6"  \" charging case filing case
5Introduction to KSH-I ( Issue 3)
6.AU "David G. Korn" DGK MH 59554 7975 5D-112 "(ulysses!dgk)"
7.TM  59554-860602-04  \"  technical memo + TM numbers
8.AS 1   \" abstract start for TM
9Ksh-i is a command language (shell) for the UNIX*\
10.FS  *
11UNIX is a trademark of Bell Laboratories.
12.FE
13operating system.
14It is essentially compatible with the System V version of the Bourne shell\*(Rf ,
15.RS
16S. R. Bourne,
17.I "An Introduction to the UNIX
18Shell,"
19BSTJ - Vol. 57, No. 6 part 2, pages 1947-1972.
20.RF
21has many additional features,
22such as those found in
23.IR Csh\*(Rf ,
24.RS
25W. Joy,
26.I "An Introduction to the C Shell,"
27University of California, Berkeley, 1980.
28.RF
29and executes faster than either of these shells.
30This memo introduces many of the additional features
31and explains some of the reasons for the better
32performance.
33This memo
34assumes that the reader is already familiar with the Bourne shell.
35The Appendix contains
36a sample script written in Ksh-i.
37The manual page for the current version is also included.
38.AE   \" abstract end
39.OK Shell "Command interpreter" Language UNIX  \" keyword
40.MT 1  \"  memo type
41.H 1 "Introduction"
42.P
43Over the past several years several papers
44have been written describing new command interpreters
45for the UNIX system.
46These papers can be divided into two categories:
47Those that improve the shell as a programming language,
48and those that improve the shell as a command interpreter.
49Most of the papers fall into the latter category.
50In particular,
51.IR vicmd \*(Rf
52.RS
53S. L. Arnold,
54.I "Vicmd a Visual Shell for Video Terminals,"
55TM-81-54533-12, 1981.
56.RF
57preserves the friendly environment of
58.I vi
59(from which this memo was entered),
60and adds a facility for convenient command entry.
61An
62.I emacs
63oriented shell
64has also been written by Veach\*(Rf.
65.RS
66J. L. Steffen and
67M. T. Veach,
68.I "The Edit Shell - Connecting Screen Editing with the History List,"
69USENIX Association Toronto Proceedings, 1983.
70.RF
71The
72.IR 2dsh \*(Rf
73.RS
74M. J. Rochkind,
75.I "2dsh - An Experimental Shell for Connecting Processes With Multiple Data Streams,"
76TM-80-9323-3.
77.RF
78shell allows the setup of more complicated networks of processes than
79just pipelines.
80The never developed
81.IR See-shell \*(Rf
82.RS
83Wayne T. Wilner,
84.I "See-Shell: a Graphical User-Interface for UNIX Systems,"
85Bell Laboratories internal memorandum, 1982.
86.RF
87proposes a Small-Talk like interface\*(Rf
88.RS
89D. C. Smith, C. Irby, R. Kimball, and B. Verplank,
90.I "Designing the Star User Interface,"
91BYTE, April, 1982, pp. 242-282.
92.RF
93suitable for bit-mapped terminals such as the BLIT\*(Rf
94.RS
95R. Pike,
96.I "The Blit Programmer's manual,"
97Bell Labs, 1982.
98.RF
99and the Apollo\*(Rf.
100.RS
101P. J. Leach,
102P. H. Levine,
103B. P. Douros,
104J. A. Hamilton,
105D. L. Nelson,
106and B. L. Stumfp,
107.I "The Architecture of an Integrated Local Network,"
108IEEE Journal of Selected Areas in Communications,
109Local Area Networks Special Issue, November 1983.
110.RF
111Perhaps the most widely used shell,
112other than the Bourne shell, is
113.IR Csh ,
114which runs under the Berkeley UNIX operating system.
115Csh has many attractive command interpreter features
116not currently in the Bourne shell;
117most notably, job control,
118history,
119arithmetic,
120and command name aliasing.
121On the other hand,
122many people (including this author),
123think that the Bourne shell is superior as a programming language.
124The history mechanism of Csh has recently been added as a local modification
125to the Bourne shell by
126J. L. Steffen\*(Rf.
127.RS
128J. L. Steffen,
129.I "An Input History for the Bourne Shell,"
130TM-82-55426-3, 1982.
131.RF
132.P
133The use of the shell as a programming language has been
134described by Dolotta and Mashey\*(Rf
135.RS
136T. A. Dolotta and J. R. Mashey,
137.I "Using the shell as a Primary Programming Tool,"
138Proc. 2nd. Int. Conf. on Software Engineering, 1976,
139pages 169-176.
140.RF
141and has been used by many people here
142at Bell Laboratories.
143Kolettis\*(Rf
144.RS
145N. J. Kolettis.
146.I "Extended Shell - A Potential Real Time Interpreter,"
147TM-77-4145-01, 1977.
148.RF
149presented extensions to the Bourne shell to provide
150message passing facilities and other inter-process communication and
151synchronization features.
152The Form shell\*(Rf
153.RS
154D. G. Korn and D. A. Lambeth,
155.I "Form Shell,"
156TM-80-9224-3, 1980.
157.RF
158added form entry/edit capabilities to the Bourne shell.
159A proposal for a more programming language oriented shell has
160been proposed by Sturzenbecker\*(Rf.
161.RS
162M. C. Sturzenbecker,
163.I "A New Command Language for UNIX and related systems,"
164TM-82-45192-3.
165.RF
166.P
167This memo describes
168.IR Ksh-i ,
169aka Korn shell-international.
170This memo is not a tutorial, only an introduction.
171A description of the
172.IR Korn shell
173can be found in Kochan and Wood\*(Rf.
174.RS
175S. G. Kochan and P. H. Wood,
176"Unix Shell Programming,"
177Hayden Book Company, 1985.
178.RF
179Ksh-i is a direct descendant of the
180Form shell
181with most of the
182form entry/edit features removed and with many new
183features added.
184The primary focus of this work has been to provide an
185enhanced programming environment in addition
186to the major command entry features of
187.IR Csh .
188Improved performance has been a major objective.
189Many of the additions have been provided so that
190medium sized programming tasks can be written
191at the shell level without a serious performance
192penalty.
193A concerted effort has been made to achieve System V Bourne shell
194compatibility so that scripts written for the Bourne shell
195can run without modification with Ksh-i.
196The description of features in this memo assumes
197that the reader is already familiar with the Bourne shell.
198.P
199A version of Ksh-i has been run on several machines
200including but not limited to VAXEN , PDP-11's, IBM-370's,
201AT&T 3B's, UNIX-PC, PC-6300+, Suns, Alliant, CCI, Sequent,
202Pyramid, and Apollo Domain.
203It has been run on top of several versions of the UNIX operating system including
204Venix, Xenix, System III, System V, UTS,
205BSD 4.1, 4.2, 4.3, 8th. Edition, and DOMAIN/IX.
206The shell is in use in several centers at AT&T Bell Laboratories,
207and has been installed as
208.I /bin/sh
209on  VAXEN running System V, BSD 4.1., BSD 4.2,
2103B's, PC-6300+,  and UNIX-PC's running System V.
211.H 1 "Shell Variables"
212.P
213The ability to define and use variables to store and retrieve values
214is an important feature in most programming languages.
215Ksh-i has variables with
216.I identifier
217names that follow the
218same rules as the Bourne shell.
219Since all variables have string representations,
220there is no need to specify the
221.I type
222of each variable in the shell.
223In Ksh-i,
224each variable can have one or more
225.I attributes
226that control the internal representation of the variable,
227the way the variable is printed, and its access or
228scope.
229Two of the attributes,
230.I readonly
231and
232.IR export ,
233are available in the Bourne shell.
234The
235.B typeset
236built-in command of Ksh-i
237assigns attributes to variables.
238The complete list of attributes,
239some of which are discussed here,
240appears in the manual page.
241The
242.B unset
243built-in of the Ksh-i removes
244values and attributes of parameters.
245.P
246Whenever a value is assigned to a variable,
247the value is transformed according to the attributes of the variable.
248Changing the attribute of a variable can change its value.
249There are three attributes for field justification,
250as might be needed for formatting a report.
251For each of these attributes, a width can be defined explicitly  or else
252it is defined the first time an assignment is made to the variable it
253Each assignment causes justification of the field, truncating
254if necessary.
255Assignment to fixed sized variables
256provides a simple way to generate a substring consisting of
257a fixed number of characters from
258the beginning or end of a string.
259.P
260The attributes
261.B \-u
262and
263.BR \-l ,
264are used for upper case and lower case
265formatting respectively.
266Since it makes no sense to have both attributes on simultaneously,
267turning on either of these attributes turns the other off.
268The following script provides an example of the use of shell variables
269with attributes.
270This script reads a file of lines each consisting of five fields separated by
271.B :
272and prints fields 4 and 2 in upper case in columns 1-15, left justified,
273and columns 20-25 right-justified respectively.
274.sp
275.nf
276.in .5i
277.ta 3.4i
278.B
279typeset \-L15u f4		# 15 character left justified
280typeset \-R6u f2       	# 6 character right justified
281IFS=:
282set \-f                     	# skip file name generation
283while   read \-r f1 f2 f3 f4 f5	# read line, split into fields
284do      print \-r "$f4    $f2" 	# print fields 4 and 2
285done
286.fi
287.ta
288.in
289.sp
290.R
291.P
292The integer attribute,
293.BR \-i ,
294causes the variable to be internally represented as an integer.
295The
296.B i
297can be followed by a number representing the numeric base for printing, otherwise
298the first assignment to an
299.I integer
300variable defines the output
301.I base
302(see below).
303This base will be used
304whenever the variable is printed.
305Assignment to
306.I integer
307typed variables result in arithmetic evaluation,
308as described below,
309of the right hand side.
310.P
311Ksh-i allows one-dimensional
312.I arrays
313in addition to simple variables.
314Any variable can become an array
315by referring to it with
316a
317.IR subscript .
318All elements of an array need not exist.
319Subscripts for arrays
320must evaluate to an
321integer between 0 and 511, otherwise
322an error results.
323Evaluation of subscripts is described in
324the next section.
325Attributes apply to the whole array.
326.P
327Assignments to array variables can be made with parameter assignment statements
328or with the
329.B typeset
330built-in.
331Referencing of subscripted variables requires the character
332.BR $ ,
333but also requires braces around the array element name.
334The braces are needed to avoid conflicts with the
335file name generation mechanism.
336The form of any array element reference is:
337.ce
338.BI ${ name [ subscript ]} .
339A subscript value of
340.B *
341or
342.B @
343can be used to generate all elements of an array,
344as they are used for expansion of positional parameters.
345.P
346A few additional operations are available on shell variables.
347\f3${#\fP\f2name\fP\f3}\fP
348will be the length in bytes of
349\f3$\fP\f2name\fP.
350For an array variable
351\f3${#\fP\f2name\fP\f3[*]}\fP
352gives the number of elements in the array.
353.P
354There are four parameter substitution modifiers that
355have been added to strip off leading and trailing substrings
356during parameter substitution.
357The modifier
358.BR # ( ## )
359strips off the smallest (largest) matching pattern from the left
360and the modifier
361.BR % ( %% )
362strips off the smallest (largest) matching pattern from the right.
363For example, if the shell variable
364.B i
365has value
366.BR file.c ,
367then the expression
368.B ${i%.c}.o
369has value
370.BR file.o .
371.H 1 "Arithmetic Evaluation"
372.P
373The built-in command,
374.B let ,
375provides the ability to do integer arithmetic.
376All arithmetic evaluations are performed using
377.I long
378arithmetic.
379Arithmetic constants are written as
380.br
381.ce
382.IB base # number
383where
384.I base
385is a decimal integer between
386two and thirty-six and
387.I number
388is any non-negative number.
389Anything after a decimal point is truncated.
390Base ten is used
391if no base is specified.
392.P
393Arithmetic expressions are made from constants,
394variables, and one or more of the fourteen operators
395listed in the manual page.
396Operators are evaluated in order of precedence.
397Parentheses may be used for grouping.
398A variable does not have to have an integer attribute
399to be used within an arithmetic expression.
400The name of the variable is replaced
401by its value within an arithmetic
402expression.
403The statement
404.ce
405.B
406let x=x+1
407.R
408can be used to
409increment a variable
410.BR x .
411Note that there is no space before or after the operators
412.B +
413and
414.BR = .
415This is because each argument to
416.B let
417is an expression to evaluate.
418The last expression determines
419the value returned by
420.BR let .
421Let returns true
422if the last expression evaluates to a non-zero value.
423Otherwise,
424.B let
425returns false.
426.P
427Many of the arithmetic operators have special meaning
428to the shell and must be quoted.
429Since this can be burdensome, an alternate form of arithmetic
430evaluation syntax has been provided.
431For any command that begins with
432.BR (( ,
433all the characters until the matching
434.B ))
435are treated as a quoted arithmetic expression.
436The double parentheses
437usually avoids incompatibility with the Bourne shell's use of
438parentheses for grouping a set of commands
439to be run in a sub-shell.
440Expressions inside double parentheses can contain blanks
441and special characters without quoting.
442More precisely,
443.ce
444.B
445(( ... ))
446.R
447is equivalent to
448.ce
449.B
450let " ... "
451.R
452.P
453The following script prints the first
454.I n
455lines of its standard input onto its standard output,
456where
457.I n
458can be supplied as an optional argument whose default value is 20.
459.B
460.sp
461.nf
462.in .5i
463.ta 4i
464typeset \-i n=${1-20}                    	# set n
465while   read \-r line && (( (n=n\-1)>=0 ))	# at most n lines
466do      print \-r \- "$line"
467done
468.fi
469.ta
470.in
471.sp
472.R
473.H 1 "Functions and Command Aliasing"
474.P
475Two new mechanisms have been provided for creating
476pseudo-commands, i. e.,
477things that look like commands,
478but do not always create a process.
479The first technique is called command name
480.IR aliasing .
481.P
482As a command is being read,
483the command name is checked against a list of
484.I alias
485names.
486If it is found,
487the name is replaced by the text associated with the
488.I alias
489and then rescanned.
490The text of an alias is not checked for aliases
491so recursive definitions are not allowed.
492However, if the value of an alias ends in a space,
493then the word following the alias is also checked for alias substitution.
494.P
495Aliases are defined with the
496.B alias
497built-in.
498The form of an
499.B alias
500command definition is:
501.ce
502.BI "alias " name = value
503The first character of an
504.I alias
505name can be any non-special printable character, while all remaining characters
506must be  alpha-numeric.
507The replacement text,
508.I value,
509can contain any valid shell script,
510including meta-characters such as pipe symbols and i/o-redirection.
511Unlike
512.BR csh ,
513aliases in
514.B Ksh-i
515cannot take arguments.
516Aliases can be used to redefine built-in commands so that
517the alias
518.ce
519.B "alias test=./test"
520can be used to look for
521.I test
522in your current working directory rather than
523using the built-in
524.B test
525command.
526Keywords such as
527.B for
528and
529.B while
530cannot be changed by aliasing.
531The command
532.BR alias ,
533without arguments, generates
534a list of aliases and corresponding texts.
535The
536.B unalias
537command removes the name and text of an alias.
538.P
539Aliases are used to save typing and to improve readability of scripts.
540For example, the alias
541.B
542alias integer=\(fmtypeset \-i\(fm
543.R
544allows integer the variables
545.B i
546and
547.B j
548to be declared and initialized with the command
549.BR "integer i=0 j=1" .
550.P
551Aliases can be used to bind program names to the
552full path-name of the program.  This eliminates the path search
553but requires knowledge of where that program will be stored.
554.I Tracked
555aliases
556make this use for aliasing automatic.
557A tracked alias is not given a value.  Its value is
558defined at the first
559reference by a path-search as the full path-name equivalent of the name, and
560remains defined until the
561.B PATH
562variable is changed.
563Programs found in directories that do not begin with
564.B /
565that occur earlier in the path-search than the value of the
566tracked alias, take precedence over tracked aliases.
567.P
568Tracked aliases provide an alternative to the
569.I Csh
570command hashing facility. Tracked aliases do not require time for
571initialization and allow for new commands to be introduced
572without the need for re-hashing.
573The
574.B \-h
575option to the shell allows all command names that are
576valid alias names to become tracked aliases.
577This option is automatically turned on for non-interactive shells.
578.P
579.I Functions
580are more general than aliases but also more costly.
581Functions definitions are of the form
582.sp
583.in +.5i
584.BI "function " name
585.br
586.B {
587.br
588	any shell script
589.br
590.B }
591.sp
592.in
593The function is invoked by writing
594.I name
595and optionally following it with arguments.
596Positional parameters are saved before each
597function call and restored when completed.
598Functions are executed in the current shell environment
599and can share named variables with the calling program.
600Options, other than execution trace
601.BR \-x ,
602set by the calling program are
603passed down to a function.
604The option flags are
605not shared with
606the function so that any options set within a function are
607restored when the function exits.
608All traps other than
609.B EXIT
610and
611.B ERR
612(described later)
613are also inherited.
614A trap on
615.B EXIT
616within a function will execute after the function completes but
617before the caller resumes.
618Therefore,
619any variable assignments and
620any options set as part of a trap action will be effective
621after the caller resumes.
622The
623.B return
624built-in can be used to cause the function to return to
625the statement following
626the point of invocation.
627.P
628By default, variables are inherited by the function and shared
629by the calling program.
630However,
631environment substitutions preceding the function call
632apply only to the scope of the function call.
633Also, variables defined with the
634.BR typeset ,
635built-in command are local to the function that they are declared in.
636Thus, for the function defined
637.B
638.sp
639.nf
640.in .5i
641function  name
642{
643     typeset \-i x=10
644     let z=x+y
645     print $z
646}
647.fi
648.ta
649.in
650.sp
651.R
652invoked as
653.BR "y=13 name" ,
654.B x
655and
656.B y
657are local variables with respect to the function
658.B name
659while
660.B z
661is global.
662.P
663Alias and function names are never directly carried across separate
664invocations of Ksh-i, but can be passed down to sub-shells.
665Ordinarily, shell scripts invoked by name are executed in a sub-shell while
666scripts invoked as
667.B ksh
668.I script
669and shell escapes from other programs
670are carried out by a separate shell invocation.
671The
672.B \-x
673flag is used with
674.B alias
675to carry aliases to sub-shells while the
676.B \-fx
677flags of
678.B typeset
679are used to do the same for functions.
680.P
681Each user can create a startup file for aliases and functions or
682any other commands.
683Aliases and functions that are to be available for all shell invocations
684should be put into this file.
685Aliases and functions which should apply to
686scripts, as well as interactive use, should be set with the
687.B \-x
688flag.
689Setting this flag to redefine the semantics of a command
690can have undesired side effects.
691For example,
692.B "alias \-x ls='ls \-l'"
693will cause shell procedures which use the
694.B ls
695command within a pipeline to break.
696By setting and exporting the environment variable,
697.BR ENV ,
698to the name of this file,
699the aliases and functions will be defined each time Ksh-i
700is invoked.
701The value of the
702.B ENV
703variable undergoes parameter substitution prior to its use.
704.P
705Several of the UNIX commands can be aliased to Ksh-i built-ins.
706Some of these are automatically set each time the shell is invoked.
707In addition,
708about twenty frequently used UNIX commands are set as tracked aliases.
709.P
710The location of an alias command can be important
711since aliases are only processed when a command is read.
712A
713.B .
714procedure is read all at once (unlike
715.I profiles
716which are read a command at
717a time) so that any aliases defined there will not effect any commands
718within this script.
719.P
720A name is checked to see if it is a built-in command before checking to see
721if it is a function.  To write a function to replace a built-in command
722you must define a function with a different name and alias the
723built-in name to this function.
724For example to write a
725.B cd
726function which changes the directory and prints out the directory name,
727you can write,
728.B
729.sp
730.nf
731.in .5i
732alias cd=_cd
733function  _cd
734{
735     if      'cd'  "$@"
736     then    echo  $PWD
737     fi
738}
739.fi
740.ta
741.in
742.sp
743.R
744The single quotes around
745.B cd
746within the function prevents alias substitution.
747The
748.B PWD
749variable is described below.
750.P
751The combination of aliases and functions can be used
752to do things that can't be done with either of these
753separately.  For example, the function and aliases
754defined as
755.B
756.sp
757.nf
758.in .5i
759function _from # i=start to finish [ by incr]
760{
761        typeset var=${1%%=*}
762       	integer incr=${5\-1} $1
763       	while   (( $var <= $3 ))
764       	do      _repeat
765       	        let $var=$var+incr
766       	done
767}
768alias repeat='function _repeat {'  from='}; _from'
769.fi
770.ta
771.in
772.sp
773.R
774allow you to write loops such as
775.B
776.sp
777.nf
778.in .5i
779repeat
780        any script command
781from i=1 to 13 by 3
782.fi
783.ta
784.in
785.sp
786.R
787with the expected behavior.
788.H 1 "Input and Output"
789.P
790An extended I/O capability has been added
791to enhance the
792use of the shell as a programming language.
793The Bourne shell has a built-in
794.B read
795for reading lines from file descriptor 0,
796but does not have any internal output mechanism.
797As a result, the
798.B echo(1)
799command has been used to produce output for a shell procedure.
800This is inefficient and also restrictive.
801For example, there is no way to read in a line
802from a terminal and to
803.I echo
804the line exactly as is.
805In the Bourne shell,
806the
807.B read
808built-in cannot be used to read lines that end in
809.BR `\e'  ,
810and the
811.B echo
812command will treat certain sequences as control sequences.
813In addition,
814there is no way to have more than one file open
815at any time for reading.
816.P
817Ksh-i has options on the
818.B read
819command to specify the file
820descriptor for the input.
821The
822.B exec
823built-in can be used to open, close, and duplicate file streams.
824The
825.B \-r
826option allows a
827.B `\e'
828at the end of an input line to be treated as a regular
829character rather than the line continuation character.
830The first argument of the
831.B read
832command can be followed by a
833.B ?
834and a prompt to produce a prompt at the
835terminal before the read.
836If the input is not from a terminal device then
837the prompt is not issued.
838.P
839The Ksh-i built-in,
840.BR print ,
841is used to output characters to the terminal or to a file.
842Again, it is possible to specify the file descriptor number
843as an option to the command.
844Ordinarily, the arguments to this command are processed
845the same as for
846.BR echo(1) .
847However, the
848.B \-r
849flag can be used to output the arguments without any special meaning.
850The
851.B \-n
852flag can be used here to suppress the trailing new-line
853that is ordinarily appended.
854.P
855To improve performance of existing shell programs,
856the
857.B echo
858command is built into Ksh-i.
859For the System V version of Ksh-i, the built-in
860.B echo
861is equivalent
862.ce
863\f3print \-\fR,
864where the
865.B \-
866signifies that there are no more options permitted.
867On the Berkeley UNIX version the value of the
868.B PATH
869variable determines the behavior of the built-in
870.B echo
871command.
872If
873.B echo
874would resolve to
875.B /bin/echo
876with a path search, then
877.B echo
878is equivalent to
879.ce
880\f3print \-R\fR.
881The
882.B \-R
883option allows only the
884.B \-n
885flag to be recognized as the next argument.
886Otherwise,
887.B echo
888behaves like the System V
889.B echo
890command.
891.P
892The shell is frequently used as a programming language for
893interactive dialogues.
894The
895.B select
896statement has been added to the language
897to make it easier to
898present menu selection alternatives to the
899user and evaluate the reply.
900The list of alternatives is numbered and put in columns.
901A user settable prompt,
902.BR PS3 ,
903is issued and if the answer is
904a number corresponding to one of the alternatives,
905the select loop variable is set to this value.
906In any case, the
907.B REPLY
908variable is used to store the user entered reply.
909The shell variables
910.B LINES
911and
912.B COLUMNS
913are used to control the layout of select lists.
914.H 1 "Command Re-entry"
915.P
916An interactive shell saves the
917commands you type at a terminal in a file.
918If the variable
919.B HISTFILE
920is set to the name of a file to which the user
921has write access,
922then the commands are stored in this
923.I history
924file.
925Otherwise the file
926.B $HOME/.sh_history
927is checked for write access and if this fails
928an unnamed file is used to hold the history lines.
929This file may be truncated if this is a top level shell.
930The number of commands accessible to the user, is determined by the value of the
931.B HISTSIZE
932variable at the time the shell is invoked.
933The default value is 128.
934A command may consist of one or more lines since a compound
935command is considered one command.
936If the character
937.B !
938is placed within the
939.I "primary prompt"
940string,
941.BR PS1 ,
942then it is replaced by the command number each time the prompt is given.
943Whenever the history file is named,
944all shells which use this file share access to the same history.
945.P
946A built-in command
947.B fc
948(fix command) is used to list and/or edit
949any of these saved commands.
950The command can always be specified with
951a range of one or more commands.
952The range can be specified by giving the command
953number, relative or absolute, or by giving
954the first character or characters of the command.
955The option
956.B \-l
957is used to specify listing of previous commands.
958When given without specifying the range,
959the last 16
960commands are listed, each
961preceded by the command number.
962.P
963If the listing option is not selected,
964then the range of commands specified,
965or the last command if no range is given,
966is passed to an editor program before
967being re-executed by Ksh-i.
968The editor to be used may be specified
969with the option
970.B \-e
971and following it with the editor name.
972If this option is not specified, the
973value of the shell variable
974.B FCEDIT
975is used as the name of the editor,
976providing that this variable has non-null value.
977If this variable is not set, or is null,
978and the
979.B \-e
980option has not been selected,
981then
982.B /bin/ed
983is used.
984When editing has been complete,
985the edited text automatically becomes
986the input for Ksh-i.
987As this text is read by Ksh-i, it is echoed onto the terminal.
988.P
989An editor name of
990.B \-
991is used to bypass the editing and just re-execute the command.
992In this case only a single command can be specified as the range
993and an optional argument of the form
994\f2old\fP\f3=\fP\f2new\fP
995may be added which requests a simple string substitution
996prior to evaluation.
997A convenient alias,
998.ce
999.B
1000alias r=\(fmfc \-e \-\(fm
1001.R
1002has been pre-defined so that
1003the single key-stroke
1004.B r
1005can be used to re-execute the previous command
1006and the key-stroke sequence,
1007.B
1008r abc=def c
1009.R
1010can be used to re-execute the last command that starts with
1011the letter
1012.B c
1013with the first occurrence of the string
1014.B abc
1015replaced with the string
1016.BR def .
1017Typing
1018.B
1019r c > file
1020.R
1021re-executes the most recent command starting with the letter
1022.BR c ,
1023with standard output redirected to
1024.IR file .
1025.H 1 "In-line editing"
1026.P
1027Lines typed from a terminal frequently need changes made
1028before entering them.
1029With the Bourne shell the only method to fix up commands
1030is by backspacing or killing the whole line.
1031Ksh-i offers options that allow the user to edit parts of the
1032current command line before submitting the command.
1033The in-line edit options make the command line into a single
1034line screen edit window.
1035When the command is longer than the width of the terminal,
1036only a portion of the command is visible.
1037Moving within the line automatically makes that portion visible.
1038Editing can be performed on this window until the
1039.I return
1040key is pressed.
1041The editing modes have commands that access the history file
1042in which previous commands are saved.
1043A user can copy any of the most recent
1044.B HISTSIZE
1045commands from this file into the input edit window.
1046You can locate commands by searching or by position.
1047.P
1048The in-line editing options do not use the
1049.I termcap
1050database.
1051They work on most standard terminals.
1052They only require that the backspace character moves the cursor left
1053and the space character overwrites the current character on the screen
1054and moves the cursor to the right.
1055.P
1056There is a choice of editor options.
1057The
1058.IR emacs ,
1059.IR gmacs ,
1060or
1061.I vi
1062option is selected by turning on the
1063corresponding
1064option of the
1065.B set
1066command.
1067If the value of the
1068.B EDITOR
1069or
1070.B VISUAL
1071ends any of these suffixes
1072the corresponding options is turned on.
1073A large subset of each of each of these editors'
1074features are available within the shell.  Additional
1075functions, such as file name completion, have also been added.
1076.P
1077The code for the
1078.I emacs
1079and
1080.I gmacs
1081editing option was supplied by Mike Veach.
1082In the
1083.I emacs
1084or
1085.I gmacs
1086mode the user positions the cursor to the point
1087needing correction and inserts, deletes, or replaces
1088characters as needed.
1089The only difference between these two modes is the
1090meaning of the command
1091.BR ^T .
1092Control keys and escape sequences are used for cursor
1093positioning and control functions.
1094The available editing functions are listed in the manual page.
1095.P
1096The code for the
1097.I vi
1098editing option was supplied by Pat Sullivan.
1099The
1100.I vi
1101editing mode
1102starts in insert mode and enters control mode when the
1103user types
1104.BR ESC (
1105.BR 033 ).
1106The
1107.I return
1108key, which submits the current command for processing,
1109can be entered from either mode.
1110The cursor can be anywhere on the line.
1111A subset of commonly used
1112.I vi
1113commands are available.
1114The
1115.B k
1116and
1117.B j
1118command that normally move up and down by one
1119.IR line ,
1120move up and down one
1121.I command
1122in the history file,
1123copying the command into the input edit window.
1124For reasons of efficiency,
1125the terminal is kept in canonical mode until an
1126.B ESC
1127is typed.
1128On some terminals,
1129and on earlier versions of the UNIX operating system,
1130this doesn't work correctly.
1131The
1132.B viraw
1133option
1134of the
1135.B set
1136command, which always uses
1137.B raw
1138or
1139.B cbreak
1140mode,
1141must be used in this case.
1142.P
1143Most of the code for the editing options does not rely on the
1144Ksh-i code and be used in a stand-alone mode with most any command
1145to add in-line edit capability.
1146However,
1147all versions of the in-line editors have some features that
1148use some shell specific code.  For example,
1149.B ESC-=
1150in all edit modes prints the names of files that match the current
1151word and
1152.B ESC-*
1153adds the expanded list of matching files to the command line.
1154A trailing
1155.B *
1156is added to the word if it doesn't contain any file pattern matching
1157characters before the expansion.
1158.H 1 "Job Control"
1159.P
1160The job control mechanism
1161is almost identical to the version found in
1162.I Csh
1163of the Berkeley UNIX operating system,
1164version 4.1.
1165The job control feature allows the user to stop and
1166restart programs, and to move programs to and from the
1167foreground and the background.
1168It will only work on systems that provide support for
1169these features.
1170However,
1171even systems without job control have a
1172.B monitor
1173option which when enabled will report the progress
1174of background jobs and enable the user to
1175.B kill
1176jobs by job number or job name.
1177.P
1178An interactive shell associates a
1179.I job
1180with each pipeline typed in from the terminal
1181and assigns them a small integer number
1182called the job number.
1183If the job is run asynchronously,
1184the job number is printed at the terminal.
1185At any given time, only one job owns the terminal,
1186i. e., keyboard signals are only sent to the processes in one job.
1187When Ksh-i creates a foreground job,
1188it gives it ownership of the terminal.
1189If you are running a job and wish to stop
1190it you hit the key
1191.B ^Z
1192(control-Z)
1193which sends a
1194.B STOP
1195signal to all processes in the current job.
1196The shell receives notification that the processes
1197have stopped and takes back control of the terminal.
1198.P
1199There are commands to continue programs in the foreground
1200and background.
1201There are several ways to refer to jobs.
1202The character
1203.B %
1204introduces a job name.
1205You can refer to jobs by name or number as described in the manual page.
1206The built-in command
1207.B bg
1208allows you to continue a job in the background,
1209while the built-in command
1210.B fg
1211allows you to continue a job in the foreground even
1212though you may have started it in the background.
1213.P
1214A job being run in the background will stop if it tries
1215to read from the terminal.
1216It is also possible to stop background jobs that try to write on
1217the terminal by setting the terminal options
1218appropriately.
1219.P
1220There is a built-in command
1221.B jobs
1222that lists the status of all running and stopped jobs.
1223In addition,
1224you are notified of the change of state of any background
1225jobs just before each prompt.
1226When you try to leave the shell while jobs are stopped or running,
1227you will receive a message from Ksh-i.
1228If you ignore this message and try to leave again,
1229all stopped processes will be terminated.
1230.P
1231A built-in version of
1232.B kill
1233makes it possible to use
1234.I job
1235numbers as targets for signals.
1236Signals can be selected by number or name.
1237The name of the signal is the name found in the
1238.I include
1239file
1240.B /usr/include/signal.h
1241with the prefix
1242.B SIG
1243removed.
1244The
1245.B \-l
1246flag of
1247.B kill
1248generates list of valid signal numbers and names.
1249.H 1 Security
1250There are several documented problems associated with the security of
1251shell procedures\*(Rf.
1252.RS
1253F. T. Grampp and R. H. Morris,
1254.I "UNIX Operating System Security,"
1255AT&T Bell Labs Tech. Journal, Vol. 63, No. 8, Part 2, pp.1649-1671, 1984.
1256.RF
1257These security holes occur primarily because a user can manipulate the
1258.I environment
1259to subvert the intent of a
1260.I setuid
1261shell procedure.
1262Frequently, shell procedures are initiated from
1263binary programs, without the author's
1264awareness, by library routines which invoke shells to carry out
1265their tasks.
1266When the binary program is run
1267.I setuid
1268then the shell procedure runs with the permissions afforded to the
1269owner of the binary file.
1270.P
1271In the Bourne shell,
1272the
1273.B IFS
1274parameter is used to split each word into separate command arguments.
1275If a user knows that some
1276.I setuid
1277program will run
1278.B "sh \-c /bin/pwd"
1279(or any other command in
1280.BR /bin )
1281then the user sets and exports
1282.BR IFS=/ .
1283Instead of running
1284.B /bin/pwd
1285the shell will run
1286.B bin
1287with
1288.B pwd
1289as an argument.
1290The user puts his or her own
1291.B bin
1292program into the current directory.
1293This program can
1294create a copy of the shell,
1295make this shell
1296.IR setuid ,
1297and then run the
1298.B /bin/pwd
1299program so that the original program continues to run successfully.
1300This kind of penetration is not possible with
1301.I Ksh-i
1302since the
1303.B IFS
1304parameter only splits arguments that result from command or parameter
1305substitution.
1306.P
1307Some
1308.I setuid
1309programs run programs using
1310.I system()
1311without giving the full path name.
1312If the
1313user sets the
1314.B PATH
1315variable so that the desired command will be found
1316in his or her local bin, then the same technique described above can
1317be employed to compromise the security of the system.
1318To close up this and other security holes,
1319.I Ksh-i
1320goes into a
1321.I protected
1322mode whenever the real and effective user or group id are not the same.
1323In this mode, the
1324.B PATH
1325variable is reset to a default value and the
1326.B .profile
1327and
1328.B ENV
1329files are not processed.
1330Instead, the file
1331.B /etc/suid_profile
1332is read and executed.
1333This gives an administrator control over the
1334environment to set the
1335.B PATH
1336variable or to log setuid shell invocations.
1337Clearly security of the system is compromised if
1338.B /etc
1339or this file is publicly writable.
1340.P
1341In BSD UNIX the operating system looks for the characters
1342.B #!
1343as the first two characters of an executable file.
1344If these characters are found, then the next word on this line is taken
1345as the interpreter to
1346.I exec
1347for this command and the interpreter is
1348.IR exec ed
1349with the name of the script as argument zero and argument one.
1350If the
1351.I setuid
1352or
1353.I setgid
1354bits are on for this file, then the interpreter
1355is run with the effective uid and/or gid set accordingly.
1356This scheme has two major drawbacks.
1357First of all, using the
1358.B #!
1359notation forces an
1360.B exec
1361of the interpreter even when the call is invoked from the interpreter
1362which it must exec.  This is inefficient since
1363the interpreter can handle a failed exec much faster than starting up
1364again.
1365More importantly,
1366.I setuid
1367and
1368.I setgid
1369procedures provide an easy target for intrusion.
1370By linking a
1371.I setuid
1372or
1373.I setgid
1374procedure to a name beginning with a
1375.B \-
1376the interpreter is fooled into thinking that is being invoked with
1377a command line option rather than the name of a file.
1378When the interpreter is the shell, the user gets a privileged
1379interactive shell.
1380There is code in
1381.I Ksh-i
1382to guard against this simple form of intrusion.
1383.P
1384A more reliable way to handle
1385.I setuid
1386and
1387.I setgid
1388procedures is provided with
1389.IR Ksh-i .
1390The technique does not require any changes to the operating system
1391and provides better security.
1392Another advantage to this method is that it also allows scripts which
1393have execute premission but no read permission to run.  Taking away read
1394permission makes scripts more secure.
1395.P
1396The method relies on a setuid
1397.B root
1398program to authenticate the
1399request and exec the shell with the correct mode bits to carry out
1400the task.  This shell is invoked with the requested file already open
1401for reading.  A script which cannot be opened for reading or which
1402has its suid and/or setgid bits turned on causes this setuid
1403.B root
1404program to get execed.
1405For security reasons, this program is given the full
1406pathname
1407.BR /etc/suid_exec .
1408A description of the implementation of the
1409.B suid_exec
1410program can be found in
1411a separate paper\*(Rf.
1412.RS
1413D. G Korn
1414.I "Parlez-vous Kanji?"
1415TM-59554-860602-03, 1986.
1416.RF
1417.H 1 "Miscellaneous"
1418.P
1419Ksh-i has several additional features to enhance functionality and performance.
1420This section lists most of these features.
1421.H 2 "Tilde substitution"
1422The character
1423.B \(ap
1424at the beginning of a word has special meaning to Ksh-i.
1425If the characters after the
1426.B \(ap
1427up to a
1428.B /
1429match a user login name in the
1430.B /etc/passwd
1431file, then the
1432.B \(ap
1433and the name are replaced by
1434that user's login directory.
1435If no match is found, the original word
1436is unchanged.
1437A
1438.B \(ap
1439by itself, or in front of a
1440.BR / ,
1441is replaced by the value of the
1442.B HOME
1443parameter.
1444A
1445.B \(ap
1446followed by a
1447.B +
1448or
1449.B \-
1450is replaced by the value of
1451the parameter
1452.B PWD
1453and
1454.B OLDPWD
1455respectively.
1456Tilde substitution takes place when the script is read,
1457not while it is executed.
1458.H 2 "Built-in I/O Redirection"
1459.P
1460All built-in commands can be redirected.
1461Compound commands which are redirected are not carried out in
1462a separate process.
1463.H 2 "Added options"
1464.P
1465Several options have been added to the shell and
1466all options have names
1467that can be used in place of flags for setting and resetting options.
1468The command
1469.B "set \-o"
1470will list the current option settings.
1471.P
1472The option,
1473.B \-f
1474or
1475.BR noglob ,
1476is used to disable file name generation.
1477.P
1478The option
1479.B ignoreeof
1480can be used to prevent
1481.B ^D
1482from exiting the shell and possibly logging you out.
1483You must type
1484.B exit
1485to log out.
1486.P
1487The
1488.B \-h
1489or
1490.B trackall
1491option will cause all commands whose name is a valid alias
1492name to become a
1493.I tracked
1494alias.
1495This option is automatically turned on for non-interactive shells.
1496.P
1497The job
1498.B monitor
1499option will cause a report to be printed
1500before issuing the next prompt
1501when each background job completes.
1502It is automatically enabled for systems that have
1503job control.
1504.P
1505If the
1506.B bgnice
1507option is set,
1508background jobs are run at a lower priority.
1509.P
1510The option
1511.B markdirs
1512causes a trailing
1513.B /
1514to be appended on every directory name resulting from a pattern match.
1515.P
1516The
1517.B protected
1518or
1519.B \-p
1520options provides additional security by disabling the
1521.B ENV
1522from being executed and by resetting the
1523.B PATH
1524variable to the default value.
1525Whenever a shell is run with the effective uid (gid) not equal to
1526the real uid (gid) then this option is implicitly enabled.
1527Instead of the
1528.B ENV
1529file, the file
1530.B /etc/suid_profile
1531is read so that administrators can have control over setuid scripts.
1532.H 2 "Built-in pwd"
1533The
1534.B pwd
1535command is built-into Ksh-i and therefore much faster.
1536.H 2 "Logical naming"
1537The
1538.B cd
1539command will take you where you expect to go even if you cross
1540symbolic links.  Thus,
1541.B "cd .."
1542will move you up one level closer to the root even if your
1543current directory is a symbolic link.
1544.H 2 "Previous Directory"
1545.P
1546Ksh-i remembers your last directory
1547in the variable
1548.BR OLDPWD .
1549The
1550.B cd
1551built-in can be given with argument
1552.B \-
1553to return to the previous directory
1554and prints the name of the directory.
1555Note that
1556.B "cd \-"
1557done twice returns you to the starting directory,
1558not the second previous directory.
1559A directory
1560.I stack
1561manager has been written as shell
1562.I functions
1563to
1564.I push
1565and
1566.I pop
1567directories from the stack.
1568.H 2 "Additional Variables and Parameters"
1569.P
1570Several new parameters have special meaning to Ksh-i.
1571The variable
1572.B PWD
1573is used to hold the current working directory of the shell.
1574The variable
1575.B OLDPWD
1576is used to hold the previous working directory of the shell.
1577.P
1578The variable
1579.B FCEDIT
1580is used by the
1581.B fc
1582built-in described above.
1583The variables
1584.B VISUAL
1585and
1586.B EDITOR
1587are used for determining the edit modes as described above.
1588.P
1589The variable
1590.B ENV
1591is used to define the startup file for non-login
1592Ksh-i invocations.
1593.P
1594The variables
1595.B HISTSIZE
1596and
1597.B HISTFILE
1598control the size and location of the file containing
1599commands entered at a terminal.
1600.P
1601The parameter
1602.B MAILPATH
1603is a colon (
1604.B :
1605) separated list of file names to be checked for changes
1606periodically. The user is notified
1607before the next prompt.
1608Each of the names in this list can be followed by a
1609.B ?
1610and a prompt to be given when a change has been detected in the file.
1611The prompt will be evaluated for parameter substitution.
1612The parameter
1613.B $_
1614within a mail message will evaluate to the name of the file that
1615has changed.
1616The parameter
1617.B MAILCHECK
1618is used to specify the minimal interval in seconds before
1619new mail is checked for.
1620.P
1621The variable
1622.B RANDOM
1623produces a random number each time it is referenced.
1624Assignment to this variable sets the seed for the
1625random number generator.
1626.P
1627The variable
1628.B SECONDS
1629is incremented every second.
1630In a roundabout way, this variable
1631can be used to generate a time stamp into the
1632.B PS1
1633prompt.
1634The following code explains how you can do this on
1635System V.  On BSD you need another command to initialize
1636the
1637.B SECONDS
1638variable.
1639.B
1640.sp
1641.nf
1642.in .5i
1643# If you . this script then you can use $TIME as part of your PS1 string to get
1644#   the time of day in your prompt
1645typeset \-RZ2  _x1 _x2 _x3
1646let SECONDS=$(date  '+3600*%H+60*%M+%S')
1647_s='(_x1=(SECONDS/3600)%24)==(_x2=(SECONDS/60)%60)==(_x3=SECONDS%60)'
1648TIME='"${_d[_s]}$_x1:$_x2:$_x3"'
1649# PS1=${TIME}whatever
1650.fi
1651.ta
1652.in
1653.sp
1654.R
1655.P
1656The parameter
1657.B PPID
1658is used to generate the process id of the process which invoked this shell.
1659.P
1660The value of the parameter
1661.B _
1662is the last argument of the previous foreground command.
1663Before execing each command this parameter is set to the file
1664name of the command and placed in the environment.
1665.P
1666The parameter
1667.B TMOUT
1668can be set to be the number of seconds that the shell will wait for
1669input before terminating.  A 60 second warning message is printed
1670before terminating.
1671.P
1672The
1673.B COLUMNS
1674variable can be used to adjust the width of the edit window for
1675the in-line edit modes.  It is also used by the
1676.B select
1677command to present menu choices.
1678.P
1679The
1680.B LINES
1681variable controls how many rows a select list will take up on the screen.
1682Select lists will try to occupy no more then two-thirds of
1683.B LINES
1684lines on the screen.
1685.H 2 "Modified variables"
1686.P
1687The input field separator parameter,
1688.BR IFS ,
1689is only used to split words that have undergone parameter or command
1690substitution.
1691In addition, adjacent non-blank delimiters separate
1692null fields in Ksh-i.
1693.P
1694The
1695.B PS1
1696parameter is evaluated for parameter substitution and a
1697.B !
1698is replaced by the current command number.
1699.H 2 "Timing Commands"
1700.P
1701A keyword
1702.B time
1703has been added to replace
1704the
1705.B time
1706command.
1707Any function, command or pipeline can be preceded by this keyword
1708to obtain information about the elapsed, user and system times.
1709Since I/O redirection bind to the command, not to
1710.BR time ,
1711parenthesis should be used to redirect the timing information which
1712is normally printed on file descriptor 2.
1713.H 2 "Co-process"
1714Ksh-i can spawn a
1715.I co-process
1716by adding a
1717.B "|&"
1718after a command.
1719This process will be run with its standard input and its
1720standard output connected to the shell.  The built-in command
1721.B print
1722with the
1723.B \-p
1724option will write into the standard input of this
1725process and
1726the built-in command
1727.B read
1728with the
1729.B \-p
1730option will read from the output of this process.
1731Only one such process can exist at any time.
1732.H 2 "Process Substitution"
1733.P
1734This feature is only available
1735on versions of the UNIX operating system which support the
1736.B /dev/fd
1737directory for naming open files.
1738Each command argument of the form
1739\f3(\fP\f2list\^\fP\f3)\fP,
1740\f3<(\fP\f2list\^\fP\f3)\fP,
1741or
1742\f3>(\fP\f2list\^\fP\f3)\fP
1743will run process
1744.I list
1745asynchronously connected to some file in the
1746.B /dev/fd
1747directory.
1748The name of this file will become the argument to the command.
1749If the form with
1750.B >
1751is selected then writing on this file will provide input for
1752.IR list .
1753If
1754.B <
1755is used or omitted,
1756then the file passed as an argument will contain the output of the
1757.I list
1758process.
1759For example,
1760.B
1761.sp
1762.nf
1763.in .5i
1764paste  (cut \-f1 \f2file1\fP)  (cut \-f3 \f2file2\fP) | tee >(\f2process1\fP)  >(\fP\f2process2\fP)
1765.fi
1766.ta
1767.in
1768.sp
1769.R
1770.I cuts
1771fields 1 and 3 from
1772the files
1773.I file1
1774and
1775.I file2
1776respectively,
1777.I pastes
1778the results together, and
1779sends it
1780to the processes
1781.I process1
1782and
1783.IR process2 ,
1784as well as putting it onto the standard output.
1785Note that the file which is passed as an argument to the command is
1786a UNIX
1787.IR pipe (2)
1788so that the programs that expect to
1789.IR lseek (2)
1790on the file will not work.
1791.H 2 "Command Substitution"
1792.P
1793Command substitution ( \fB\(ga\(ga\fR)
1794in the Bourne shell suffers from some
1795complicated quoting rules.
1796It is hard to write a
1797.B sed
1798pattern which contains back slashes within command substitution.
1799Putting the pattern is single quotes doesn't help much.
1800Ksh-i leaves the Bourne shell command substitution alone and adds
1801a newer and easier to use command substitution syntax.
1802All the characters between a
1803.B $(
1804and a matching
1805.B )
1806are evaluated as a command the output is substituted just as
1807with  \fB\(ga\(ga\fR.
1808The
1809.B $
1810means
1811.I "value of"
1812and the
1813.B ()
1814denotes a command.
1815The command itself can contain quoted strings even if the substitution
1816occurs within double quotes. Nesting is legal.  You can use
1817unbalanced parenthesis within the command providing that they are
1818quoted.
1819.P
1820The special command substitution of the form
1821\fB$(cat file)\fR
1822can be replaced by
1823\fB$(< file)\fR,
1824which is faster because no separate process is created.
1825.H 2 "Whence"
1826.P
1827The addition of
1828.IR aliases ,
1829.IR functions ,
1830and more built-ins
1831has made it substantially more difficult to know what
1832a given command word really means.
1833A built-in command,
1834.B whence
1835when used with the
1836.B \-v
1837option has been provided to answer this question.
1838A line is printed for each argument to
1839.B whence
1840telling what would happen if this argument were used as a command name.
1841It reports on keywords, aliases, built-ins, and
1842functions.
1843If the command is none of the above,
1844it follows the path search rules and prints the full path-name,
1845if any, otherwise it prints an error message.
1846.H 2 "Additional test operators"
1847.P
1848The binary operators
1849.B \-ot
1850and
1851.B \-nt
1852can be used to compare the modification times
1853of two files to see which is file is
1854.I "older than"
1855or
1856.I "newer than"
1857the other.
1858The binary operator
1859.B \-ef
1860is used to see if two files
1861have the same device and i-node number,
1862i.\ e., a link to the same file.
1863.P
1864The unary operator
1865.B \-L
1866returns true for a symbolic link.
1867.H 2 "Added Trap"
1868All traps can be given by name in Ksh-i.  The names of traps
1869corresponding to signals are the same as the signal name with
1870the
1871.B SIG
1872prefix removed.
1873The trap
1874.B 0
1875is named
1876.B EXIT
1877and a new trap named
1878.B ERR
1879has been added.
1880This trap is invoked whenever the shell would exit if the
1881.B \-e
1882flag were set.
1883This trap is used by
1884Fourth Generation Make\*(Rf
1885.RS
1886G. S. Fowler,
1887"The Fourth Generation Make,"
1888Proceedings of the Portland USENIX meeting, pp. 159-174, 1985.
1889.RF
1890which runs Ksh-i
1891as a co-process.
1892.H 2 "Shell Accounting"
1893.P
1894There is a compile time option to the shell to generate
1895an accounting message for each shell script.
1896The changes needed to provide this feature were supplied
1897by Foregger\*(Rf
1898.RS
1899T. H. Foregger,
1900.I "Shell Accounting,"
1901Case 40094-21, July 1982.
1902.RF
1903and have been adopted as described in his memo.
1904.H 2 "Coded in Standard C"
1905.P
1906Early versions of Bourne shell were coded in an ALGOL-68 like dialect of C.
1907Ksh-i is coded in standard C.
1908It tries to adapt itself to the environment when it is compiled
1909taking advantages of the features of the host environment when possible.
1910There are far fewer
1911.I lint
1912messages from Ksh-i then for the Bourne shell.
1913Ksh-i does not catch the segmentation violation signal, SIGSEGV,
1914so that it can run on machines that can't recover from these traps.
1915.H 2 Internationization
1916Ksh-i treats eight bit characters transparently without stripping off the
1917leading bit.
1918There is also a compile time switch to enable handling multi-byte
1919and multi-width characters sets.
1920.H 2 "No special meaning for ^"
1921The Bourne shell uses
1922.B ^
1923as an archaic synonym for
1924.B | .
1925The
1926.B ^
1927is not a special character to Ksh-i.
1928.H 2 "Added conveniences"
1929You can refer to multi-digit positional parameters in Ksh-i by putting
1930the number in braces.  Thus,
1931.B ${12}
1932is legal in Ksh-i but illegal in the Bourne shell.
1933.P
1934Ksh-i will perform file name expansion of file name arguments if the
1935expansion is unique.  Thus,
1936.B "cat < file*"
1937will expand the file name if the expansion is unique.
1938.P
1939If you invoke the shell as
1940.B "ksh script"
1941then Ksh-i will do a path search on script.
1942.P
1943Unbalanced quotes will cause the shell to print an
1944error message giving the type of quote and the line number
1945on which the opening quote occurs.
1946.P
1947Run time error messages detected by the shell will print the
1948line number within a function or script where the error was
1949detected.
1950.H 1 "Example"
1951.P
1952An example of a Ksh-i script is included
1953in the Appendix.
1954This one page program is a variant of the UNIX
1955.I grep(1)
1956program.
1957Pattern matching for this version of
1958.I grep
1959means shell patterns consisting of
1960.BR ? ,
1961.BR * ,
1962and
1963.BR [] .
1964.P
1965The first half examines option flags.
1966Note that all options except
1967.B \-b
1968have been implemented.
1969The second half goes through each line of each file
1970to look for a pattern match.
1971.P
1972This program is not intended to serve as a
1973replacement for
1974.BR grep ;
1975just as an illustration of the programming power of Ksh-i.
1976Note that no auxiliary processes are spawned by this script.
1977It was written and debugged in under two hours.
1978While performance is acceptable for small programs,
1979this program runs at only one tenth
1980the speed of
1981.B grep
1982for large files.
1983.H 1 "Performance"
1984.P
1985Ksh-i executes many scripts faster than the System V Bourne shell.
1986One major reason is that many of the functions provided by
1987.I echo(1)
1988and
1989.I expr(1)
1990are built-in.
1991The time to execute a built-in function is one or two
1992orders of magnitude faster than performing a fork and
1993execute of the shell.
1994Command substitution of built-ins is performed without
1995creating another process, and often without even
1996creating a temporary file.
1997.P
1998Another reason for improved performance is that all I/O is buffered.
1999Output buffers are flushed only when required.
2000Several of the internal algorithms have been changed
2001so that the number of subroutine calls has been
2002substantially reduced.
2003Ksh-i uses hash tables for variables.
2004Scripts that rely heavily on referencing variables execute faster.
2005More processing is performed while reading the script
2006so that execution time is saved while running loops.
2007.P
2008Scripts that do little internal processing and create many processes
2009may run a little slower on System V because the time to
2010.I fork
2011Ksh-i is slightly slower than for the Bourne shell.
2012On BSD Unix, Ksh-i can be compiled with a
2013.B VFORK
2014option which uses
2015.I vfork
2016whenever possible.
2017In this case, binary programs startup somewhat faster but shell
2018script files start a little slower since a separate invocation
2019of the Ksh-i in required.
2020.P
2021The
2022.B ENV
2023file can have an undiserable effect on performance.
2024Even if this file is small, the shell must perform an open of this
2025file.  If large functions are placed in
2026the
2027.B ENV
2028file they must be read in and compiled even if they are never referenced.
2029If you only need the startup file for interactive shells only, then set your
2030.B ENV
2031variable to a
2032value which evaluates to a file name for interactive shells and to
2033the null string otherwise.  If you export the startup file name
2034in the variable
2035.BR START ,
2036then setting
2037.B
2038.sp
2039.nf
2040.in .5i
2041ENV='${START[(_$\-=1)+(_=0)\-(_$\-!=_${\-%%*i*})]}'
2042.fi
2043.ta
2044.in
2045.sp
2046.R
2047will only invoke the startup file for interactive shells
2048since the subscript evaluates to 0
2049only if the shell is interactive.
2050.P
2051If you need a startup
2052.B ENV
2053file for all shells
2054then use a
2055.I case
2056statement on the
2057.B $\-
2058parameter to distinguish which actions only apply to interactive shells.
2059The
2060.B ENV
2061file should look like
2062.B
2063.sp
2064.nf
2065.in .5i
2066# options aliases and functions for all shell invocations
2067case    $\- in
2068*i*)
2069        # options aliases and functions for interactive only
2070        ;;
2071esac
2072.fi
2073.ta
2074.in
2075.sp
2076.R
2077.P
2078If there are functions which are only occasionally referenced, put them
2079into a separate file
2080.B $HOME/functions
2081or any name you prefer
2082and put aliases in the
2083.B ENV
2084file for each function name of the form
2085.B
2086.sp
2087.nf
2088.in .5i
2089alias \f2function_name\fP='. $HOME/functions;\f2function_name\fP'
2090.fi
2091.ta
2092.in
2093.sp
2094.R
2095In the beginning of the
2096.B $HOME/functions
2097file you must unalias each of the function names defined in the
2098file.
2099The first reference to any
2100.I function_name
2101in the function file
2102causes the function file to get read in and the functions compiled.
2103.H 1  "Conclusion"
2104.P
2105Ksh-i has several thousand regular users.
2106Ksh-i is a suitable replacement for the Bourne shell.
2107It offers new features,
2108better performance,
2109and is essentially upward compatible with the Bourne shell.
2110.SG dgk \"  signature typist initials
2111.NS 0 \" start notation
2112Members of Center 5954
2113Laboratory 4542 Supervision
2114J. W. Gross
2115N. J. Kolettis
2116J. L. Steffen
2117P. D. Sullivan
2118M. T. Veach
2119.NE  \" end notation
2120.CS 14 24 38 0 0 16  \" cover sheet for TM
2121.bp
2122.ce
2123APPENDIX
2124.nf
2125	#
2126	#	SHELL VERSION OF GREP
2127	#
2128	vflag= xflag= cflag= lflag= nflag=
2129	set \-f
2130	while	((1))			# look for grep options
2131	do	case	"$1" in
2132		\-v*)	vflag=1;;
2133		\-x*)	xflag=1;;
2134		\-c*)	cflag=1;;
2135		\-l*)	lflag=1;;
2136		\-n*)	nflag=1;;
2137		\-b*)	print \(fmb option not supported\(fm;;
2138		\-e*)	shift;expr="$1";;
2139		\-f*)	shift;expr=$( < $1 );;
2140		\-*)	print $0: \(fmunknown flag\(fm;exit 2;;
2141		*)	if	test "$expr" = \(fm\|\(fm
2142			then	expr="$1";shift
2143			fi
2144			test "$xflag" |\|| expr="*${expr}*"
2145			break;;
2146		esac
2147		shift			# next argument
2148	done
2149	noprint=$vflag$cflag$lflag	# don't print if these flags set
2150	integer n=0 c=0 tc=0 nargs=$#	# initialize counters
2151	for i in "$@"			# go through the files
2152	do	if	((nargs<=1))
2153		then	fname=\(fm\|\(fm
2154		else	fname="$i":
2155		fi
2156		test "$i"  &&  exec 0< $i	# open file if necessary
2157		while	read \-r line		# read in a line
2158		do	let n=n+1
2159			case	"$line" in
2160			$expr)			# line matches pattern
2161				if	test "$noprint" = ""
2162				then	print \-r "$fname${nflag:+$n:}$line"
2163				fi
2164				let c=c+1 ;;
2165			*)			# not a match
2166				if	test "$vflag"
2167				then	print \-r "$fname${nflag:+$n:}$line"
2168				fi;;
2169			esac
2170		done
2171		if	test "$lflag" && ((c))
2172		then	print \- $i
2173		fi
2174		let tc=tc+c n=0 c=0
2175	done
2176	test "$cflag" && print $tc	#  print count if cflag is set
2177	let tc				#  set the exit value
2178.fi
2179