xref: /titanic_53/usr/src/contrib/ast/src/cmd/ksh93/sh.memo (revision 906afcb89d0412cc073b95c2d701a804a8cdb62c)
1*906afcb8SAndy Fiddaman.	 \" use troff -mm
2*906afcb8SAndy Fiddaman.nr C 3
3*906afcb8SAndy Fiddaman.nr N 2
4*906afcb8SAndy Fiddaman.SA 1  \"  right justified
5*906afcb8SAndy Fiddaman.ND "December 21, 1993"
6*906afcb8SAndy Fiddaman.TL "311466-6713" "61175"  \" charging case filing case
7*906afcb8SAndy FiddamanIntroduction to \f5ksh-93\fP
8*906afcb8SAndy Fiddaman.AU "David G. Korn" DGK MH 11267 7975 3C-526B "(research!dgk)"
9*906afcb8SAndy Fiddaman.TM  11267-931221-26  \"  technical memo + TM numbers
10*906afcb8SAndy Fiddaman.MT 1  \"  memo type
11*906afcb8SAndy Fiddaman.OK Shell "Command interpreter" Language UNIX  \" keyword
12*906afcb8SAndy Fiddaman.AS 2   \" abstract start for TM
13*906afcb8SAndy Fiddaman\f5ksh-93\fP is a
14*906afcb8SAndy Fiddamanmajor rewrite of \f5ksh\fP,
15*906afcb8SAndy Fiddamana program that serves as a command language
16*906afcb8SAndy Fiddaman(shell) for the UNIX*
17*906afcb8SAndy Fiddaman.FS  *
18*906afcb8SAndy FiddamanUNIX is a registered trademark of Novell.
19*906afcb8SAndy Fiddaman.FE
20*906afcb8SAndy Fiddamanoperating system.
21*906afcb8SAndy FiddamanAs with \f5ksh\fP, \f5ksh-93\fP
22*906afcb8SAndy Fiddamanis essentially compatible with the System V version of the Bourne shell\*(Rf,
23*906afcb8SAndy Fiddaman.RS
24*906afcb8SAndy FiddamanS. R. Bourne,
25*906afcb8SAndy Fiddaman.I "An Introduction to the UNIX
26*906afcb8SAndy FiddamanShell,"
27*906afcb8SAndy FiddamanBSTJ - Vol. 57, No. 6 part 2, pages 1947-1972, 1978.
28*906afcb8SAndy Fiddaman.RF
29*906afcb8SAndy Fiddamanand compatible with previous versions of \f5ksh\fP.
30*906afcb8SAndy Fiddaman\f5ksh-93\fP is intended to comply with the IEEE POSIX 1003.2
31*906afcb8SAndy Fiddamanand ISO 9945-2\*(Rf
32*906afcb8SAndy Fiddaman.RS
33*906afcb8SAndy Fiddaman.I "POSIX \- Part 2: Shell and Utilities,"
34*906afcb8SAndy FiddamanIEEE Std 1003.2-1992, ISO/IEC 9945-2, IEEE, 1993.
35*906afcb8SAndy Fiddaman.RF
36*906afcb8SAndy Fiddamanshell standard.
37*906afcb8SAndy FiddamanIn addition to changes in the language required
38*906afcb8SAndy Fiddamanby these standards, the primary focus of \f5ksh-93\fP
39*906afcb8SAndy Fiddamanis related to shell programming.
40*906afcb8SAndy Fiddaman\f5ksh-93\fP provides the programming power of several
41*906afcb8SAndy Fiddamanother interpretive languages such as \f5awk\fP\*(Rf,
42*906afcb8SAndy Fiddaman.RS
43*906afcb8SAndy FiddamanAl Aho,
44*906afcb8SAndy FiddamanBrian Kernighan,
45*906afcb8SAndy Fiddamanand
46*906afcb8SAndy FiddamanPeter Weinberger,
47*906afcb8SAndy Fiddaman.I "The AWK Programming Language,"
48*906afcb8SAndy FiddamanAddison Wesley, 1988.
49*906afcb8SAndy Fiddaman.RF
50*906afcb8SAndy Fiddaman\f5FIT\fP\*(Rf,
51*906afcb8SAndy Fiddaman.RS
52*906afcb8SAndy FiddamanLloyd H. Nakatani and Laurence W. Ruedisueli,
53*906afcb8SAndy Fiddaman.I "The FIT Programming Language Primer",
54*906afcb8SAndy FiddamanTM 1126-920301-03, 1992.
55*906afcb8SAndy Fiddaman.RF
56*906afcb8SAndy Fiddaman\f5PERL\fP\*(Rf,
57*906afcb8SAndy Fiddaman.RS
58*906afcb8SAndy FiddamanLarry Wall and Randal Schwartz,
59*906afcb8SAndy Fiddaman.I "Programming perl,"
60*906afcb8SAndy FiddamanO'Reilly & Assoc, 1990.
61*906afcb8SAndy Fiddaman.RF
62*906afcb8SAndy Fiddamanand
63*906afcb8SAndy Fiddaman\f5tcl\fP\*(Rf.
64*906afcb8SAndy Fiddaman.RS
65*906afcb8SAndy FiddamanJohn K. Ousterhout,
66*906afcb8SAndy Fiddaman.I "Tcl: An Embeddable Command Language",
67*906afcb8SAndy FiddamanProceedings of the Washington USENIX meeting, pp. 133-146, 1990.
68*906afcb8SAndy Fiddaman.RF
69*906afcb8SAndy Fiddaman.P
70*906afcb8SAndy FiddamanThis memo
71*906afcb8SAndy Fiddamanassumes that the reader is already familiar with the Bourne shell.
72*906afcb8SAndy FiddamanIt introduces most of the features of \f5ksh-93\fP
73*906afcb8SAndy Fiddamanrelative to the Bourne shell; both
74*906afcb8SAndy Fiddamanas a command language and as a programming language.
75*906afcb8SAndy FiddamanThe Appendix contains
76*906afcb8SAndy Fiddamana sample script written in \f5ksh-93\fP.
77*906afcb8SAndy Fiddaman.AE   \" abstract end
78*906afcb8SAndy Fiddaman.H 1 "INTRODUCTION"
79*906afcb8SAndy Fiddaman.P
80*906afcb8SAndy FiddamanThe term "shell" is used to describe a program that provides
81*906afcb8SAndy Fiddamana command language
82*906afcb8SAndy Fiddamaninterface.
83*906afcb8SAndy FiddamanBecause the UNIX*\
84*906afcb8SAndy Fiddaman.FS *
85*906afcb8SAndy FiddamanUNIX is a registered trademark of USL
86*906afcb8SAndy Fiddaman.FE
87*906afcb8SAndy Fiddamansystem shell is a user level program, and not part of
88*906afcb8SAndy Fiddamanthe operating system itself,
89*906afcb8SAndy Fiddamananyone can write a new shell or modify an existing one.
90*906afcb8SAndy FiddamanThis has caused an evolutionary progress
91*906afcb8SAndy Fiddamanin the design and implementation of shells,
92*906afcb8SAndy Fiddamanwith the better ones surviving.
93*906afcb8SAndy FiddamanThe most widely available UNIX system shells are the Bourne shell\*(Rf,
94*906afcb8SAndy Fiddaman.RS
95*906afcb8SAndy FiddamanS. R. Bourne,
96*906afcb8SAndy Fiddaman.IR "An Introduction to the UNIX Shell" ,
97*906afcb8SAndy FiddamanBell System Technical Journal,
98*906afcb8SAndy FiddamanVol. 57, No. 6, Part 2, pp. 1947-1972, July 1978.
99*906afcb8SAndy Fiddaman.RF
100*906afcb8SAndy Fiddamanwritten by Steve Bourne
101*906afcb8SAndy Fiddamanat AT&T Bell Laboratories,
102*906afcb8SAndy Fiddamanthe C shell\*(Rf,
103*906afcb8SAndy Fiddaman.RS
104*906afcb8SAndy FiddamanW. Joy,
105*906afcb8SAndy Fiddaman.IR "An Introduction to the C Shell" ,
106*906afcb8SAndy FiddamanUnix Programmer's Manual, Berkeley Software Distribution,
107*906afcb8SAndy FiddamanUniversity of California, Berkeley, 1980.
108*906afcb8SAndy Fiddaman.RF
109*906afcb8SAndy Fiddamanwritten by Bill Joy at the University of California, Berkeley,
110*906afcb8SAndy Fiddamanand the KornShell language \*(Rf,
111*906afcb8SAndy Fiddaman.RS
112*906afcb8SAndy FiddamanMorris Bolsky and David Korn,
113*906afcb8SAndy Fiddaman.IR "The KornShell Command and Programming Language" ,
114*906afcb8SAndy FiddamanPrentice Hall, 1989.
115*906afcb8SAndy Fiddaman.RF
116*906afcb8SAndy Fiddamanwritten by David Korn
117*906afcb8SAndy Fiddamanat AT&T Bell Laboratories.
118*906afcb8SAndy FiddamanThe Bourne shell is available on almost all versions of the UNIX
119*906afcb8SAndy Fiddamansystem.
120*906afcb8SAndy FiddamanThe C Shell is available with all Berkeley Software Distribution (BSD) UNIX systems and on many other systems.
121*906afcb8SAndy FiddamanThe KornShell
122*906afcb8SAndy Fiddamanis available on System V Release 4 systems.
123*906afcb8SAndy FiddamanIn addition, it is available on many other systems.
124*906afcb8SAndy FiddamanThe source for the KornShell language is available from the AT&T Toolchest,
125*906afcb8SAndy Fiddamanan electronic software distribution system.
126*906afcb8SAndy FiddamanIt runs on all known versions of the UNIX system and
127*906afcb8SAndy Fiddamanon many UNIX system look-alikes.
128*906afcb8SAndy Fiddaman.P
129*906afcb8SAndy FiddamanThere have been several articles comparing the UNIX system shells.
130*906afcb8SAndy FiddamanJason Levitt\*(Rf
131*906afcb8SAndy Fiddaman.RS
132*906afcb8SAndy FiddamanJason Levitt,
133*906afcb8SAndy Fiddaman.IR "The Korn Shell: An Emerging Standard" ,
134*906afcb8SAndy FiddamanUNIX/World, pp. 74-81, September 1986.
135*906afcb8SAndy Fiddaman.RF
136*906afcb8SAndy Fiddamanhighlights some of the new features
137*906afcb8SAndy Fiddamanintroduced by the KornShell language.
138*906afcb8SAndy FiddamanRich Bilancia\*(Rf
139*906afcb8SAndy Fiddaman.RS
140*906afcb8SAndy FiddamanRich Bilancia,
141*906afcb8SAndy Fiddaman.IR "Proficiency and Power are Yours With the Korn Shell" ,
142*906afcb8SAndy FiddamanUNIX/World, pp. 103-107, September 1987.
143*906afcb8SAndy Fiddaman.RF
144*906afcb8SAndy Fiddamanexplains some of the advantages of using the KornShell language.
145*906afcb8SAndy FiddamanJohn Sebes\*(Rf
146*906afcb8SAndy Fiddaman.RS
147*906afcb8SAndy FiddamanJohn Sebes,
148*906afcb8SAndy Fiddaman.I "Comparing UNIX Shells,"
149*906afcb8SAndy FiddamanUNIX Papers,
150*906afcb8SAndy FiddamanEdited by the Waite Group, Howard W. Sams & Co., 1987.
151*906afcb8SAndy Fiddaman.RF
152*906afcb8SAndy Fiddamanprovides a more detailed comparison of the three shells,
153*906afcb8SAndy Fiddamanboth as a command language and as a programming language.
154*906afcb8SAndy Fiddaman.P
155*906afcb8SAndy FiddamanThe KornShell language is a superset of the
156*906afcb8SAndy FiddamanBourne shell. The KornShell language has many of the popular C shell features,
157*906afcb8SAndy Fiddamanplus additional features of its own.
158*906afcb8SAndy FiddamanIts initial popularity stems primarily from its improvements as
159*906afcb8SAndy Fiddamana command language.
160*906afcb8SAndy FiddamanThe primary interactive benefit of the KornShell command language
161*906afcb8SAndy Fiddamanis a visual command line editor that allows you to
162*906afcb8SAndy Fiddamanmake corrections to your current command line
163*906afcb8SAndy Fiddamanor to earlier command lines,
164*906afcb8SAndy Fiddamanwithout having to retype them.
165*906afcb8SAndy Fiddaman.P
166*906afcb8SAndy FiddamanHowever,
167*906afcb8SAndy Fiddamanin the long run,
168*906afcb8SAndy Fiddamanthe power of the KornShell language as a high-level programming language,
169*906afcb8SAndy Fiddamanas described by Dolotta and Mashey\*(Rf,
170*906afcb8SAndy Fiddaman.RS
171*906afcb8SAndy FiddamanT. A. Dolotta and J. R. Mashey,
172*906afcb8SAndy Fiddaman.I "Using the shell as a Primary Programming Tool,"
173*906afcb8SAndy FiddamanProc. 2nd. Int. Conf. on Software Engineering, 1976,
174*906afcb8SAndy Fiddamanpages 169-176.
175*906afcb8SAndy Fiddaman.RF
176*906afcb8SAndy Fiddamanmay prove to be of greater significance.
177*906afcb8SAndy Fiddaman\f5ksh-93\fP provides the programming power of several
178*906afcb8SAndy Fiddamanother interpretive languages such as \f5awk\fP,
179*906afcb8SAndy Fiddaman\f5FIT\fP,
180*906afcb8SAndy Fiddaman\f5PERL\fP,
181*906afcb8SAndy Fiddamanand
182*906afcb8SAndy Fiddaman\f5tcl\fP.
183*906afcb8SAndy FiddamanAn application that was originally written in the C programming language
184*906afcb8SAndy Fiddamanwas rewritten in the KornShell language.
185*906afcb8SAndy FiddamanMore than 20,000 lines of C code were replaced with KornShell scripts
186*906afcb8SAndy Fiddamantotaling fewer than 700 lines.
187*906afcb8SAndy FiddamanIn most instances there was no perceptible difference in performance
188*906afcb8SAndy Fiddamanbetween the two versions of the code.
189*906afcb8SAndy Fiddaman.P
190*906afcb8SAndy FiddamanThe KornShell language has been embedded into windowing systems
191*906afcb8SAndy Fiddamanallowing graphical user interfaces to be developed in shell
192*906afcb8SAndy Fiddamanrather than having to build applications that need to be
193*906afcb8SAndy Fiddamancompiled.
194*906afcb8SAndy FiddamanThe \f5wksh\fP program\*(Rf
195*906afcb8SAndy Fiddaman.RS
196*906afcb8SAndy FiddamanJ. S. Pendergrast,
197*906afcb8SAndy Fiddaman.IR "WKSH - Korn Shell with X-Windows Support",
198*906afcb8SAndy FiddamanUSL. 1991.
199*906afcb8SAndy Fiddaman.RF
200*906afcb8SAndy Fiddamanprovides a method of developing OpenLook or Motif
201*906afcb8SAndy Fiddamanapplications as \f5ksh\fP scripts.
202*906afcb8SAndy Fiddaman.P
203*906afcb8SAndy FiddamanThis memo is an introduction to \f5ksh-93\fP,
204*906afcb8SAndy Fiddamanthe program that implements an enhanced version
205*906afcb8SAndy Fiddamanof the KornShell language.
206*906afcb8SAndy FiddamanIt is referred to as \f5ksh\fP in the rest of this memo.
207*906afcb8SAndy FiddamanThe memo describes the KornShell language based on the
208*906afcb8SAndy Fiddamanfeatures of the 12/28/93 release of \f5ksh\fP.
209*906afcb8SAndy FiddamanThis memo is not a tutorial, only an introduction.
210*906afcb8SAndy FiddamanThe second edition of reference [9] gives
211*906afcb8SAndy Fiddamana more complete treatment of the KornShell language.
212*906afcb8SAndy Fiddaman.P
213*906afcb8SAndy FiddamanA concerted effort has been made to achieve both System V Bourne shell
214*906afcb8SAndy Fiddamancompatibility and IEEE POSIX compatibility
215*906afcb8SAndy Fiddamanso that scripts written for either of these shells
216*906afcb8SAndy Fiddamancan run without modification with \f5ksh\fP.
217*906afcb8SAndy FiddamanIn addition, \f5ksh-93\fP attempts to
218*906afcb8SAndy Fiddamanbe compatible with older versions of \f5ksh\fP.
219*906afcb8SAndy FiddamanWhen there are conflicts between versions of the shell,
220*906afcb8SAndy Fiddaman\f5ksh-93\fP selects the behavior dictated by the IEEE POSIX
221*906afcb8SAndy Fiddamanstandard.
222*906afcb8SAndy FiddamanThe description of features in this memo assumes
223*906afcb8SAndy Fiddamanthat the reader is already familiar with the Bourne shell.
224*906afcb8SAndy Fiddaman.H 1 "COMMAND LANGUAGE"
225*906afcb8SAndy FiddamanThere is no separate command language.
226*906afcb8SAndy FiddamanAll features of the language, except job control,
227*906afcb8SAndy Fiddamancan be
228*906afcb8SAndy Fiddamanused both within a script and interactively from a terminal.
229*906afcb8SAndy FiddamanHowever, features that are more likely to be used
230*906afcb8SAndy Fiddamanwhile running commands interactively from a terminal
231*906afcb8SAndy Fiddamanare presented here.
232*906afcb8SAndy Fiddaman.H 2 "Setting Options"
233*906afcb8SAndy FiddamanBy convention, UNIX commands
234*906afcb8SAndy Fiddamanconsist of a command name followed by options and other arguments.
235*906afcb8SAndy FiddamanOptions are either of the form \f5-\fP\fIletter\fP,
236*906afcb8SAndy Fiddamanor \f5-\fP\fIletter value\fP.
237*906afcb8SAndy FiddamanIn the former case, several options may be grouped after a single \f5-\fP.
238*906afcb8SAndy FiddamanThe argument \f5--\fP signifies an end to the option list and is
239*906afcb8SAndy Fiddamanonly required when the first non-option argument begins with
240*906afcb8SAndy Fiddamana \f5-\fP.
241*906afcb8SAndy FiddamanMost commands print an error message which
242*906afcb8SAndy Fiddamanshows which options are permitted
243*906afcb8SAndy Fiddamanwhen given incorrect arguments.
244*906afcb8SAndy FiddamanIn addition, the option sequence \f5-?\fP causes most commands
245*906afcb8SAndy Fiddamanto print a usage message which lists the valid options.
246*906afcb8SAndy Fiddaman.P
247*906afcb8SAndy FiddamanOrdinarily, \f5ksh\fP executes a command by
248*906afcb8SAndy Fiddamanusing the command name to locate a program to run
249*906afcb8SAndy Fiddamanand by running the program as a separate process.
250*906afcb8SAndy FiddamanSome commands, referred to as
251*906afcb8SAndy Fiddaman.IR built-ins ,
252*906afcb8SAndy Fiddamanare carried out by \f5ksh\fP itself,
253*906afcb8SAndy Fiddamanwithout creating a separate process.
254*906afcb8SAndy FiddamanThe reasons that some commands are built-in are presented later.
255*906afcb8SAndy FiddamanIn nearly all cases the distinction
256*906afcb8SAndy Fiddamanbetween a command that is built-in and one that
257*906afcb8SAndy Fiddamanis not is invisible to the user.
258*906afcb8SAndy FiddamanHowever, nearly
259*906afcb8SAndy Fiddamanall commands that are built-in follow command line conventions.
260*906afcb8SAndy Fiddaman.P
261*906afcb8SAndy Fiddaman\f5ksh\fP has several options that can be set by the user
262*906afcb8SAndy Fiddamanas command line arguments at invocation and as option arguments to the
263*906afcb8SAndy Fiddaman\f5set\fP command.
264*906afcb8SAndy FiddamanMost other options can be set with a single letter option or as a name
265*906afcb8SAndy Fiddamanthat follows the \f5-o\fP option.
266*906afcb8SAndy FiddamanUse
267*906afcb8SAndy Fiddaman\f5set\ -o\fP
268*906afcb8SAndy Fiddamanto display the current option settings.
269*906afcb8SAndy FiddamanSome of these options, such as
270*906afcb8SAndy Fiddaman.B interactive
271*906afcb8SAndy Fiddamanand
272*906afcb8SAndy Fiddaman.B monitor
273*906afcb8SAndy Fiddaman(see
274*906afcb8SAndy Fiddaman.I "Job Control"
275*906afcb8SAndy Fiddamanbelow),
276*906afcb8SAndy Fiddamanare enabled automatically by \f5ksh\fP
277*906afcb8SAndy Fiddamanwhen the shell is connected to a terminal device.
278*906afcb8SAndy FiddamanOther options, such as
279*906afcb8SAndy Fiddaman.B noclobber
280*906afcb8SAndy Fiddamanand
281*906afcb8SAndy Fiddaman.BR ignoreeof ,
282*906afcb8SAndy Fiddamanare normally placed in a startup file.
283*906afcb8SAndy FiddamanThe
284*906afcb8SAndy Fiddaman.B noclobber
285*906afcb8SAndy Fiddamanoption causes
286*906afcb8SAndy Fiddaman\f5ksh\fP
287*906afcb8SAndy Fiddamanto print an error message when you use
288*906afcb8SAndy Fiddaman.B >
289*906afcb8SAndy Fiddamanto redirect output to a file that already exists.
290*906afcb8SAndy FiddamanIf you want to redirect to an existing file, then
291*906afcb8SAndy Fiddamanyou have to use
292*906afcb8SAndy Fiddaman.B >|
293*906afcb8SAndy Fiddamanto override
294*906afcb8SAndy Fiddamanthe
295*906afcb8SAndy Fiddaman.B noclobber
296*906afcb8SAndy Fiddamanoption.
297*906afcb8SAndy FiddamanThe
298*906afcb8SAndy Fiddaman.B ignoreeof
299*906afcb8SAndy Fiddamanoption
300*906afcb8SAndy Fiddamanis used to prevent the
301*906afcb8SAndy Fiddaman.I end-of-file
302*906afcb8SAndy Fiddamancharacter, normally
303*906afcb8SAndy Fiddaman.B ^D
304*906afcb8SAndy Fiddaman(Control- d),
305*906afcb8SAndy Fiddamanfrom exiting the shell and possibly logging you out.
306*906afcb8SAndy FiddamanYou must type \f5exit\fP
307*906afcb8SAndy Fiddamanto log out.
308*906afcb8SAndy FiddamanMost of the options are described in this memo as appropriate.
309*906afcb8SAndy Fiddaman.H 2 "Command Aliases"
310*906afcb8SAndy Fiddaman.P
311*906afcb8SAndy FiddamanCommand aliases provide a mechanism of associating a command name and
312*906afcb8SAndy Fiddamanarguments with a shorter name.
313*906afcb8SAndy FiddamanAliases are defined with the \f5alias\fP
314*906afcb8SAndy Fiddamanbuilt-in.
315*906afcb8SAndy FiddamanThe form of an \f5alias\fP
316*906afcb8SAndy Fiddamancommand definition is:
317*906afcb8SAndy Fiddaman.ce
318*906afcb8SAndy Fiddaman\f5alias\fP \fIname\fP\f5=\fP\fIvalue\fP
319*906afcb8SAndy FiddamanAs with most other shell assignments, no space is allowed before or after
320*906afcb8SAndy Fiddamanthe \f5=\fP.
321*906afcb8SAndy FiddamanThe characters of an alias name cannot be characters that are
322*906afcb8SAndy Fiddamanspecial to the shell.
323*906afcb8SAndy FiddamanThe replacement string,
324*906afcb8SAndy Fiddaman.I value,
325*906afcb8SAndy Fiddamancan contain any valid shell script,
326*906afcb8SAndy Fiddamanincluding meta-characters such as pipe symbols and i/o-redirection
327*906afcb8SAndy Fiddamanprovided that they are quoted.
328*906afcb8SAndy FiddamanUnlike
329*906afcb8SAndy Fiddaman\f5csh\fP,
330*906afcb8SAndy Fiddamanaliases in
331*906afcb8SAndy Fiddaman\f5ksh\fP
332*906afcb8SAndy Fiddamancannot take arguments.
333*906afcb8SAndy FiddamanThe equivalent functionality of aliases with arguments can
334*906afcb8SAndy Fiddamanbe achieved with shell functions, described later.
335*906afcb8SAndy Fiddaman.P
336*906afcb8SAndy FiddamanAs a command is being read,
337*906afcb8SAndy Fiddamanthe command name is checked against a list of
338*906afcb8SAndy Fiddaman.I alias
339*906afcb8SAndy Fiddamannames.
340*906afcb8SAndy FiddamanIf it is found,
341*906afcb8SAndy Fiddamanthe name is replaced by the alias value associated with the
342*906afcb8SAndy Fiddaman.I alias
343*906afcb8SAndy Fiddamanand then rescanned.
344*906afcb8SAndy FiddamanWhen rescanning the value for an alias, alias substitutions
345*906afcb8SAndy Fiddamanare performed except for an alias that is currently being processed.
346*906afcb8SAndy FiddamanThis prevents infinite loops in alias substitutions.
347*906afcb8SAndy FiddamanFor example with the aliases, \f5alias\ l=ls\ 'ls=ls\ -C'\fP,
348*906afcb8SAndy Fiddamanthe command name \f5l\fP becomes \f5ls\fP, which becomes \f5ls\ -C\fP.
349*906afcb8SAndy FiddamanOrdinarily, only the command name word is processed for alias substitution.
350*906afcb8SAndy FiddamanHowever, if the value of an alias ends in a space,
351*906afcb8SAndy Fiddamanthen the word following the alias is also checked for alias substitution.
352*906afcb8SAndy FiddamanThis makes it possible
353*906afcb8SAndy Fiddamanto define an alias whose first argument is the name of a command
354*906afcb8SAndy Fiddamanand have alias substitution performed on this argument,
355*906afcb8SAndy Fiddamanfor example
356*906afcb8SAndy Fiddaman\f5nohup='nohup\ '\fP.
357*906afcb8SAndy Fiddaman.P
358*906afcb8SAndy FiddamanAliases can be used to redefine built-in commands so that
359*906afcb8SAndy Fiddamanthe alias,
360*906afcb8SAndy Fiddaman.ce
361*906afcb8SAndy Fiddaman\f5alias test=./test\fP
362*906afcb8SAndy Fiddamancan be used to look for \f5test\fP
363*906afcb8SAndy Fiddamanin your current working directory rather than
364*906afcb8SAndy Fiddamanusing the built-in \f5test\fP command.
365*906afcb8SAndy FiddamanReserved words such as
366*906afcb8SAndy Fiddaman\f5for\fP and \f5while\fP
367*906afcb8SAndy Fiddamancannot be changed by aliasing.
368*906afcb8SAndy FiddamanThe command \f5alias\fP,
369*906afcb8SAndy Fiddamanwithout arguments, generates
370*906afcb8SAndy Fiddamana list of aliases and corresponding alias values.
371*906afcb8SAndy FiddamanThe \f5unalias\fP command removes the name and text of an alias.
372*906afcb8SAndy Fiddaman.P
373*906afcb8SAndy FiddamanAliases are used to save typing and to improve readability of scripts.
374*906afcb8SAndy FiddamanSeveral aliases are predefined by \f5ksh\fP.
375*906afcb8SAndy FiddamanFor example, the predefined alias
376*906afcb8SAndy Fiddaman.ce
377*906afcb8SAndy Fiddaman\f5alias integer='typeset -i'\fP
378*906afcb8SAndy Fiddamanallows the integer variables \f5i\fP and \f5j\fP
379*906afcb8SAndy Fiddamanto be declared and initialized with the command
380*906afcb8SAndy Fiddaman.ce
381*906afcb8SAndy Fiddaman\f5integer i=0 j=1\fP
382*906afcb8SAndy Fiddaman.P
383*906afcb8SAndy FiddamanWhile aliases can be defined in scripts,
384*906afcb8SAndy Fiddamanit is not recommended.
385*906afcb8SAndy FiddamanThe location of an alias command can be important
386*906afcb8SAndy Fiddamansince aliases are only processed when a command is read.
387*906afcb8SAndy FiddamanA \fB\s+2.\s-2\fP
388*906afcb8SAndy Fiddamanprocedure (the shell equivalent of an include file)
389*906afcb8SAndy Fiddamanis read all at once (unlike
390*906afcb8SAndy Fiddamanstart up files
391*906afcb8SAndy Fiddamanwhich are read a command at
392*906afcb8SAndy Fiddamana time) so that any aliases defined there will not effect any commands
393*906afcb8SAndy Fiddamanwithin this script.
394*906afcb8SAndy FiddamanPredefined aliases do not have this problem.
395*906afcb8SAndy Fiddaman.H 2 "Command Re-entry"
396*906afcb8SAndy Fiddaman.P
397*906afcb8SAndy FiddamanWhen run interactively,
398*906afcb8SAndy Fiddaman\f5ksh\fP saves the
399*906afcb8SAndy Fiddamancommands you type at a terminal in a file.
400*906afcb8SAndy FiddamanIf the variable
401*906afcb8SAndy Fiddaman\fB\s-1HISTFILE\s+1\fP
402*906afcb8SAndy Fiddamanis set to the name of a file to which the user
403*906afcb8SAndy Fiddamanhas write access,
404*906afcb8SAndy Fiddamanthen the commands are stored in this
405*906afcb8SAndy Fiddaman.I history
406*906afcb8SAndy Fiddamanfile.
407*906afcb8SAndy FiddamanOtherwise the file
408*906afcb8SAndy Fiddaman\fB$\s-1HOME\s+1/.sh_history\fP
409*906afcb8SAndy Fiddamanis checked for write access and if this fails
410*906afcb8SAndy Fiddamanan unnamed file is used to hold the history lines.
411*906afcb8SAndy FiddamanCommands are always appended to this file.
412*906afcb8SAndy FiddamanInstances of \f5ksh\fP
413*906afcb8SAndy Fiddamanthat run concurrently and use the same history file
414*906afcb8SAndy Fiddamanname, share access to the history file so that a command
415*906afcb8SAndy Fiddamanentered in one shell will be available for editing in another
416*906afcb8SAndy Fiddamanshell.
417*906afcb8SAndy FiddamanThe file may be truncated when \f5ksh\fP
418*906afcb8SAndy Fiddamandetermines that no other shell is using the history file.
419*906afcb8SAndy FiddamanThe number of commands accessible to the user is determined by the value of the
420*906afcb8SAndy Fiddaman\fB\s-1HISTSIZE\s+1\fP
421*906afcb8SAndy Fiddamanvariable at the time the shell is invoked.
422*906afcb8SAndy FiddamanThe default value is 256.
423*906afcb8SAndy FiddamanEach command may consist of one or more lines since a compound
424*906afcb8SAndy Fiddamancommand is considered one command.
425*906afcb8SAndy FiddamanIf the character
426*906afcb8SAndy Fiddaman.B !
427*906afcb8SAndy Fiddamanis placed within the
428*906afcb8SAndy Fiddaman.I "primary prompt"
429*906afcb8SAndy Fiddamanstring,
430*906afcb8SAndy Fiddaman\fB\s-1PS1\s+1\fP,
431*906afcb8SAndy Fiddamanthen it is replaced by the command number each time the prompt is given.
432*906afcb8SAndy Fiddaman.P
433*906afcb8SAndy FiddamanA built-in command named \f5hist\fP
434*906afcb8SAndy Fiddamanis used to list and/or edit
435*906afcb8SAndy Fiddamanany of these saved commands.
436*906afcb8SAndy FiddamanThe option
437*906afcb8SAndy Fiddaman.B \-l
438*906afcb8SAndy Fiddamanis used to specify listing of previous commands.
439*906afcb8SAndy FiddamanThe command can always be specified with
440*906afcb8SAndy Fiddamana range of one or more commands.
441*906afcb8SAndy FiddamanThe range can be specified by giving the command
442*906afcb8SAndy Fiddamannumber, relative or absolute, or by giving
443*906afcb8SAndy Fiddamanthe first character or characters of the command.
444*906afcb8SAndy FiddamanWhen given without specifying the range,
445*906afcb8SAndy Fiddamanthe last 16
446*906afcb8SAndy Fiddamancommands are listed, each
447*906afcb8SAndy Fiddamanpreceded by the command number.
448*906afcb8SAndy Fiddaman.P
449*906afcb8SAndy FiddamanIf the listing option is not selected,
450*906afcb8SAndy Fiddamanthen the range of commands specified,
451*906afcb8SAndy Fiddamanor the last command if no range is given,
452*906afcb8SAndy Fiddamanis passed to an editor program before
453*906afcb8SAndy Fiddamanbeing re-executed by \f5ksh\fP.
454*906afcb8SAndy FiddamanThe editor to be used may be specified
455*906afcb8SAndy Fiddamanwith the option
456*906afcb8SAndy Fiddaman.B \-e
457*906afcb8SAndy Fiddamanand following it with the editor name.
458*906afcb8SAndy FiddamanIf this option is not specified, the
459*906afcb8SAndy Fiddamanvalue of the shell variable
460*906afcb8SAndy Fiddaman\fB\s-1HISTEDIT\s+1\fP
461*906afcb8SAndy Fiddamanis used as the name of the editor,
462*906afcb8SAndy Fiddamanproviding that this variable has a non-null value.
463*906afcb8SAndy FiddamanIf this variable is not set, or is null,
464*906afcb8SAndy Fiddamanand the
465*906afcb8SAndy Fiddaman.B \-e
466*906afcb8SAndy Fiddamanoption has not been selected,
467*906afcb8SAndy Fiddamanthen
468*906afcb8SAndy Fiddaman\f5/bin/ed\fP
469*906afcb8SAndy Fiddamanis used.
470*906afcb8SAndy FiddamanWhen editing has been complete,
471*906afcb8SAndy Fiddamanthe edited text automatically becomes
472*906afcb8SAndy Fiddamanthe input for \f5ksh\fP.
473*906afcb8SAndy FiddamanAs this text is read by \f5ksh\fP, it is echoed onto the terminal.
474*906afcb8SAndy Fiddaman.P
475*906afcb8SAndy FiddamanThe
476*906afcb8SAndy Fiddaman.B \-s
477*906afcb8SAndy Fiddamanoption causes the editing to be bypassed
478*906afcb8SAndy Fiddamanand just re-executes the command.
479*906afcb8SAndy FiddamanIn this case only a single command can be specified as the range
480*906afcb8SAndy Fiddamanand an optional argument of the form
481*906afcb8SAndy Fiddaman\fIold\fP\fB=\fP\fInew\fP
482*906afcb8SAndy Fiddamanmay be added which requests a simple string substitution
483*906afcb8SAndy Fiddamanprior to evaluation.
484*906afcb8SAndy FiddamanA convenient alias,
485*906afcb8SAndy Fiddaman.ce
486*906afcb8SAndy Fiddaman\f5alias r='hist -s'\fP
487*906afcb8SAndy Fiddamanhas been pre-defined so that
488*906afcb8SAndy Fiddamanthe single key-stroke
489*906afcb8SAndy Fiddaman\f5r\fP
490*906afcb8SAndy Fiddamancan be used to re-execute the previous command
491*906afcb8SAndy Fiddamanand the key-stroke sequence,
492*906afcb8SAndy Fiddaman\f5r\ abc=def\ c\fP
493*906afcb8SAndy Fiddamancan be used to re-execute the last command that starts with
494*906afcb8SAndy Fiddamanthe letter \f5c\fP
495*906afcb8SAndy Fiddamanwith the first occurrence of the string \f5abc\fP
496*906afcb8SAndy Fiddamanreplaced with the string \f5def\fP.
497*906afcb8SAndy FiddamanTyping
498*906afcb8SAndy Fiddaman\f5r\ c\ >\ file\fP
499*906afcb8SAndy Fiddamanre-executes the most recent command starting with the letter \f5c\fP,
500*906afcb8SAndy Fiddamanwith standard output redirected to
501*906afcb8SAndy Fiddaman.IR file .
502*906afcb8SAndy Fiddaman.H 2 "In-line editing"
503*906afcb8SAndy Fiddaman.P
504*906afcb8SAndy FiddamanLines typed from a terminal frequently need changes made
505*906afcb8SAndy Fiddamanbefore entering them.
506*906afcb8SAndy FiddamanWith the Bourne shell the only method to fix up commands
507*906afcb8SAndy Fiddamanis by backspacing or killing the whole line.
508*906afcb8SAndy Fiddaman\f5ksh\fP offers options that allow the user to edit parts of the
509*906afcb8SAndy Fiddamancurrent command line before submitting the command.
510*906afcb8SAndy FiddamanThe in-line edit options make the command line into a single
511*906afcb8SAndy Fiddamanline screen edit window.
512*906afcb8SAndy FiddamanWhen the command is longer than the width of the terminal,
513*906afcb8SAndy Fiddamanonly a portion of the command is visible.
514*906afcb8SAndy FiddamanMoving within the line automatically makes that portion visible.
515*906afcb8SAndy FiddamanEditing can be performed on this window until the
516*906afcb8SAndy Fiddaman.I return
517*906afcb8SAndy Fiddamankey is pressed.
518*906afcb8SAndy FiddamanThe editing modes have editing directives that access the history file
519*906afcb8SAndy Fiddamanin which previous commands are saved.
520*906afcb8SAndy FiddamanA user can copy any of the most recent
521*906afcb8SAndy Fiddaman\fB\s-1HISTSIZE\s+1\fP
522*906afcb8SAndy Fiddamancommands from this file into the input edit window.
523*906afcb8SAndy FiddamanYou can locate commands by searching or by position.
524*906afcb8SAndy Fiddaman.P
525*906afcb8SAndy FiddamanThe in-line editing options do not use the
526*906afcb8SAndy Fiddaman.I termcap
527*906afcb8SAndy Fiddamanor
528*906afcb8SAndy Fiddaman.I terminfo
529*906afcb8SAndy Fiddamandatabases.
530*906afcb8SAndy FiddamanThey work on most standard terminals.
531*906afcb8SAndy FiddamanThey only require that the backspace character moves the cursor left
532*906afcb8SAndy Fiddamanand the space character overwrites the current character on the screen
533*906afcb8SAndy Fiddamanand moves the cursor to the right.
534*906afcb8SAndy FiddamanVery few terminals or terminal emulators do not have
535*906afcb8SAndy Fiddamanthis behavior.
536*906afcb8SAndy Fiddaman.P
537*906afcb8SAndy FiddamanThere is a choice of editor options.
538*906afcb8SAndy FiddamanThe
539*906afcb8SAndy Fiddaman.BR emacs ,
540*906afcb8SAndy Fiddaman.BR gmacs ,
541*906afcb8SAndy Fiddamanor
542*906afcb8SAndy Fiddaman.B vi
543*906afcb8SAndy Fiddamanoption is selected by turning on the
544*906afcb8SAndy Fiddamancorresponding
545*906afcb8SAndy Fiddamanoption of the \f5set\fP
546*906afcb8SAndy Fiddamancommand.
547*906afcb8SAndy FiddamanIf the value of the
548*906afcb8SAndy Fiddaman\fB\s-1EDITOR\s+1\fP
549*906afcb8SAndy Fiddamanor
550*906afcb8SAndy Fiddaman\fB\s-1VISUAL\s+1\fP
551*906afcb8SAndy Fiddamanvariables ends with any of these suffixes
552*906afcb8SAndy Fiddamanthe corresponding option is turned on.
553*906afcb8SAndy FiddamanA large subset of each of these editors'
554*906afcb8SAndy Fiddamanfeatures is available within the shell.  Additional
555*906afcb8SAndy Fiddamanfunctions, such as file name completion, have also been added.
556*906afcb8SAndy Fiddaman.P
557*906afcb8SAndy FiddamanIn the
558*906afcb8SAndy Fiddaman.B emacs
559*906afcb8SAndy Fiddamanor
560*906afcb8SAndy Fiddaman.B gmacs
561*906afcb8SAndy Fiddamanmode the user positions the cursor to the point
562*906afcb8SAndy Fiddamanneeding correction and inserts, deletes, or replaces
563*906afcb8SAndy Fiddamancharacters as needed.
564*906afcb8SAndy FiddamanThe only difference between these two modes is the
565*906afcb8SAndy Fiddamanmeaning of the directive
566*906afcb8SAndy Fiddaman.BR ^T .
567*906afcb8SAndy FiddamanControl keys and escape sequences are used for cursor
568*906afcb8SAndy Fiddamanpositioning and control functions.
569*906afcb8SAndy FiddamanThe available editing functions are listed in the manual page.
570*906afcb8SAndy Fiddaman.P
571*906afcb8SAndy FiddamanThe
572*906afcb8SAndy Fiddaman.B vi
573*906afcb8SAndy Fiddamanediting mode
574*906afcb8SAndy Fiddamanstarts in insert mode and enters control mode when the
575*906afcb8SAndy Fiddamanuser types ESC ( 033 ).
576*906afcb8SAndy FiddamanThe
577*906afcb8SAndy Fiddaman.I return
578*906afcb8SAndy Fiddamankey, which submits the current command for processing,
579*906afcb8SAndy Fiddamancan be entered from either mode.
580*906afcb8SAndy FiddamanThe cursor can be anywhere on the line.
581*906afcb8SAndy FiddamanA subset of commonly used
582*906afcb8SAndy Fiddaman.I vi
583*906afcb8SAndy Fiddamanediting directives are available.
584*906afcb8SAndy FiddamanThe
585*906afcb8SAndy Fiddaman.B k
586*906afcb8SAndy Fiddamanand
587*906afcb8SAndy Fiddaman.B j
588*906afcb8SAndy Fiddamandirectives that normally move up and down by one
589*906afcb8SAndy Fiddaman.IR line ,
590*906afcb8SAndy Fiddamanmove up and down one
591*906afcb8SAndy Fiddaman.I command
592*906afcb8SAndy Fiddamanin the history file,
593*906afcb8SAndy Fiddamancopying the command into the input edit window.
594*906afcb8SAndy FiddamanFor reasons of efficiency,
595*906afcb8SAndy Fiddamanthe terminal is kept in canonical mode until an
596*906afcb8SAndy FiddamanESC
597*906afcb8SAndy Fiddamanis typed.
598*906afcb8SAndy FiddamanOn some terminals,
599*906afcb8SAndy Fiddamanand on earlier versions of the UNIX operating system,
600*906afcb8SAndy Fiddamanthis doesn't work correctly.
601*906afcb8SAndy FiddamanThe
602*906afcb8SAndy Fiddaman.B viraw
603*906afcb8SAndy Fiddamanoption,
604*906afcb8SAndy Fiddamanwhich always uses
605*906afcb8SAndy Fiddaman.I raw
606*906afcb8SAndy Fiddamanor
607*906afcb8SAndy Fiddaman.I cbreak
608*906afcb8SAndy Fiddamanmode,
609*906afcb8SAndy Fiddamanmust be used in this case.
610*906afcb8SAndy Fiddaman.P
611*906afcb8SAndy FiddamanMost of the code for the editing options does not rely on the
612*906afcb8SAndy Fiddaman\f5ksh\fP code and can be used in a stand-alone mode with most any command
613*906afcb8SAndy Fiddamanto add in-line edit capability.
614*906afcb8SAndy FiddamanHowever,
615*906afcb8SAndy Fiddamanall versions of the in-line editors have some features that
616*906afcb8SAndy Fiddamanuse some shell specific code.  For example,
617*906afcb8SAndy Fiddamanwith all edit modes, the
618*906afcb8SAndy FiddamanESC-=
619*906afcb8SAndy Fiddamandirective applied to command words
620*906afcb8SAndy Fiddaman(the first word on the line,
621*906afcb8SAndy Fiddamanor the first word after a
622*906afcb8SAndy Fiddaman.BR ; ,
623*906afcb8SAndy Fiddaman.BR | ,
624*906afcb8SAndy Fiddaman.BR ( ,
625*906afcb8SAndy Fiddamanor
626*906afcb8SAndy Fiddaman.BR & )
627*906afcb8SAndy Fiddamanlists all aliases, functions, or commands
628*906afcb8SAndy Fiddamanthat match the portion of the given current word.
629*906afcb8SAndy FiddamanWhen applied to other words, this directive
630*906afcb8SAndy Fiddamanprints the names of files that match the current
631*906afcb8SAndy Fiddamanword.
632*906afcb8SAndy FiddamanThe ESC\fB-*\fP directive
633*906afcb8SAndy Fiddamanadds the expanded list of matching files to the command line.
634*906afcb8SAndy FiddamanA trailing
635*906afcb8SAndy Fiddaman.B *
636*906afcb8SAndy Fiddamanis added to the word if it doesn't contain any file pattern matching
637*906afcb8SAndy Fiddamancharacters before the expansion.
638*906afcb8SAndy FiddamanIn
639*906afcb8SAndy Fiddaman.B emacs
640*906afcb8SAndy Fiddamanand
641*906afcb8SAndy Fiddaman.B gmacs
642*906afcb8SAndy Fiddamanmode,
643*906afcb8SAndy FiddamanESC-ESC
644*906afcb8SAndy Fiddamanindicates command completion when applied to
645*906afcb8SAndy Fiddamancommand names, otherwise it indicates pathname completion.
646*906afcb8SAndy FiddamanWith command or pathname completion,
647*906afcb8SAndy Fiddamanthe list generated by the
648*906afcb8SAndy FiddamanESC-= directive is examined to find
649*906afcb8SAndy Fiddamanthe longest common prefix.
650*906afcb8SAndy FiddamanWith command completion, only the last component of
651*906afcb8SAndy Fiddamanthe pathname is used to compute the longest command prefix.
652*906afcb8SAndy FiddamanIf the longest common prefix is a complete match,
653*906afcb8SAndy Fiddamanthen the word is replaced by the pathname, and a
654*906afcb8SAndy Fiddaman.B /
655*906afcb8SAndy Fiddamanis appended if
656*906afcb8SAndy Fiddamanpathname is a directory, otherwise a space is added.
657*906afcb8SAndy FiddamanIn
658*906afcb8SAndy Fiddaman.B vi
659*906afcb8SAndy Fiddamanmode,
660*906afcb8SAndy Fiddaman.B \e
661*906afcb8SAndy Fiddamanfrom control mode gives the same behavior.
662*906afcb8SAndy Fiddaman.H 2 "Key Binding"
663*906afcb8SAndy Fiddaman.P
664*906afcb8SAndy FiddamanIt is possible to intercept keys as they are entered and
665*906afcb8SAndy Fiddamanapply new meanings or bindings.
666*906afcb8SAndy FiddamanA trap named
667*906afcb8SAndy Fiddaman\fB\s-1KEYBD\s+1\fP
668*906afcb8SAndy Fiddamanis evaluated each time
669*906afcb8SAndy Fiddaman\f5ksh\fP processes characters entered
670*906afcb8SAndy Fiddamanfrom the keyboard,
671*906afcb8SAndy Fiddamanother than those typed
672*906afcb8SAndy Fiddamanwhile entering a search string or an argument to an
673*906afcb8SAndy Fiddamanedit directive such as
674*906afcb8SAndy Fiddaman.B r
675*906afcb8SAndy Fiddamanin vi-mode.
676*906afcb8SAndy FiddamanThe action associated with this trap can change the value of
677*906afcb8SAndy Fiddamanthe entered key to cause the key to perform a different
678*906afcb8SAndy Fiddamanoperation.
679*906afcb8SAndy Fiddaman.P
680*906afcb8SAndy FiddamanWhen the
681*906afcb8SAndy Fiddaman\fB\s-1KEYBD\s+1\fP
682*906afcb8SAndy Fiddamantrap is entered,
683*906afcb8SAndy Fiddamanthe \fB.sh.edtext\fP
684*906afcb8SAndy Fiddamanvariable contains the contents of the current input line
685*906afcb8SAndy Fiddamanand the \fB.sh.edcol\fP
686*906afcb8SAndy Fiddamanvariable gives the current cursor position within this line.
687*906afcb8SAndy FiddamanThe \fB.sh.edmode\fP
688*906afcb8SAndy Fiddamanvariable contains the
689*906afcb8SAndy Fiddaman.B ESC
690*906afcb8SAndy Fiddamancharacter when the trap is entered from
691*906afcb8SAndy Fiddaman.B vi
692*906afcb8SAndy Fiddamaninsert mode.
693*906afcb8SAndy FiddamanOtherwise, this value is null.
694*906afcb8SAndy FiddamanThe \fB.sh.edchar\fP
695*906afcb8SAndy Fiddamanvariable contains the character or
696*906afcb8SAndy Fiddamanescape sequence that caused the trap.
697*906afcb8SAndy FiddamanA key sequence is either a single character,
698*906afcb8SAndy Fiddaman.B ESC
699*906afcb8SAndy Fiddamanfollowed by a single character,
700*906afcb8SAndy Fiddamanor
701*906afcb8SAndy Fiddaman.B ESC[
702*906afcb8SAndy Fiddamanfollowed by a single character.
703*906afcb8SAndy FiddamanIn the \fBvi\fP edit mode,
704*906afcb8SAndy Fiddamanthe characters after the
705*906afcb8SAndy Fiddaman.B ESC
706*906afcb8SAndy Fiddamanmust be entered within half a second after the
707*906afcb8SAndy Fiddaman.BR ESC .
708*906afcb8SAndy FiddamanThe value of \fB.sh.edchar\fP
709*906afcb8SAndy Fiddamanat the end of the trap will be used as
710*906afcb8SAndy Fiddamanthe input sequence.
711*906afcb8SAndy Fiddaman.P
712*906afcb8SAndy FiddamanUsing the associative array facility of \f5ksh\fP described later,
713*906afcb8SAndy Fiddamanand the function facility of \f5ksh\fP, it is easy to write
714*906afcb8SAndy Fiddamana single trap so that keys can be bound dynamically.  For example,
715*906afcb8SAndy Fiddaman.sp
716*906afcb8SAndy Fiddaman.nf
717*906afcb8SAndy Fiddaman.in .5i
718*906afcb8SAndy Fiddaman.ta 4i
719*906afcb8SAndy Fiddaman\f5typeset -A Keytable
720*906afcb8SAndy Fiddamantrap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD
721*906afcb8SAndy Fiddamanfunction keybind # key action
722*906afcb8SAndy Fiddaman{
723*906afcb8SAndy Fiddaman        typeset key=$(print -f "%q" "$2")
724*906afcb8SAndy Fiddaman        case $# in
725*906afcb8SAndy Fiddaman        2)      Keytable[$1]='.sh.edchar=${.sh.edmode}'"$key"
726*906afcb8SAndy Fiddaman                ;;
727*906afcb8SAndy Fiddaman        1)      unset Keytable[$1]
728*906afcb8SAndy Fiddaman                ;;
729*906afcb8SAndy Fiddaman        *)      print -u2 "Usage: $0 key [action]"
730*906afcb8SAndy Fiddaman                ;;
731*906afcb8SAndy Fiddaman        esac
732*906afcb8SAndy Fiddaman}\fP
733*906afcb8SAndy Fiddaman.ta
734*906afcb8SAndy Fiddaman.in
735*906afcb8SAndy Fiddaman.fi
736*906afcb8SAndy Fiddaman.sp
737*906afcb8SAndy Fiddaman.H 2 "Job Control"
738*906afcb8SAndy Fiddaman.P
739*906afcb8SAndy FiddamanThe job control mechanism
740*906afcb8SAndy Fiddamanis almost identical to the version introduced in \f5csh\fP
741*906afcb8SAndy Fiddamanof the Berkeley UNIX operating system,
742*906afcb8SAndy Fiddamanversion 4.1 and later.
743*906afcb8SAndy FiddamanThe job control feature allows the user to stop and
744*906afcb8SAndy Fiddamanrestart programs, and to move programs to and from the
745*906afcb8SAndy Fiddamanforeground and the background.
746*906afcb8SAndy FiddamanIt will only work on systems that provide support for
747*906afcb8SAndy Fiddamanthese features.
748*906afcb8SAndy FiddamanHowever,
749*906afcb8SAndy Fiddamaneven systems without job control have a
750*906afcb8SAndy Fiddaman.B monitor
751*906afcb8SAndy Fiddamanoption which, when enabled, will report the progress
752*906afcb8SAndy Fiddamanof background jobs and enable the user to \f5kill\fP
753*906afcb8SAndy Fiddamanjobs by job number or job name.
754*906afcb8SAndy Fiddaman.P
755*906afcb8SAndy FiddamanAn interactive shell associates a
756*906afcb8SAndy Fiddaman.I job
757*906afcb8SAndy Fiddamanwith each pipeline typed in from the terminal
758*906afcb8SAndy Fiddamanand assigns it a small integer number
759*906afcb8SAndy Fiddamancalled the job number.
760*906afcb8SAndy FiddamanIf the job is run asynchronously,
761*906afcb8SAndy Fiddamanthe job number is printed at the terminal.
762*906afcb8SAndy FiddamanAt any given time, only one job owns the terminal,
763*906afcb8SAndy Fiddamani.e., keyboard signals are only sent to the processes in one job.
764*906afcb8SAndy FiddamanWhen \f5ksh\fP creates a foreground job,
765*906afcb8SAndy Fiddamanit gives it ownership of the terminal.
766*906afcb8SAndy FiddamanIf you are running a job and wish to stop
767*906afcb8SAndy Fiddamanit you hit the key
768*906afcb8SAndy Fiddaman.B ^Z
769*906afcb8SAndy Fiddaman(control-\fBZ\fP)
770*906afcb8SAndy Fiddamanwhich sends a
771*906afcb8SAndy Fiddaman\fB\s-1STOP\s+1\fP
772*906afcb8SAndy Fiddamansignal to all processes in the current job.
773*906afcb8SAndy FiddamanThe shell receives notification that the processes
774*906afcb8SAndy Fiddamanhave stopped and takes back control of the terminal.
775*906afcb8SAndy Fiddaman.P
776*906afcb8SAndy FiddamanThere are commands to continue programs in the foreground
777*906afcb8SAndy Fiddamanand background.
778*906afcb8SAndy FiddamanThere are several ways to refer to jobs.
779*906afcb8SAndy FiddamanThe character
780*906afcb8SAndy Fiddaman.B %
781*906afcb8SAndy Fiddamanintroduces a job name.
782*906afcb8SAndy FiddamanYou can refer to jobs by name or number as described in the manual page.
783*906afcb8SAndy FiddamanThe built-in command \f5bg\fP
784*906afcb8SAndy Fiddamanallows you to continue a job in the background,
785*906afcb8SAndy Fiddamanwhile the built-in command \f5fg\fP
786*906afcb8SAndy Fiddamanallows you to continue a job in the foreground even
787*906afcb8SAndy Fiddamanthough you may have started it in the background.
788*906afcb8SAndy Fiddaman.P
789*906afcb8SAndy FiddamanA job being run in the background will stop if it tries
790*906afcb8SAndy Fiddamanto read from the terminal.
791*906afcb8SAndy FiddamanIt is also possible to stop background jobs that try to write on
792*906afcb8SAndy Fiddamanthe terminal by setting the terminal options
793*906afcb8SAndy Fiddamanappropriately.
794*906afcb8SAndy Fiddaman.P
795*906afcb8SAndy FiddamanThere is a built-in command \f5jobs\fP
796*906afcb8SAndy Fiddamanthat lists the status of all running and stopped jobs.
797*906afcb8SAndy FiddamanIn addition,
798*906afcb8SAndy Fiddamanyou are informed of the change of state (running or stopped)
799*906afcb8SAndy Fiddamanof any background
800*906afcb8SAndy Fiddamanjobs just before each prompt.
801*906afcb8SAndy FiddamanIf you want to be notified about background job completions
802*906afcb8SAndy Fiddamanas soon as they occur without waiting for a prompt, then use the
803*906afcb8SAndy Fiddaman.B notify
804*906afcb8SAndy Fiddamanoption.
805*906afcb8SAndy FiddamanWhen you try to exit the shell while jobs are stopped or running,
806*906afcb8SAndy Fiddamanyou will receive a message from \f5ksh\fP.
807*906afcb8SAndy FiddamanIf you ignore this message and try to exit again,
808*906afcb8SAndy Fiddamanall stopped processes will be terminated.
809*906afcb8SAndy FiddamanIn addition, for login shells, the
810*906afcb8SAndy Fiddaman\fB\s-1HUP\s+1\fP
811*906afcb8SAndy Fiddamansignal will be sent to
812*906afcb8SAndy Fiddamanall background jobs
813*906afcb8SAndy Fiddamanunless the job has been disowned with the
814*906afcb8SAndy Fiddaman.B disown
815*906afcb8SAndy Fiddamancommand.
816*906afcb8SAndy Fiddaman.P
817*906afcb8SAndy FiddamanA built-in version of \f5kill\fP
818*906afcb8SAndy Fiddamanmakes it possible to use
819*906afcb8SAndy Fiddaman.I job
820*906afcb8SAndy Fiddamannumbers as targets for signals.
821*906afcb8SAndy FiddamanSignals can be selected by number or name.
822*906afcb8SAndy FiddamanThe name of the signal is the name found in the
823*906afcb8SAndy Fiddaman.I include
824*906afcb8SAndy Fiddamanfile
825*906afcb8SAndy Fiddaman.B /usr/include/sys/signal.h
826*906afcb8SAndy Fiddamanwith the prefix
827*906afcb8SAndy Fiddaman.B \s-1SIG\s+1
828*906afcb8SAndy Fiddamanremoved.
829*906afcb8SAndy FiddamanThe
830*906afcb8SAndy Fiddaman.B \-l
831*906afcb8SAndy Fiddamanoption of \f5kill\fP
832*906afcb8SAndy Fiddamanprovides a means to map individual signal names to and from
833*906afcb8SAndy Fiddamansignal number.
834*906afcb8SAndy FiddamanIn addition, if no signal name or number is given,
835*906afcb8SAndy Fiddaman\f5kill\ -l\fP
836*906afcb8SAndy Fiddamangenerates a list of valid signal names.
837*906afcb8SAndy Fiddaman.H 2 "Changing Directories"
838*906afcb8SAndy FiddamanBy default,
839*906afcb8SAndy Fiddaman\f5ksh\fP
840*906afcb8SAndy Fiddamanmaintains a logical view of the file system hierarchy
841*906afcb8SAndy Fiddamanwhich makes symbolic links transparent.
842*906afcb8SAndy FiddamanFor systems that have symbolic links,
843*906afcb8SAndy Fiddamanthis means that if \f5/bin\fP is a symbolic link to \f5/usr/bin\fP
844*906afcb8SAndy Fiddamanand you change directory to \f5/bin\fP, \f5pwd\fP will indicate
845*906afcb8SAndy Fiddamanthat you are in \f5/bin\fP, not \f5/usr/bin\fP.
846*906afcb8SAndy Fiddaman\f5pwd\ -P\fP
847*906afcb8SAndy Fiddamangenerates the physical pathname of the present working
848*906afcb8SAndy Fiddamandirectory by resolving all the symbolic links.
849*906afcb8SAndy FiddamanBy default,
850*906afcb8SAndy Fiddamanthe \f5cd\fP
851*906afcb8SAndy Fiddamancommand will take you where you expect to go even if you cross
852*906afcb8SAndy Fiddamansymbolic links.
853*906afcb8SAndy FiddamanA subsequent \f5cd\ ..\fP in the example above
854*906afcb8SAndy Fiddamanwill place you in \f5/\fP, not \f5/usr\fP.
855*906afcb8SAndy FiddamanOn systems with symbolic links,
856*906afcb8SAndy Fiddaman\f5cd\ -P\fP
857*906afcb8SAndy Fiddamancauses
858*906afcb8SAndy Fiddaman.B ..
859*906afcb8SAndy Fiddamanto be treated physically.
860*906afcb8SAndy Fiddaman.P
861*906afcb8SAndy Fiddaman\f5ksh\fP remembers your last directory
862*906afcb8SAndy Fiddamanin the variable
863*906afcb8SAndy Fiddaman\fB\s-1OLDPWD\s+1\fP.
864*906afcb8SAndy FiddamanThe \f5cd\fP
865*906afcb8SAndy Fiddamanbuilt-in can be given with argument
866*906afcb8SAndy Fiddaman.B \-
867*906afcb8SAndy Fiddamanto return to the previous directory
868*906afcb8SAndy Fiddamanand print the name of the directory.
869*906afcb8SAndy FiddamanNote that \f5cd\ -\fP
870*906afcb8SAndy Fiddamandone twice returns you to the starting directory,
871*906afcb8SAndy Fiddamannot the second previous directory.
872*906afcb8SAndy FiddamanA directory
873*906afcb8SAndy Fiddaman.I stack
874*906afcb8SAndy Fiddamanmanager has been written as shell
875*906afcb8SAndy Fiddaman.I functions
876*906afcb8SAndy Fiddamanto
877*906afcb8SAndy Fiddaman.I push
878*906afcb8SAndy Fiddamanand
879*906afcb8SAndy Fiddaman.I pop
880*906afcb8SAndy Fiddamandirectories from the stack.
881*906afcb8SAndy Fiddaman.H 2 "Prompts"
882*906afcb8SAndy Fiddaman.P
883*906afcb8SAndy FiddamanWhen \f5ksh\fP
884*906afcb8SAndy Fiddamanreads commands from a terminal,
885*906afcb8SAndy Fiddamanit issues a prompt whenever it is ready
886*906afcb8SAndy Fiddamanto accept more input and then
887*906afcb8SAndy Fiddamanwaits for the user to respond.
888*906afcb8SAndy FiddamanThe
889*906afcb8SAndy Fiddaman\fB\s-1TMOUT\s+1\fP
890*906afcb8SAndy Fiddamanvariable
891*906afcb8SAndy Fiddamancan be set to be the number of seconds that the shell will wait for
892*906afcb8SAndy Fiddamaninput before terminating.
893*906afcb8SAndy FiddamanA 60 second warning message is printed
894*906afcb8SAndy Fiddamanbefore terminating.
895*906afcb8SAndy Fiddaman.P
896*906afcb8SAndy FiddamanThe shell uses two prompts.
897*906afcb8SAndy FiddamanThe primary prompt,
898*906afcb8SAndy Fiddamandefined by the value of the
899*906afcb8SAndy Fiddaman\fB\s-1PS1\s+1\fP
900*906afcb8SAndy Fiddamanvariable,
901*906afcb8SAndy Fiddamanis issued at the start of each command.
902*906afcb8SAndy FiddamanThe secondary prompt,
903*906afcb8SAndy Fiddamandefined by the value of the
904*906afcb8SAndy Fiddaman\fB\s-1PS2\s+1\fP
905*906afcb8SAndy Fiddamanvariable,
906*906afcb8SAndy Fiddamanis issued when more input is needed to complete a command.
907*906afcb8SAndy Fiddaman.P
908*906afcb8SAndy Fiddaman\f5ksh\fP allows the user to specify a list of files or directories
909*906afcb8SAndy Fiddamanto check before issuing the
910*906afcb8SAndy Fiddaman\fB\s-1PS1\s+1\fP
911*906afcb8SAndy Fiddamanprompt.
912*906afcb8SAndy FiddamanThe variable
913*906afcb8SAndy Fiddaman\fB\s-1MAILPATH\s+1\fP
914*906afcb8SAndy Fiddamanis a colon (
915*906afcb8SAndy Fiddaman.B :
916*906afcb8SAndy Fiddaman) separated list of file names to be checked for changes
917*906afcb8SAndy Fiddamanperiodically. The user is notified
918*906afcb8SAndy Fiddamanbefore the next prompt.
919*906afcb8SAndy FiddamanEach of the names in this list can be followed by a
920*906afcb8SAndy Fiddaman.B ?
921*906afcb8SAndy Fiddamanand a message to be given when a change has been detected in the file.
922*906afcb8SAndy FiddamanThe prompt will be evaluated for parameter expansion, command
923*906afcb8SAndy Fiddamansubstitution and arithmetic expansion which are described later.
924*906afcb8SAndy FiddamanThe parameter
925*906afcb8SAndy Fiddaman.B $_
926*906afcb8SAndy Fiddamanwithin a mail message will evaluate to the name of the file that
927*906afcb8SAndy Fiddamanhas changed.
928*906afcb8SAndy FiddamanThe parameter
929*906afcb8SAndy Fiddaman\fB\s-1MAILCHECK\s+1\fP
930*906afcb8SAndy Fiddamanis used to specify the minimal interval in seconds before
931*906afcb8SAndy Fiddamannew mail is checked for.
932*906afcb8SAndy Fiddaman.P
933*906afcb8SAndy FiddamanIn addition to replacing each
934*906afcb8SAndy Fiddaman.B !
935*906afcb8SAndy Fiddamanin the prompt with the command number,
936*906afcb8SAndy Fiddaman\f5ksh\fP expands
937*906afcb8SAndy Fiddamanthe value of the
938*906afcb8SAndy Fiddaman.B \s-1PS1\s+1
939*906afcb8SAndy Fiddamanvariable
940*906afcb8SAndy Fiddamanfor parameter expansions, arithmetic expansions,
941*906afcb8SAndy Fiddamanand command substitutions as described below
942*906afcb8SAndy Fiddamanto generate the prompt.
943*906afcb8SAndy FiddamanThe expansion characters that are to be applied when
944*906afcb8SAndy Fiddamanthe prompt is issued must be quoted to prevent the
945*906afcb8SAndy Fiddamanexpansions from occurring when assigning the value to
946*906afcb8SAndy Fiddaman.B \s-1PS1\s+1.
947*906afcb8SAndy FiddamanFor example,
948*906afcb8SAndy Fiddaman\f3\s-1PS1\s+1="$\s-1PWD\s+1"\fP
949*906afcb8SAndy Fiddamancauses
950*906afcb8SAndy Fiddaman.B \s-1PS1\s+1
951*906afcb8SAndy Fiddamanto be set to the value of
952*906afcb8SAndy Fiddaman.B \s-1PWD\s+1
953*906afcb8SAndy Fiddamanat the time of the assignment whereas
954*906afcb8SAndy Fiddaman.B \s-1PS1\s+1='$\s-1PWD\s+1'
955*906afcb8SAndy Fiddamancauses
956*906afcb8SAndy Fiddaman.B \s-1PWD\s+1
957*906afcb8SAndy Fiddamanto be expanded at the time the prompt is issued.
958*906afcb8SAndy Fiddaman.P
959*906afcb8SAndy FiddamanCommand substitution may require a separate process
960*906afcb8SAndy Fiddamanto execute and cause the prompt display to be somewhat
961*906afcb8SAndy Fiddamanslow, especially
962*906afcb8SAndy Fiddamanwhen the return key is pressed several times in a row.
963*906afcb8SAndy FiddamanTherefore, its use
964*906afcb8SAndy Fiddamanwithin
965*906afcb8SAndy Fiddaman.B \s-1PS1\s+1
966*906afcb8SAndy Fiddamanis discouraged.
967*906afcb8SAndy FiddamanSome variables are maintained by \f5ksh\fP
968*906afcb8SAndy Fiddamanso that their values can be used with
969*906afcb8SAndy Fiddaman.B \s-1PS1\s+1.
970*906afcb8SAndy FiddamanThe
971*906afcb8SAndy Fiddaman.B \s-1PWD\s+1
972*906afcb8SAndy Fiddamanvariable stores the pathname of the current working directory.
973*906afcb8SAndy FiddamanThe value of
974*906afcb8SAndy Fiddaman.B \s-1SECONDS\s+1
975*906afcb8SAndy Fiddamanvariable
976*906afcb8SAndy Fiddamanis the value of the most
977*906afcb8SAndy Fiddamanrecent assignment plus the elapsed time.
978*906afcb8SAndy FiddamanBy default, the time is measured in milli-seconds,
979*906afcb8SAndy Fiddamanbut since
980*906afcb8SAndy Fiddaman.B \s-1SECONDS\s+1
981*906afcb8SAndy Fiddamanis a floating point variable, the
982*906afcb8SAndy Fiddamannumber of places after the decimal point in the expanded
983*906afcb8SAndy Fiddamanvalue can be
984*906afcb8SAndy Fiddamanspecified with
985*906afcb8SAndy Fiddaman\f5typeset\ -F\fP\fIplaces\fP\f5\ SECONDS\fP.
986*906afcb8SAndy FiddamanIn a roundabout way, this variable
987*906afcb8SAndy Fiddamancan be used to generate a time stamp into the
988*906afcb8SAndy Fiddaman.B \s-1PS1\s+1
989*906afcb8SAndy Fiddamanprompt without creating a process at each prompt.
990*906afcb8SAndy FiddamanThe following code explains how you can do this on
991*906afcb8SAndy FiddamanSystem V.  On BSD, you need a different command to initialize
992*906afcb8SAndy Fiddamanthe
993*906afcb8SAndy Fiddaman.B \s-1SECONDS\s+1
994*906afcb8SAndy Fiddamanvariable.
995*906afcb8SAndy Fiddaman\f5
996*906afcb8SAndy Fiddaman.sp
997*906afcb8SAndy Fiddaman.nf
998*906afcb8SAndy Fiddaman.in .5i
999*906afcb8SAndy Fiddaman# . this script and use $TIME as part of your PS1 string to
1000*906afcb8SAndy Fiddaman# get the time of day in your prompt
1001*906afcb8SAndy Fiddamantypeset -RZ2  _x1 _x2 _x3
1002*906afcb8SAndy Fiddaman(( SECONDS=$(date  '+3600*%H+60*%M+%S') ))
1003*906afcb8SAndy Fiddaman_s='_x1=(SECONDS/3600)%24,_x2=(SECONDS/60)%60,_x3=SECONDS%60,0'
1004*906afcb8SAndy FiddamanTIME='"${_d[_s]}$_x1:$_x2:$_x3"'
1005*906afcb8SAndy Fiddaman# PS1=${TIME}whatever
1006*906afcb8SAndy Fiddaman.fi
1007*906afcb8SAndy Fiddaman.ta
1008*906afcb8SAndy Fiddaman.in
1009*906afcb8SAndy Fiddaman.sp
1010*906afcb8SAndy Fiddaman\fP
1011*906afcb8SAndy Fiddaman.H 2 "Tilde substitution"
1012*906afcb8SAndy Fiddaman.P
1013*906afcb8SAndy FiddamanThe character
1014*906afcb8SAndy Fiddaman.B \(ap
1015*906afcb8SAndy Fiddamanat the beginning of a word has special meaning to \f5ksh\fP.
1016*906afcb8SAndy FiddamanIf the characters after the
1017*906afcb8SAndy Fiddaman.B \(ap
1018*906afcb8SAndy Fiddamanup to a
1019*906afcb8SAndy Fiddaman.B /
1020*906afcb8SAndy Fiddamanmatch a user login name in the password database, then the
1021*906afcb8SAndy Fiddaman.B \(ap
1022*906afcb8SAndy Fiddamanand the name are replaced by
1023*906afcb8SAndy Fiddamanthat user's login directory.
1024*906afcb8SAndy FiddamanIf no match is found, the original word
1025*906afcb8SAndy Fiddamanis unchanged.
1026*906afcb8SAndy FiddamanA
1027*906afcb8SAndy Fiddaman.B \(ap
1028*906afcb8SAndy Fiddamanby itself, or in front of a
1029*906afcb8SAndy Fiddaman.BR / ,
1030*906afcb8SAndy Fiddamanis replaced by the value of the
1031*906afcb8SAndy Fiddaman\fB\s-1HOME\s+1\fP
1032*906afcb8SAndy Fiddamanparameter.
1033*906afcb8SAndy FiddamanA
1034*906afcb8SAndy Fiddaman.B \(ap
1035*906afcb8SAndy Fiddamanfollowed by a
1036*906afcb8SAndy Fiddaman.B +
1037*906afcb8SAndy Fiddamanor
1038*906afcb8SAndy Fiddaman.B \-
1039*906afcb8SAndy Fiddamanis replaced by the value of
1040*906afcb8SAndy Fiddaman.B $\s-1PWD\s+1
1041*906afcb8SAndy Fiddamanor
1042*906afcb8SAndy Fiddaman.B $\s-1OLDPWD\s+1
1043*906afcb8SAndy Fiddamanrespectively.
1044*906afcb8SAndy Fiddaman.H 2 "Output formats"
1045*906afcb8SAndy FiddamanThe output of built-in commands and traces have values quoted so that they
1046*906afcb8SAndy Fiddamancan be re-input to the shell.
1047*906afcb8SAndy FiddamanThis makes it easy to cut and paste shell output on systems
1048*906afcb8SAndy Fiddamanwhich use a pointing device such as a mouse.
1049*906afcb8SAndy FiddamanIn addition, output can be saved in a file for reuse.
1050*906afcb8SAndy Fiddaman.P
1051*906afcb8SAndy Fiddaman.H 2 "The \fB\s-1ENV\s+1\fP file"
1052*906afcb8SAndy FiddamanWhen an interactive \f5ksh\fP starts, it evaluates the
1053*906afcb8SAndy Fiddaman.B $\s-1ENV\s+1
1054*906afcb8SAndy Fiddamanvariable to arrive at a file name.
1055*906afcb8SAndy FiddamanIf this value is not null,
1056*906afcb8SAndy Fiddaman\f5ksh\fP attempts to read and process
1057*906afcb8SAndy Fiddamancommands in a file by this name.
1058*906afcb8SAndy FiddamanEarlier versions of \f5ksh\fP read the \fB\s-1ENV\s+1\fP file
1059*906afcb8SAndy Fiddamanfor all invocations of the shell primarily to allow
1060*906afcb8SAndy Fiddamanfunction definitions to be available for all shell
1061*906afcb8SAndy Fiddamaninvocations.
1062*906afcb8SAndy FiddamanThe function search path, \fB\s-1FPATH\s+1\fP, described later,
1063*906afcb8SAndy Fiddamaneliminated the primary need for this capability and it was
1064*906afcb8SAndy Fiddamanremoved because the high performance cost was no longer
1065*906afcb8SAndy Fiddamandeemed acceptable.
1066*906afcb8SAndy Fiddaman.H 1 "PROGRAMMING LANGUAGE"
1067*906afcb8SAndy FiddamanThe KornShell vastly extends the set of applications that
1068*906afcb8SAndy Fiddamancan be implemented efficiently at the shell level.
1069*906afcb8SAndy FiddamanIt does this by providing simple yet powerful mechanisms
1070*906afcb8SAndy Fiddamanto perform arithmetic, pattern matching,
1071*906afcb8SAndy Fiddamansubstring generation,
1072*906afcb8SAndy Fiddamanand arrays.
1073*906afcb8SAndy FiddamanUsers can write applications as separate functions that can
1074*906afcb8SAndy Fiddamanbe defined in the same file or in a library of functions
1075*906afcb8SAndy Fiddamanstored in a directory and loaded on demand.
1076*906afcb8SAndy Fiddaman.H 2 "String Processing"
1077*906afcb8SAndy FiddamanThe shell is primarily a string processing language.
1078*906afcb8SAndy FiddamanBy default, variables hold variable length strings.
1079*906afcb8SAndy FiddamanThere are no limits to the length of strings.  Storage
1080*906afcb8SAndy Fiddamanmanagement is handled by the shell automatically.
1081*906afcb8SAndy FiddamanDeclarations are not required.
1082*906afcb8SAndy FiddamanWith most programming languages, string constants are designated
1083*906afcb8SAndy Fiddamanby enclosing characters in single quotes or double quotes.
1084*906afcb8SAndy FiddamanSince most of the words in the language are strings, the shell
1085*906afcb8SAndy Fiddamanrequires quotes only when a string contains characters that
1086*906afcb8SAndy Fiddamanare normally processed specially by the shell, but their
1087*906afcb8SAndy Fiddamanliteral meaning is intended.
1088*906afcb8SAndy FiddamanHowever, since the shell is a string processing language,
1089*906afcb8SAndy Fiddamanand some characters can occur as literals and as language metacharacters,
1090*906afcb8SAndy Fiddamanquoting is an important part of the language.
1091*906afcb8SAndy Fiddaman.P
1092*906afcb8SAndy FiddamanThere are four quoting mechanisms in \f5ksh\fP.
1093*906afcb8SAndy FiddamanThe simplest is to enclose a sequence of characters inside single quotes.
1094*906afcb8SAndy FiddamanAll characters between a pair of single quotes have their literal meaning;
1095*906afcb8SAndy Fiddamanthe single quote itself cannot appear.
1096*906afcb8SAndy FiddamanA
1097*906afcb8SAndy Fiddaman.B $
1098*906afcb8SAndy Fiddamanimmediately preceding
1099*906afcb8SAndy Fiddamana single quoted string
1100*906afcb8SAndy Fiddamancauses all the characters until the matching single quote
1101*906afcb8SAndy Fiddamanto be interpreted as an ANSI-C language string.
1102*906afcb8SAndy FiddamanThus, \f5'\en'\fP represents characters \f5\e\fP and
1103*906afcb8SAndy Fiddaman\f5n\fP, whereas, \f5$'\en'\fP
1104*906afcb8SAndy Fiddamanrepresents the new-line character.
1105*906afcb8SAndy FiddamanDouble quoted strings remove the special meaning of all characters
1106*906afcb8SAndy Fiddamanexcept
1107*906afcb8SAndy Fiddaman.BR $ ,
1108*906afcb8SAndy Fiddaman.BR \(ga ,
1109*906afcb8SAndy Fiddamanand
1110*906afcb8SAndy Fiddaman.BR \e ,
1111*906afcb8SAndy Fiddamanso that parameter expansion and command substitution (defined below)
1112*906afcb8SAndy Fiddamanare performed.
1113*906afcb8SAndy FiddamanThe final mechanism for quoting a character is by preceding it with the
1114*906afcb8SAndy Fiddamanescape character
1115*906afcb8SAndy Fiddaman.BR \e\^ .
1116*906afcb8SAndy FiddamanThis mechanism works outside of quoted strings and for the characters
1117*906afcb8SAndy Fiddaman.BR $ ,
1118*906afcb8SAndy Fiddaman.BR \(ga ,
1119*906afcb8SAndy Fiddaman\fB"\fP,
1120*906afcb8SAndy Fiddamanand
1121*906afcb8SAndy Fiddaman.B \e
1122*906afcb8SAndy Fiddamanin double quoted strings.
1123*906afcb8SAndy Fiddaman.P
1124*906afcb8SAndy FiddamanVariables are designated by
1125*906afcb8SAndy Fiddamanone or more
1126*906afcb8SAndy Fiddamanstrings of alphanumeric
1127*906afcb8SAndy Fiddamancharacters beginning with an alphabetic character
1128*906afcb8SAndy Fiddamanseparated by a \fB\s+2.\s-2\fP.
1129*906afcb8SAndy FiddamanUpper and lower case characters are distinct, so that the variable
1130*906afcb8SAndy Fiddaman.B A
1131*906afcb8SAndy Fiddamanand
1132*906afcb8SAndy Fiddaman.B a
1133*906afcb8SAndy Fiddamanare names of different variables.
1134*906afcb8SAndy FiddamanThere is no
1135*906afcb8SAndy Fiddamanlimit to the length of the name of a variable.
1136*906afcb8SAndy FiddamanYou do not have to declare variables.
1137*906afcb8SAndy FiddamanYou can assign a value to a variable by writing the name of the
1138*906afcb8SAndy Fiddamanvariable, followed by an equal sign, followed by a character string
1139*906afcb8SAndy Fiddamanthat represents its value.
1140*906afcb8SAndy FiddamanTo create a variable whose name
1141*906afcb8SAndy Fiddamancontains a \fB\s+2.\s-2\fP,
1142*906afcb8SAndy Fiddamanthe variable whose name consists of
1143*906afcb8SAndy Fiddamanthe characters before the last \fB\s+2.\s-2\fP
1144*906afcb8SAndy Fiddamanmust already exist.
1145*906afcb8SAndy FiddamanYou reference a variable by
1146*906afcb8SAndy Fiddamanputting the name inside curly braces and
1147*906afcb8SAndy Fiddamanpreceding the braces with a dollar sign.
1148*906afcb8SAndy FiddamanThe braces may be omitted when the name
1149*906afcb8SAndy Fiddamanis alphanumeric.
1150*906afcb8SAndy FiddamanIf \f5x\fP and \f5y\fP
1151*906afcb8SAndy Fiddamanare two shell variables, then
1152*906afcb8SAndy Fiddamanto define a new variable,
1153*906afcb8SAndy Fiddaman\f5z\fP,
1154*906afcb8SAndy Fiddamanwhose value is
1155*906afcb8SAndy Fiddamanthe concatenation of the values of
1156*906afcb8SAndy Fiddaman\f5x\fP and \f5y\fP,
1157*906afcb8SAndy Fiddamanyou just say
1158*906afcb8SAndy Fiddaman\f5z=$x$y\fP.
1159*906afcb8SAndy FiddamanIt is that easy.
1160*906afcb8SAndy Fiddaman.P
1161*906afcb8SAndy FiddamanThe
1162*906afcb8SAndy Fiddaman.B $
1163*906afcb8SAndy Fiddamancan be thought of as meaning
1164*906afcb8SAndy Fiddaman"value of."
1165*906afcb8SAndy FiddamanYou can also capture the output of any command with the notation
1166*906afcb8SAndy Fiddaman.BI $( command ) .
1167*906afcb8SAndy FiddamanThis is referred to as command substitution.
1168*906afcb8SAndy FiddamanFor example,
1169*906afcb8SAndy Fiddaman\f5x=$(date)\fP
1170*906afcb8SAndy Fiddamanassigns the output from the \f5date\fP
1171*906afcb8SAndy Fiddamancommand to the variable \f5x\fP.
1172*906afcb8SAndy FiddamanCommand substitution in the
1173*906afcb8SAndy FiddamanBourne shell is denoted by enclosing the command between
1174*906afcb8SAndy Fiddamanbackquotes,
1175*906afcb8SAndy Fiddaman(\fB\(ga\^\(ga\fP).
1176*906afcb8SAndy FiddamanThis notation
1177*906afcb8SAndy Fiddamansuffers from some
1178*906afcb8SAndy Fiddamancomplicated quoting rules.
1179*906afcb8SAndy FiddamanThus, it is hard to write \f5sed\fP
1180*906afcb8SAndy Fiddamanpatterns which contains back slashes within command substitution.
1181*906afcb8SAndy FiddamanPutting the pattern in single quotes
1182*906afcb8SAndy Fiddamanis of little help.
1183*906afcb8SAndy Fiddaman\f5ksh\fP accepts the Bourne shell command substitution syntax
1184*906afcb8SAndy Fiddamanfor backward compatibility.
1185*906afcb8SAndy FiddamanThe
1186*906afcb8SAndy Fiddaman.BI $( command )
1187*906afcb8SAndy Fiddamannotation allows
1188*906afcb8SAndy Fiddamanthe \fIcommand\fP itself to contain quoted strings even if the substitution
1189*906afcb8SAndy Fiddamanoccurs within double quotes. Nesting is legal.
1190*906afcb8SAndy Fiddaman.P
1191*906afcb8SAndy FiddamanThe special command substitution of the form
1192*906afcb8SAndy Fiddaman\f5$(cat\ file)\fP
1193*906afcb8SAndy Fiddamancan be replaced by
1194*906afcb8SAndy Fiddaman\f5$(<\ file)\fP,
1195*906afcb8SAndy Fiddamanwhich is faster because
1196*906afcb8SAndy Fiddamanthe \f5cat\fP
1197*906afcb8SAndy Fiddamancommand doesn't have to run.
1198*906afcb8SAndy Fiddaman.H 2 "Shell Parameters and Variables"
1199*906afcb8SAndy Fiddaman.P
1200*906afcb8SAndy FiddamanThere are three types of parameters used by \f5ksh\fP,
1201*906afcb8SAndy Fiddamanspecial parameters, positional parameters, and named
1202*906afcb8SAndy Fiddamanparameters which are called variables.
1203*906afcb8SAndy Fiddaman\f5ksh\fP defines the same special parameters,
1204*906afcb8SAndy Fiddaman.BR 0 ,
1205*906afcb8SAndy Fiddaman.BR * ,
1206*906afcb8SAndy Fiddaman.BR @ ,
1207*906afcb8SAndy Fiddaman.BR # ,
1208*906afcb8SAndy Fiddaman.BR ? ,
1209*906afcb8SAndy Fiddaman.BR $ ,
1210*906afcb8SAndy Fiddaman.BR ! ,
1211*906afcb8SAndy Fiddamanand
1212*906afcb8SAndy Fiddaman.BR \- ,
1213*906afcb8SAndy Fiddamanas in the Bourne shell.
1214*906afcb8SAndy Fiddaman.P
1215*906afcb8SAndy FiddamanPositional parameters are set when the shell is invoked,
1216*906afcb8SAndy Fiddamanas arguments to the \f5set\fP built-in,
1217*906afcb8SAndy Fiddamanand by calls to functions (see below) and \fB\s+2.\s-2\fP
1218*906afcb8SAndy Fiddamanprocedures.
1219*906afcb8SAndy FiddamanThey are named by numbers starting at 1.
1220*906afcb8SAndy Fiddaman.P
1221*906afcb8SAndy FiddamanThe third type of parameter is a variable.
1222*906afcb8SAndy FiddamanAs mentioned earlier,
1223*906afcb8SAndy Fiddaman\f5ksh\fP uses variables whose names
1224*906afcb8SAndy Fiddamanconsist of one or more
1225*906afcb8SAndy Fiddamanalpha-numeric strings separated by a \fB\s+2.\s-2\fP.
1226*906afcb8SAndy FiddamanThere is no need to specify the
1227*906afcb8SAndy Fiddaman.I type
1228*906afcb8SAndy Fiddamanof a variable in the shell because, by default,
1229*906afcb8SAndy Fiddamanvariables store strings of arbitrary length
1230*906afcb8SAndy Fiddamanand values will automatically be converted to numbers
1231*906afcb8SAndy Fiddamanwhen used in an arithmetic context.
1232*906afcb8SAndy FiddamanHowever, \f5ksh\fP variables
1233*906afcb8SAndy Fiddamancan have one or more
1234*906afcb8SAndy Fiddaman.I attributes
1235*906afcb8SAndy Fiddamanthat control the internal representation of the variable,
1236*906afcb8SAndy Fiddamanthe way the variable is printed, and its access or
1237*906afcb8SAndy Fiddamanscope.
1238*906afcb8SAndy FiddamanIn addition,
1239*906afcb8SAndy Fiddaman\f5ksh\fP
1240*906afcb8SAndy Fiddamanallows variables to represent arrays of values
1241*906afcb8SAndy Fiddamanand references to other variables.
1242*906afcb8SAndy FiddamanThe \f5typeset\fP
1243*906afcb8SAndy Fiddamanbuilt-in command of \f5ksh\fP
1244*906afcb8SAndy Fiddamanassigns attributes to variables.
1245*906afcb8SAndy FiddamanTwo of the attributes,
1246*906afcb8SAndy Fiddaman.I readonly
1247*906afcb8SAndy Fiddamanand
1248*906afcb8SAndy Fiddaman.IR export ,
1249*906afcb8SAndy Fiddamanare available in the Bourne shell.
1250*906afcb8SAndy FiddamanMost of the remaining attributes are discussed here.
1251*906afcb8SAndy FiddamanThe complete list of attributes appears in the manual.
1252*906afcb8SAndy FiddamanThe \f5unset\fP
1253*906afcb8SAndy Fiddamanbuilt-in of \f5ksh\fP removes
1254*906afcb8SAndy Fiddamanvalues and attributes of variables.
1255*906afcb8SAndy FiddamanWhen a variable is exported, certain of its attributes are also exported.
1256*906afcb8SAndy Fiddaman.P
1257*906afcb8SAndy FiddamanWhenever a value is assigned to a variable,
1258*906afcb8SAndy Fiddamanthe value is transformed according to the attributes of the variable.
1259*906afcb8SAndy FiddamanChanging the attribute of a variable can change its value.
1260*906afcb8SAndy FiddamanThe attributes
1261*906afcb8SAndy Fiddaman.B \-L
1262*906afcb8SAndy Fiddamanand
1263*906afcb8SAndy Fiddaman.B \-R
1264*906afcb8SAndy Fiddamanare for left and right field justification respectively.
1265*906afcb8SAndy FiddamanThey are useful for aligning columns in a report.
1266*906afcb8SAndy FiddamanFor each of these attributes, a width can be defined explicitly or else
1267*906afcb8SAndy Fiddamanit is defined the first time an assignment is made to the variable.
1268*906afcb8SAndy FiddamanEach assignment causes justification of the field, truncating
1269*906afcb8SAndy Fiddamanif necessary.
1270*906afcb8SAndy FiddamanAssignment to fixed sized variables
1271*906afcb8SAndy Fiddamanprovides one way to generate a substring consisting of
1272*906afcb8SAndy Fiddamana fixed number of characters from
1273*906afcb8SAndy Fiddamanthe beginning or end of a string.
1274*906afcb8SAndy FiddamanOther methods are discussed later.
1275*906afcb8SAndy Fiddaman.P
1276*906afcb8SAndy FiddamanThe attributes
1277*906afcb8SAndy Fiddaman.B \-u
1278*906afcb8SAndy Fiddamanand
1279*906afcb8SAndy Fiddaman.B \-l
1280*906afcb8SAndy Fiddamanare used for upper case and lower case
1281*906afcb8SAndy Fiddamanformatting, respectively.
1282*906afcb8SAndy FiddamanSince it makes no sense to have both attributes on simultaneously,
1283*906afcb8SAndy Fiddamanturning on either of these attributes turns the other off.
1284*906afcb8SAndy FiddamanThe following script,
1285*906afcb8SAndy Fiddamanusing \f5read\fP and \f5print\fP which are described later,
1286*906afcb8SAndy Fiddamanprovides an example of the use of shell variables
1287*906afcb8SAndy Fiddamanwith attributes.
1288*906afcb8SAndy FiddamanThis script reads a file of lines each consisting of five fields separated by
1289*906afcb8SAndy Fiddaman.B :
1290*906afcb8SAndy Fiddamanand prints fields 4 and 2 in upper case in columns 1-15, left justified,
1291*906afcb8SAndy Fiddamanand columns 20-25 right-justified respectively.
1292*906afcb8SAndy Fiddaman.sp
1293*906afcb8SAndy Fiddaman.nf
1294*906afcb8SAndy Fiddaman.in .5i
1295*906afcb8SAndy Fiddaman.ta 3.4i
1296*906afcb8SAndy Fiddaman\f5typeset -uL15 f4                # 15 character left justified
1297*906afcb8SAndy Fiddamantypeset -uR6 f2                 # 6 character right justified
1298*906afcb8SAndy FiddamanIFS=:                           # set field separator to :
1299*906afcb8SAndy Fiddamanwhile   read -r f1 f2 f3 f4 f5  # read line, split into fields
1300*906afcb8SAndy Fiddamando      print -r -- "$f4  $f2"  # print fields 4 and 2
1301*906afcb8SAndy Fiddamandone\fP
1302*906afcb8SAndy Fiddaman.fi
1303*906afcb8SAndy Fiddaman.ta
1304*906afcb8SAndy Fiddaman.in
1305*906afcb8SAndy Fiddaman.sp
1306*906afcb8SAndy Fiddaman.P
1307*906afcb8SAndy FiddamanThe
1308*906afcb8SAndy Fiddaman.BR \-i ,
1309*906afcb8SAndy Fiddaman.BR \-E ,
1310*906afcb8SAndy Fiddamanand
1311*906afcb8SAndy Fiddaman.BR \-F ,
1312*906afcb8SAndy Fiddamanattributes are used to represent numbers.
1313*906afcb8SAndy FiddamanEach can be followed by a decimal number.
1314*906afcb8SAndy FiddamanThe
1315*906afcb8SAndy Fiddaman.B \-i
1316*906afcb8SAndy Fiddamanattribute causes the value to be represented as an integer and it
1317*906afcb8SAndy Fiddamancan be followed by a number representing the numeric base when expanding
1318*906afcb8SAndy Fiddamanits value.
1319*906afcb8SAndy FiddamanWhenever a value is assigned to an integer variable, it is evaluated
1320*906afcb8SAndy Fiddamanas an arithmetic expression
1321*906afcb8SAndy Fiddamanand then truncated to an integer.
1322*906afcb8SAndy Fiddaman.P
1323*906afcb8SAndy FiddamanThe
1324*906afcb8SAndy Fiddaman.B \-E
1325*906afcb8SAndy Fiddamanattribute causes the value to be represented in scientific
1326*906afcb8SAndy Fiddamannotation whenever its value is expanded.  The number following the
1327*906afcb8SAndy Fiddaman.B \-E
1328*906afcb8SAndy Fiddamandetermines the number of significant figures, and defaults to 6.
1329*906afcb8SAndy FiddamanThe
1330*906afcb8SAndy Fiddaman.B \-F
1331*906afcb8SAndy Fiddamanattribute causes the value to be represented with a fixed number
1332*906afcb8SAndy Fiddamanof places after the decimal point.
1333*906afcb8SAndy FiddamanAssignments to variables with the
1334*906afcb8SAndy Fiddaman.B \-E
1335*906afcb8SAndy Fiddamanor
1336*906afcb8SAndy Fiddaman.B \-F
1337*906afcb8SAndy Fiddamanattributes cause the evaluation of the right hand side of the assignment.
1338*906afcb8SAndy Fiddaman.P
1339*906afcb8SAndy Fiddaman\f5ksh\fP allows one-dimensional
1340*906afcb8SAndy Fiddaman.I arrays
1341*906afcb8SAndy Fiddamanin addition to simple variables.
1342*906afcb8SAndy FiddamanThere are two types of arrays; associative arrays
1343*906afcb8SAndy Fiddamanand indexed arrays.
1344*906afcb8SAndy FiddamanThe subscript for an associative array is an arbitrary
1345*906afcb8SAndy Fiddamanstring, whereas the subscript for an indexed array is
1346*906afcb8SAndy Fiddamanan arithmetic expression that is evaluated to yield an integer
1347*906afcb8SAndy Fiddamanindex.
1348*906afcb8SAndy FiddamanAny variable can become an indexed array
1349*906afcb8SAndy Fiddamanby referring to it with
1350*906afcb8SAndy Fiddamanan integer
1351*906afcb8SAndy Fiddaman.IR subscript .
1352*906afcb8SAndy FiddamanAll elements of an array need not exist.
1353*906afcb8SAndy FiddamanSubscripts for arrays
1354*906afcb8SAndy Fiddamanmust evaluate to an
1355*906afcb8SAndy Fiddamaninteger between 0 and some maximum value, otherwise
1356*906afcb8SAndy Fiddamanan error results.
1357*906afcb8SAndy FiddamanThe maximum value may vary from one machine to another but
1358*906afcb8SAndy Fiddamanis at least 4095.
1359*906afcb8SAndy FiddamanEvaluation of subscripts is described in
1360*906afcb8SAndy Fiddamanthe next section.
1361*906afcb8SAndy FiddamanAttributes apply to the whole array.
1362*906afcb8SAndy Fiddaman.P
1363*906afcb8SAndy FiddamanAssignments to array variables can be made to individual elements
1364*906afcb8SAndy Fiddamanvia parameter
1365*906afcb8SAndy Fiddamanassignment commands or the
1366*906afcb8SAndy Fiddaman.B typeset
1367*906afcb8SAndy Fiddamanbuilt-in.
1368*906afcb8SAndy FiddamanAdditionally, values can be assigned sequentially with
1369*906afcb8SAndy Fiddamancompound assignment as described below, or by the
1370*906afcb8SAndy Fiddaman.B \-A
1371*906afcb8SAndy Fiddaman.I name
1372*906afcb8SAndy Fiddamanoption of the \f5set\fP command.
1373*906afcb8SAndy FiddamanReferencing of subscripted variables requires the character
1374*906afcb8SAndy Fiddaman.BR $ ,
1375*906afcb8SAndy Fiddamanbut also requires braces around the array element name.
1376*906afcb8SAndy FiddamanThe braces are needed to avoid conflicts with the
1377*906afcb8SAndy Fiddamanfile name generation mechanism.
1378*906afcb8SAndy FiddamanThe form of any array element reference is:
1379*906afcb8SAndy Fiddaman.ce
1380*906afcb8SAndy Fiddaman.BI ${ name [ subscript ]}
1381*906afcb8SAndy FiddamanSubscript values of
1382*906afcb8SAndy Fiddaman.B *
1383*906afcb8SAndy Fiddamanand
1384*906afcb8SAndy Fiddaman.B @
1385*906afcb8SAndy Fiddamancan be used to generate all elements of an array,
1386*906afcb8SAndy Fiddamanas they are used for expansion of positional parameters.
1387*906afcb8SAndy FiddamanThe list of currently defined subscripts for a given
1388*906afcb8SAndy Fiddamanvariable can be generated with
1389*906afcb8SAndy Fiddaman.BI ${! name [@]} ,
1390*906afcb8SAndy Fiddamanor
1391*906afcb8SAndy Fiddaman.BI ${! name [*]} .
1392*906afcb8SAndy Fiddaman.P
1393*906afcb8SAndy FiddamanThe
1394*906afcb8SAndy Fiddaman.B \-n
1395*906afcb8SAndy Fiddamanor
1396*906afcb8SAndy Fiddaman.I nameref
1397*906afcb8SAndy Fiddamanattribute causes the variable to be treated
1398*906afcb8SAndy Fiddamanas a reference to the variable defined by its value.
1399*906afcb8SAndy FiddamanOnce this attribute is set, all references to this variable
1400*906afcb8SAndy Fiddamanbecome references to the variable named by the value
1401*906afcb8SAndy Fiddamanof this variable.
1402*906afcb8SAndy FiddamanFor example, if \f5foo=bar\fP, then setting the reference
1403*906afcb8SAndy Fiddamanattribute on \f5foo\fP will cause all subsequent references
1404*906afcb8SAndy Fiddamanto \f5foo\fP to behave as the variable whose name is \f5$foo\fP
1405*906afcb8SAndy Fiddamanwas referenced, which in this case is the variable \f5bar\fP.
1406*906afcb8SAndy FiddamanUnsetting this attribute breaks the association.
1407*906afcb8SAndy FiddamanReference variables are usually used inside functions whose
1408*906afcb8SAndy Fiddamanarguments are the names of shell variables.
1409*906afcb8SAndy FiddamanThe names for reference variables cannot contain a \fB\s+2.\s-2\fP.
1410*906afcb8SAndy FiddamanWhenever a shell variable is referenced, the portion of the
1411*906afcb8SAndy Fiddamanvariable up to the first \fB\s+2.\s-2\fP
1412*906afcb8SAndy Fiddamanis checked to see whether it matches the name of a reference
1413*906afcb8SAndy Fiddamanvariable.
1414*906afcb8SAndy FiddamanIf it does, then the name of the variable actually used
1415*906afcb8SAndy Fiddamanconsists of the concatenation of the name of the variable
1416*906afcb8SAndy Fiddamandefined by the reference plus the remaining portion of the
1417*906afcb8SAndy Fiddamanoriginal variable name.
1418*906afcb8SAndy FiddamanFor example, using the predefined alias, \f5alias\ nameref='typeset\ -n'\fP,
1419*906afcb8SAndy Fiddaman.sp
1420*906afcb8SAndy Fiddaman.nf
1421*906afcb8SAndy Fiddaman.in .5i
1422*906afcb8SAndy Fiddaman.ta 3.4i
1423*906afcb8SAndy Fiddaman\f5\^.bar.home.bam="hello world"
1424*906afcb8SAndy Fiddamannameref foo=.bar.home
1425*906afcb8SAndy Fiddamanprint ${foo.bam}
1426*906afcb8SAndy Fiddaman\fBhello world\fP\fP
1427*906afcb8SAndy Fiddaman.fi
1428*906afcb8SAndy Fiddaman.ta
1429*906afcb8SAndy Fiddaman.in
1430*906afcb8SAndy Fiddaman.sp
1431*906afcb8SAndy Fiddaman.H 2 "Compound Assignment"
1432*906afcb8SAndy FiddamanCompound assignments are used to assign values to arrays
1433*906afcb8SAndy Fiddamanand compound data structures.
1434*906afcb8SAndy FiddamanThe syntax for a compound assignment is
1435*906afcb8SAndy Fiddaman.IB name =( assignment-list )
1436*906afcb8SAndy Fiddamanwhere
1437*906afcb8SAndy Fiddaman\fIname\fP
1438*906afcb8SAndy Fiddamanis the name of the variable to which you want to assign values.
1439*906afcb8SAndy FiddamanNo space is permitted between the variable name and the \fB=\fP
1440*906afcb8SAndy Fiddamanbut can appear between the \fB=\fP and the open parenthesis.
1441*906afcb8SAndy FiddamanNew-lines can appear between the parentheses.
1442*906afcb8SAndy Fiddaman.P
1443*906afcb8SAndy FiddamanThe \fIassignment-list\fP can be in several different forms
1444*906afcb8SAndy Fiddamanyielding different results.
1445*906afcb8SAndy FiddamanIf \fIassignment-list\fP is simply a list of words, then
1446*906afcb8SAndy Fiddamanthe words are processed as they are with the \f5for\fP command
1447*906afcb8SAndy Fiddamanand assigned sequentially as an indexed array.
1448*906afcb8SAndy FiddamanFor example,
1449*906afcb8SAndy Fiddaman.ce
1450*906afcb8SAndy Fiddaman\f5foo=( * )\fP
1451*906afcb8SAndy Fiddamancreates an indexed array \f5foo\fP and assigns the
1452*906afcb8SAndy Fiddamanfile names in the current directory to each index starting
1453*906afcb8SAndy Fiddamanat zero.
1454*906afcb8SAndy Fiddaman.P
1455*906afcb8SAndy FiddamanThe second form for \fIassignment-list\fP is a list of assignments
1456*906afcb8SAndy Fiddamanof the special form \fB[\fP\fIword\fP\fB]=\fP\fIword\fP.
1457*906afcb8SAndy FiddamanNo space is permitted before or after the \fB=\fP.
1458*906afcb8SAndy FiddamanIn this case, the variable given by \fIname\fP becomes
1459*906afcb8SAndy Fiddamanan associative array with the given arguments as subscripts.
1460*906afcb8SAndy FiddamanFor example,
1461*906afcb8SAndy Fiddaman.ce
1462*906afcb8SAndy Fiddaman\f5bar=( [color]=red [shape]=box )\fP
1463*906afcb8SAndy Fiddamancreates an associate array named \f5bar\fP whose
1464*906afcb8SAndy Fiddamansubscripts are \f5color\fP and \f5shape\fP.
1465*906afcb8SAndy Fiddaman.P
1466*906afcb8SAndy FiddamanThe third form for \fIassignment-list\fP is a list of
1467*906afcb8SAndy Fiddamannormal assignments, including compound assignments.
1468*906afcb8SAndy FiddamanThese assignments cause sub-variables to be assigned
1469*906afcb8SAndy Fiddamancorresponding to the given assignments.
1470*906afcb8SAndy FiddamanIn addition to assignments, the \fIassignment-list\fP
1471*906afcb8SAndy Fiddamancan contain \f5typeset\fP commands.
1472*906afcb8SAndy FiddamanIn addition to creating sub-variables,
1473*906afcb8SAndy Fiddamanthe effect of a compound assignment is to make
1474*906afcb8SAndy Fiddamanthe value of the original variable be a parenthesized
1475*906afcb8SAndy Fiddamanassignment list of its components.
1476*906afcb8SAndy FiddamanFor example, the assignment
1477*906afcb8SAndy Fiddaman.sp
1478*906afcb8SAndy Fiddaman.nf
1479*906afcb8SAndy Fiddaman.in .5i
1480*906afcb8SAndy Fiddaman.ta 3.4i
1481*906afcb8SAndy Fiddaman\f5foo=(
1482*906afcb8SAndy Fiddaman        left=bar
1483*906afcb8SAndy Fiddaman        typeset -i count=3
1484*906afcb8SAndy Fiddaman        point=(
1485*906afcb8SAndy Fiddaman                x=50
1486*906afcb8SAndy Fiddaman                y=60
1487*906afcb8SAndy Fiddaman        )
1488*906afcb8SAndy Fiddaman        colors=( red green yellow )
1489*906afcb8SAndy Fiddaman        right=bam
1490*906afcb8SAndy Fiddaman) \fP
1491*906afcb8SAndy Fiddaman.ta
1492*906afcb8SAndy Fiddaman.in
1493*906afcb8SAndy Fiddaman.fi
1494*906afcb8SAndy Fiddaman.sp
1495*906afcb8SAndy Fiddamanis equivalent to the assignments
1496*906afcb8SAndy Fiddaman.sp
1497*906afcb8SAndy Fiddaman.nf
1498*906afcb8SAndy Fiddaman.in .5i
1499*906afcb8SAndy Fiddaman.ta 3.4i
1500*906afcb8SAndy Fiddaman\f5foo.left=bar
1501*906afcb8SAndy Fiddamanfoo.count=3
1502*906afcb8SAndy Fiddamanfoo.point.x=50
1503*906afcb8SAndy Fiddamanfoo.point.y=60
1504*906afcb8SAndy Fiddamanfoo.colors=( red green yellow )
1505*906afcb8SAndy Fiddamanfoo.right=bam\fP
1506*906afcb8SAndy Fiddaman.ta
1507*906afcb8SAndy Fiddaman.in
1508*906afcb8SAndy Fiddaman.fi
1509*906afcb8SAndy Fiddaman.sp
1510*906afcb8SAndy FiddamanIn addition, the value of \f5"$foo"\fP is
1511*906afcb8SAndy Fiddaman.sp
1512*906afcb8SAndy Fiddaman.nf
1513*906afcb8SAndy Fiddaman.in .5i
1514*906afcb8SAndy Fiddaman.ta 3.4i
1515*906afcb8SAndy Fiddaman\f5(
1516*906afcb8SAndy Fiddaman        colors=( red green yellow )
1517*906afcb8SAndy Fiddaman        left=bar
1518*906afcb8SAndy Fiddaman        typeset -i count=3
1519*906afcb8SAndy Fiddaman        point=(
1520*906afcb8SAndy Fiddaman                y=60
1521*906afcb8SAndy Fiddaman                x=50
1522*906afcb8SAndy Fiddaman        )
1523*906afcb8SAndy Fiddaman        right=bam
1524*906afcb8SAndy Fiddaman)\fP
1525*906afcb8SAndy Fiddaman.ta
1526*906afcb8SAndy Fiddaman.in
1527*906afcb8SAndy Fiddaman.fi
1528*906afcb8SAndy Fiddaman.sp
1529*906afcb8SAndy Fiddaman.H 2 "Substring Generation"
1530*906afcb8SAndy FiddamanThe expansion of a variable or parameter can be modified so that
1531*906afcb8SAndy Fiddamanonly a portion of the value results.
1532*906afcb8SAndy FiddamanIt is often necessary to extract a portion of a shell variable or
1533*906afcb8SAndy Fiddamana portion of an array.
1534*906afcb8SAndy FiddamanThere are several parameter expansion operators that can do this.
1535*906afcb8SAndy FiddamanOne method to generate a substring is with an expansion of
1536*906afcb8SAndy Fiddamanthe form \fB${\fP\fIname\fP\fB:\fP\fIoffset\fP\fB:\fP\fIlength\fP\fB}\fP
1537*906afcb8SAndy Fiddamanwhere \fIoffset\^\fP is an arithmetic expression that defines the
1538*906afcb8SAndy Fiddamanoffset of the first character starting from 0, and
1539*906afcb8SAndy Fiddaman\fIlength\^\fP is an arithmetic expression that defines the
1540*906afcb8SAndy Fiddamanlength of the substring.
1541*906afcb8SAndy FiddamanIf
1542*906afcb8SAndy Fiddaman.BI : length\^
1543*906afcb8SAndy Fiddamanis omitted,
1544*906afcb8SAndy Fiddamanthe length of the value of
1545*906afcb8SAndy Fiddaman.I name\^
1546*906afcb8SAndy Fiddamanstarting at
1547*906afcb8SAndy Fiddaman.I offset\^
1548*906afcb8SAndy Fiddamanis used.
1549*906afcb8SAndy FiddamanThe
1550*906afcb8SAndy Fiddaman.BI : offset : length
1551*906afcb8SAndy Fiddamanoperators can also be applied to array expansions and to parameters
1552*906afcb8SAndy Fiddaman.B *
1553*906afcb8SAndy Fiddamanand
1554*906afcb8SAndy Fiddaman.B @
1555*906afcb8SAndy Fiddamanto generate portions of an array.
1556*906afcb8SAndy FiddamanFor example, the expansion, \fB${\fP\fIname\fP\fB[@]:\fP\fIoffset\fP\fB:\fP\fIlength\fP\fB}\fP, yields up to \fIlength\fP elements of the array \fIname\fP
1557*906afcb8SAndy Fiddamanstarting at the element \fIoffset\fP.
1558*906afcb8SAndy Fiddaman.P
1559*906afcb8SAndy FiddamanThe other parameter expansion modifiers use shell patterns
1560*906afcb8SAndy Fiddamanto describe portions of the string to modify and delete.
1561*906afcb8SAndy FiddamanA description of shell patterns is contained below.
1562*906afcb8SAndy FiddamanWhen these
1563*906afcb8SAndy Fiddamanmodifiers are applied to special parameters
1564*906afcb8SAndy Fiddaman.B @
1565*906afcb8SAndy Fiddamanand
1566*906afcb8SAndy Fiddaman.B *
1567*906afcb8SAndy Fiddamanor to array parameters given as
1568*906afcb8SAndy Fiddaman\fIname\fP\fB[@]\fP or \fIname\fP\fB[*]\fP,
1569*906afcb8SAndy Fiddamanthe operation is performed on each element.
1570*906afcb8SAndy FiddamanThere are four parameter expansion modifiers that
1571*906afcb8SAndy Fiddamanstrip off leading and trailing substrings
1572*906afcb8SAndy Fiddamanduring parameter expansion
1573*906afcb8SAndy Fiddamanby removing the characters matching a given pattern.
1574*906afcb8SAndy FiddamanAn expansion of
1575*906afcb8SAndy Fiddamanthe form \fB${\fP\fIname\fP\fB#\fP\fIpattern\fP\fB}\fP
1576*906afcb8SAndy Fiddamancauses the smallest matching prefix of the value of
1577*906afcb8SAndy Fiddaman.I name\^
1578*906afcb8SAndy Fiddamanto be removed.
1579*906afcb8SAndy FiddamanThe largest prefix matching
1580*906afcb8SAndy Fiddaman.I pattern\^
1581*906afcb8SAndy Fiddamanis removed by using
1582*906afcb8SAndy Fiddaman.B ##
1583*906afcb8SAndy Fiddamaninstead of
1584*906afcb8SAndy Fiddaman.BR # .
1585*906afcb8SAndy FiddamanSimilarly,
1586*906afcb8SAndy Fiddamanan expansion of
1587*906afcb8SAndy Fiddamanthe form \fB${\fP\fIname\fP\fB%\fP\fIpattern\fP\fB}\fP
1588*906afcb8SAndy Fiddamancauses the smallest matching substring at the end of
1589*906afcb8SAndy Fiddaman.I name\^
1590*906afcb8SAndy Fiddamanto be removed.
1591*906afcb8SAndy FiddamanAgain, using
1592*906afcb8SAndy Fiddaman.B %%
1593*906afcb8SAndy Fiddamaninstead of
1594*906afcb8SAndy Fiddaman.BR % ,
1595*906afcb8SAndy Fiddamancauses the largest matching trailing substring to be deleted.
1596*906afcb8SAndy FiddamanFor example, if the shell variable
1597*906afcb8SAndy Fiddaman.B file
1598*906afcb8SAndy Fiddamanhas value
1599*906afcb8SAndy Fiddaman.BR foo.c ,
1600*906afcb8SAndy Fiddamanthen the expression
1601*906afcb8SAndy Fiddaman.B ${file%.c}.o
1602*906afcb8SAndy Fiddamanhas value
1603*906afcb8SAndy Fiddaman.BR foo.o .
1604*906afcb8SAndy Fiddaman.P
1605*906afcb8SAndy FiddamanThe value of an expansion can be changed by
1606*906afcb8SAndy Fiddamanspecifying a pattern that matches the part that needs to be changed
1607*906afcb8SAndy Fiddamanafter the
1608*906afcb8SAndy Fiddamanthe parameter expansion modifier
1609*906afcb8SAndy Fiddaman.BR / .
1610*906afcb8SAndy FiddamanAn expansion of the form
1611*906afcb8SAndy Fiddaman\fB${\fP\fIname\fP\fB/\fP\fIpattern\fP\fB/\fP\fIstring\fP\fB}\fP
1612*906afcb8SAndy Fiddamanreplaces the first match of \fIpattern\fP with
1613*906afcb8SAndy Fiddamanthe value of variable \fIname\fP to \fIstring\fP.
1614*906afcb8SAndy FiddamanThe second
1615*906afcb8SAndy Fiddaman.B /
1616*906afcb8SAndy Fiddamanis not necessary when \fIstring\fP is null.
1617*906afcb8SAndy FiddamanThe expansion
1618*906afcb8SAndy Fiddaman\fB${\fP\fIname\fP\fB//\fP\fIpattern\fP\fB/\fP\fIstring\fP\fB}\fP
1619*906afcb8SAndy Fiddamanchanges all occurrences of the \fIpattern\fP into \fIstring\fP.
1620*906afcb8SAndy FiddamanThe parameter expansion modifiers
1621*906afcb8SAndy Fiddaman.B /#
1622*906afcb8SAndy Fiddamanand
1623*906afcb8SAndy Fiddaman.B /%
1624*906afcb8SAndy Fiddamancause the matching pattern to be anchored to the beginning and
1625*906afcb8SAndy Fiddamanend respectively.
1626*906afcb8SAndy Fiddaman.P
1627*906afcb8SAndy FiddamanFinally, there are parameter expansion modifiers that yield
1628*906afcb8SAndy Fiddamanthe name of the variable, the string length of the value, or the number
1629*906afcb8SAndy Fiddamanof elements of an array.
1630*906afcb8SAndy Fiddaman\fB${!\fP\fIname\fP\fB}\fP
1631*906afcb8SAndy Fiddamanyields the name of the variable which will be \fIname\fP itself
1632*906afcb8SAndy Fiddamanexcept when \fIname\fP is a reference variable.  In this case
1633*906afcb8SAndy Fiddamanit will yield the name of the variable it refers to.
1634*906afcb8SAndy FiddamanWhen applied to an array variable,
1635*906afcb8SAndy Fiddaman\fB${!\fP\fIname\fP\fB[@]}\fP and
1636*906afcb8SAndy Fiddaman\fB${!\fP\fIname\fP\fB[*]}\fP
1637*906afcb8SAndy Fiddamangenerate the names of all subscripts.
1638*906afcb8SAndy Fiddaman\fB${#\fP\fIname\fP\fB}\fP
1639*906afcb8SAndy Fiddamanwill be the length in bytes of
1640*906afcb8SAndy Fiddaman\fB$\fP\fIname\fP.
1641*906afcb8SAndy FiddamanFor an array variable
1642*906afcb8SAndy Fiddaman\fB${#\fP\fIname\fP\fB[*]}\fP
1643*906afcb8SAndy Fiddamangives the number of elements in the array.
1644*906afcb8SAndy Fiddaman.H 2 "Arithmetic Evaluation"
1645*906afcb8SAndy Fiddaman.P
1646*906afcb8SAndy FiddamanFor the most part, the shell is a string processing
1647*906afcb8SAndy Fiddamanlanguage.  However, the need for arithmetic has
1648*906afcb8SAndy Fiddamanlong been obvious.
1649*906afcb8SAndy FiddamanMany of the characters that are special to the
1650*906afcb8SAndy FiddamanBourne shell are needed as arithmetic operators.
1651*906afcb8SAndy FiddamanTo make arithmetic easy to use, and to maintain
1652*906afcb8SAndy Fiddamancompatibility with the Bourne shell, \f5ksh\fP uses matching
1653*906afcb8SAndy Fiddaman.B ((
1654*906afcb8SAndy Fiddamanand
1655*906afcb8SAndy Fiddaman.B ))
1656*906afcb8SAndy Fiddamanto delineate arithmetic expressions.
1657*906afcb8SAndy FiddamanWhile single parentheses might have been
1658*906afcb8SAndy Fiddamanmore desirable, these already mean
1659*906afcb8SAndy Fiddaman.I subshell\^
1660*906afcb8SAndy Fiddamanso that another notation was required.
1661*906afcb8SAndy FiddamanThe arithmetic expression
1662*906afcb8SAndy Fiddamaninside the double parentheses
1663*906afcb8SAndy Fiddamanfollows the same syntax, associativity and precedence
1664*906afcb8SAndy Fiddamanas the ANSI-C\*(Rf
1665*906afcb8SAndy Fiddaman.RS
1666*906afcb8SAndy FiddamanAmerican National Standard for Information Systems \- Programming
1667*906afcb8SAndy FiddamanLanguage \- C, ANSI X3.159-1989.
1668*906afcb8SAndy Fiddaman.RF
1669*906afcb8SAndy Fiddamanprogramming language.
1670*906afcb8SAndy FiddamanThe characters between the matching double parentheses
1671*906afcb8SAndy Fiddamanare processed with the same rules used for double
1672*906afcb8SAndy Fiddamanquotes so that spaces can be used to aid readability
1673*906afcb8SAndy Fiddamanwithout additional quoting.
1674*906afcb8SAndy Fiddaman.P
1675*906afcb8SAndy FiddamanAll arithmetic evaluations are performed using
1676*906afcb8SAndy Fiddamandouble precision floating point arithmetic.
1677*906afcb8SAndy FiddamanFloating point constants follow the same rules as
1678*906afcb8SAndy Fiddamanthe ANSI-C programming language.
1679*906afcb8SAndy FiddamanInteger arithmetic constants are written as
1680*906afcb8SAndy Fiddaman.ce
1681*906afcb8SAndy Fiddaman.IB base # number,
1682*906afcb8SAndy Fiddamanwhere
1683*906afcb8SAndy Fiddaman.I base\^
1684*906afcb8SAndy Fiddamanis a decimal integer between
1685*906afcb8SAndy Fiddamantwo and sixty-four and
1686*906afcb8SAndy Fiddaman.I number\^
1687*906afcb8SAndy Fiddamanis any non-negative number.
1688*906afcb8SAndy FiddamanBase ten is used
1689*906afcb8SAndy Fiddamanwhen no base is specified.
1690*906afcb8SAndy FiddamanThe digits are represented by the characters
1691*906afcb8SAndy Fiddaman.BR 0-9a-zA-Z_@ .
1692*906afcb8SAndy FiddamanFor bases less than or equal to 36,
1693*906afcb8SAndy Fiddamanupper and lower case characters can
1694*906afcb8SAndy Fiddamanbe used interchangeably to represent the digits
1695*906afcb8SAndy Fiddamanfrom 10 thru 35.
1696*906afcb8SAndy Fiddaman.P
1697*906afcb8SAndy FiddamanArithmetic expressions are made from constants,
1698*906afcb8SAndy Fiddamanvariables, and operators.
1699*906afcb8SAndy FiddamanParentheses may be used for grouping.
1700*906afcb8SAndy FiddamanThe contents inside the double parentheses
1701*906afcb8SAndy Fiddamanare processed with the same expansions as occurs in a double quoted string,
1702*906afcb8SAndy Fiddamanso that all
1703*906afcb8SAndy Fiddaman.B $
1704*906afcb8SAndy Fiddamanexpansions are performed before the expression is evaluated.
1705*906afcb8SAndy FiddamanHowever, there is usually no need to use the
1706*906afcb8SAndy Fiddaman.B $
1707*906afcb8SAndy Fiddamanto get the value of a variable
1708*906afcb8SAndy Fiddamanbecause the arithmetic evaluator replaces the name of the variable
1709*906afcb8SAndy Fiddamanby its value within an arithmetic expression.
1710*906afcb8SAndy FiddamanThe
1711*906afcb8SAndy Fiddaman.B $
1712*906afcb8SAndy Fiddamancannot be used when the variable is the subject of assignment
1713*906afcb8SAndy Fiddamanor an increment operation.
1714*906afcb8SAndy FiddamanAs a rule it is better not to use
1715*906afcb8SAndy Fiddaman.B $
1716*906afcb8SAndy Fiddamanin front of variables in an arithmetic expression.
1717*906afcb8SAndy Fiddaman.P
1718*906afcb8SAndy FiddamanAn arithmetic command of the form
1719*906afcb8SAndy Fiddaman.B
1720*906afcb8SAndy Fiddaman(( ... ))
1721*906afcb8SAndy Fiddaman.R
1722*906afcb8SAndy Fiddamanis a command that evaluates the enclosed arithmetic expression.
1723*906afcb8SAndy FiddamanFor example, the command
1724*906afcb8SAndy Fiddaman.ce
1725*906afcb8SAndy Fiddaman\f5(( x++ ))\fP
1726*906afcb8SAndy Fiddamancan be used to
1727*906afcb8SAndy Fiddamanincrement the variable \f5x\fP,
1728*906afcb8SAndy Fiddamanassuming that \f5x\fP contains some numerical value.
1729*906afcb8SAndy FiddamanThe arithmetic command is true (return value 0), when the resulting
1730*906afcb8SAndy Fiddamanexpression is non-zero, and false (return value 1) when the
1731*906afcb8SAndy Fiddamanexpression evaluates to zero.
1732*906afcb8SAndy FiddamanThis makes the command easy to use with the \f5if\fP and \f5while\fP
1733*906afcb8SAndy Fiddamancompound commands.
1734*906afcb8SAndy Fiddaman.P
1735*906afcb8SAndy FiddamanThe \f5for\fP compound command
1736*906afcb8SAndy Fiddamanhas been extended for use in arithmetic contexts.
1737*906afcb8SAndy FiddamanThe syntax,
1738*906afcb8SAndy Fiddaman.ce
1739*906afcb8SAndy Fiddaman\f5for\fP \fB((\fP \fIexpr1\fP\fB;\fP \fIexpr2\fP \fB;\fP \fIexpr3 \fP\fB))\fP
1740*906afcb8SAndy Fiddamancan be used as the first line of a \f5for\fP loop with the same semantics
1741*906afcb8SAndy Fiddamanas the \f5for\fP statement in the ANSI-C programming language.
1742*906afcb8SAndy Fiddaman.P
1743*906afcb8SAndy FiddamanArithmetic evaluations can also be performed as part of the evaluation
1744*906afcb8SAndy Fiddamanof a command line.
1745*906afcb8SAndy FiddamanThe syntax
1746*906afcb8SAndy Fiddaman.B
1747*906afcb8SAndy Fiddaman$((\ ...\ ))
1748*906afcb8SAndy Fiddaman.R
1749*906afcb8SAndy Fiddamanexpands to the value of the enclosed arithmetic expression.
1750*906afcb8SAndy FiddamanThis expansion can occur wherever parameter expansion is performed.
1751*906afcb8SAndy FiddamanFor example using the \f5ksh\fP command \f5print\fP (described
1752*906afcb8SAndy Fiddamanlater)
1753*906afcb8SAndy Fiddaman.ce
1754*906afcb8SAndy Fiddaman\f5print $((2+2))\fP
1755*906afcb8SAndy Fiddamanprints the number 4.
1756*906afcb8SAndy Fiddaman.P
1757*906afcb8SAndy FiddamanThe following script prints the first
1758*906afcb8SAndy Fiddaman.I n
1759*906afcb8SAndy Fiddamanlines of its standard input onto its standard output,
1760*906afcb8SAndy Fiddamanwhere
1761*906afcb8SAndy Fiddaman.I n
1762*906afcb8SAndy Fiddamancan be supplied as an optional argument whose default value is 20.
1763*906afcb8SAndy Fiddaman.sp
1764*906afcb8SAndy Fiddaman.nf
1765*906afcb8SAndy Fiddaman.in .5i
1766*906afcb8SAndy Fiddaman.ta 4i
1767*906afcb8SAndy Fiddaman\f5integer n=${1-20}                       # set n
1768*906afcb8SAndy Fiddamanwhile   (( n-- >=0 )) && read -r line   # at most n lines
1769*906afcb8SAndy Fiddamando      print -r -- "$line"
1770*906afcb8SAndy Fiddamandone\fP
1771*906afcb8SAndy Fiddaman.fi
1772*906afcb8SAndy Fiddaman.ta
1773*906afcb8SAndy Fiddaman.in
1774*906afcb8SAndy Fiddaman.sp
1775*906afcb8SAndy Fiddaman.H 2 "Shell Expansions"
1776*906afcb8SAndy Fiddaman.P
1777*906afcb8SAndy FiddamanThe commands you enter from the terminal or from a script
1778*906afcb8SAndy Fiddamanare divided into words and each word undergoes several
1779*906afcb8SAndy Fiddamanexpansions to generate the command name and its arguments.
1780*906afcb8SAndy FiddamanThis is done in two phases.
1781*906afcb8SAndy FiddamanThe first phase recognizes reserved words, spaces and operators
1782*906afcb8SAndy Fiddamanto decide where command boundaries lie.
1783*906afcb8SAndy FiddamanAlias substitutions take place during this phase.
1784*906afcb8SAndy FiddamanThe second phase performs expansions in the following order:
1785*906afcb8SAndy Fiddaman.BL
1786*906afcb8SAndy Fiddaman.LI
1787*906afcb8SAndy FiddamanTilde substitution,
1788*906afcb8SAndy Fiddamanparameter expansion,
1789*906afcb8SAndy Fiddamanarithmetic expansion,
1790*906afcb8SAndy Fiddamanand command substitution
1791*906afcb8SAndy Fiddamanare performed from left to right.
1792*906afcb8SAndy FiddamanThe option
1793*906afcb8SAndy Fiddaman.B \-u
1794*906afcb8SAndy Fiddamanor
1795*906afcb8SAndy Fiddaman.BR nounset ,
1796*906afcb8SAndy Fiddamanwill cause an error to occur when any variable
1797*906afcb8SAndy Fiddamanthat is not set is expanded.
1798*906afcb8SAndy Fiddaman.LI
1799*906afcb8SAndy FiddamanThe characters that result from parameter expansion and
1800*906afcb8SAndy Fiddamancommand substitution above are checked with the characters
1801*906afcb8SAndy Fiddamanin the
1802*906afcb8SAndy Fiddaman\fB\s-1IFS\s+1\fP variable
1803*906afcb8SAndy Fiddamanfor possible
1804*906afcb8SAndy Fiddamanfield splitting.
1805*906afcb8SAndy Fiddaman(See a description of \f5read\fP below to see how
1806*906afcb8SAndy Fiddaman\fB\s-1IFS\s+1\fP is used.)
1807*906afcb8SAndy FiddamanSetting
1808*906afcb8SAndy Fiddaman\fB\s-1IFS\s+1\fP to a null
1809*906afcb8SAndy Fiddamanvalue causes field splitting to be skipped.
1810*906afcb8SAndy Fiddaman.LI
1811*906afcb8SAndy FiddamanPathname generation (as described below)
1812*906afcb8SAndy Fiddamanis performed on each of the fields.
1813*906afcb8SAndy FiddamanAny field that doesn't match a pathname is left alone.
1814*906afcb8SAndy FiddamanThe option,
1815*906afcb8SAndy Fiddaman.B \-f
1816*906afcb8SAndy Fiddamanor
1817*906afcb8SAndy Fiddaman.BR noglob ,
1818*906afcb8SAndy Fiddamanis used to disable pathname generation.
1819*906afcb8SAndy Fiddaman.LE
1820*906afcb8SAndy Fiddaman.H 2 "Pattern Matching"
1821*906afcb8SAndy FiddamanThe shell is primarily a string processing language and uses
1822*906afcb8SAndy Fiddamanpatterns for matching file names as well as for matching strings.
1823*906afcb8SAndy FiddamanThe characters
1824*906afcb8SAndy Fiddaman.BR ? ,
1825*906afcb8SAndy Fiddaman.BR * ,
1826*906afcb8SAndy Fiddamanand
1827*906afcb8SAndy Fiddaman.B [
1828*906afcb8SAndy Fiddamanare processed specially
1829*906afcb8SAndy Fiddamanby the shell when not quoted.
1830*906afcb8SAndy FiddamanThese characters are used to form patterns that
1831*906afcb8SAndy Fiddamanmatch strings.
1832*906afcb8SAndy FiddamanPatterns are used by the shell to match pathnames,
1833*906afcb8SAndy Fiddamanto specify substrings,
1834*906afcb8SAndy Fiddamanand for
1835*906afcb8SAndy Fiddaman.B case
1836*906afcb8SAndy Fiddamancommands.
1837*906afcb8SAndy FiddamanThe character
1838*906afcb8SAndy Fiddaman.B ?
1839*906afcb8SAndy Fiddamanmatches any one character.
1840*906afcb8SAndy FiddamanThe character
1841*906afcb8SAndy Fiddaman.B *
1842*906afcb8SAndy Fiddamanmatches zero or more characters.
1843*906afcb8SAndy FiddamanThe character sequence
1844*906afcb8SAndy Fiddaman.BR [ ... ]
1845*906afcb8SAndy Fiddamandefines a character class
1846*906afcb8SAndy Fiddamanthat matches any character contained within
1847*906afcb8SAndy Fiddaman.BR [\^] .
1848*906afcb8SAndy FiddamanA range of characters can be specified by putting a
1849*906afcb8SAndy Fiddaman.B \-
1850*906afcb8SAndy Fiddamanbetween the first and last character of the range.
1851*906afcb8SAndy FiddamanAn exclamation mark,
1852*906afcb8SAndy Fiddaman.BR ! ,
1853*906afcb8SAndy Fiddamanimmediately after the
1854*906afcb8SAndy Fiddaman.BR [ ,
1855*906afcb8SAndy Fiddamanmeans match all characters except the characters specified.
1856*906afcb8SAndy FiddamanFor example, the pattern
1857*906afcb8SAndy Fiddaman\f5a?c*.[!a-z]\fP
1858*906afcb8SAndy Fiddamanmatches any string beginning with an
1859*906afcb8SAndy Fiddaman.BR a ,
1860*906afcb8SAndy Fiddamanwhose third character is a
1861*906afcb8SAndy Fiddaman.BR c ,
1862*906afcb8SAndy Fiddamanand that ends in
1863*906afcb8SAndy Fiddaman.B .
1864*906afcb8SAndy Fiddaman(dot) followed by any character except the lower case letters,
1865*906afcb8SAndy Fiddaman.BR a\-z .
1866*906afcb8SAndy FiddamanThe sequence \f5[:alpha:]\fP
1867*906afcb8SAndy Fiddamaninside a character class, matches any set of characters in
1868*906afcb8SAndy Fiddamanthe ANSI-C
1869*906afcb8SAndy Fiddaman.B alpha
1870*906afcb8SAndy Fiddamanclass.
1871*906afcb8SAndy FiddamanSimilarly, \f5[:\fP\fIclass\fP\f5:]\fP matches
1872*906afcb8SAndy Fiddamaneach of the characters in the given \fIclass\fP
1873*906afcb8SAndy Fiddamanfor all the ANSI-C character classes.
1874*906afcb8SAndy FiddamanFor example, \f5[[:alnum:]_]\fP
1875*906afcb8SAndy Fiddamanmatches any alpha-numeric character or the character
1876*906afcb8SAndy Fiddaman.BR _ .
1877*906afcb8SAndy Fiddaman.P
1878*906afcb8SAndy Fiddaman\f5ksh\fP
1879*906afcb8SAndy Fiddamantreats
1880*906afcb8SAndy Fiddamanstrings of the form
1881*906afcb8SAndy Fiddaman.BI ( pattern-list
1882*906afcb8SAndy Fiddaman.BR ) ,
1883*906afcb8SAndy Fiddamanwhere
1884*906afcb8SAndy Fiddaman.I pattern-list
1885*906afcb8SAndy Fiddamanis a list of one or more patterns separated by a
1886*906afcb8SAndy Fiddaman.BR \(bv ,
1887*906afcb8SAndy Fiddamanspecially when preceded by
1888*906afcb8SAndy Fiddaman.BR * ,
1889*906afcb8SAndy Fiddaman.BR ? ,
1890*906afcb8SAndy Fiddaman.BR + ,
1891*906afcb8SAndy Fiddaman.BR @ ,
1892*906afcb8SAndy Fiddamanor
1893*906afcb8SAndy Fiddaman.BR ! .
1894*906afcb8SAndy FiddamanA
1895*906afcb8SAndy Fiddaman.B ?
1896*906afcb8SAndy Fiddamanpreceding
1897*906afcb8SAndy Fiddaman.BI ( pattern-list )
1898*906afcb8SAndy Fiddamanmeans that the pattern list enclosed in
1899*906afcb8SAndy Fiddaman.B (\^)
1900*906afcb8SAndy Fiddamanis optional.
1901*906afcb8SAndy FiddamanAn
1902*906afcb8SAndy Fiddaman.BI @( pattern-list )
1903*906afcb8SAndy Fiddamanmatches any pattern in the list of patterns enclosed in
1904*906afcb8SAndy Fiddaman.BR () .
1905*906afcb8SAndy FiddamanA
1906*906afcb8SAndy Fiddaman.BI *( pattern-list )
1907*906afcb8SAndy Fiddamanmatches any string that contains zero or more of each of the enclosed
1908*906afcb8SAndy Fiddamanpatterns,
1909*906afcb8SAndy Fiddamanwhereas
1910*906afcb8SAndy Fiddaman.BI +( pattern-list )
1911*906afcb8SAndy Fiddamanrequires a match of one or more of any of the given patterns.
1912*906afcb8SAndy FiddamanFor instance, the pattern
1913*906afcb8SAndy Fiddaman.B +([0\-9])?(.)
1914*906afcb8SAndy Fiddamanmatches one or more digits optionally followed by a
1915*906afcb8SAndy Fiddaman.BR . (dot).
1916*906afcb8SAndy FiddamanA
1917*906afcb8SAndy Fiddaman.BI !( pattern-list )
1918*906afcb8SAndy Fiddamanmatches anything except any of the given patterns.
1919*906afcb8SAndy FiddamanFor example,
1920*906afcb8SAndy Fiddaman\f5print\ !(*.o)\fP
1921*906afcb8SAndy Fiddamandisplays all file names in the current directory that do not end in
1922*906afcb8SAndy Fiddaman.BR .o .
1923*906afcb8SAndy Fiddaman.P
1924*906afcb8SAndy FiddamanWhen patterns are used to generate pathnames when expanding
1925*906afcb8SAndy Fiddamancommands several other rules apply.
1926*906afcb8SAndy FiddamanA separate match is made
1927*906afcb8SAndy Fiddamanfor each file name component of the pathname.
1928*906afcb8SAndy FiddamanRead permission is required for
1929*906afcb8SAndy Fiddamanany portion of the pathname that contains any special
1930*906afcb8SAndy Fiddamanpattern character.
1931*906afcb8SAndy FiddamanSearch permission is required for every component except
1932*906afcb8SAndy Fiddamanpossibly the last.
1933*906afcb8SAndy Fiddaman.P
1934*906afcb8SAndy FiddamanBy default,
1935*906afcb8SAndy Fiddamanfile names in each directory that begin with \fB\s+2.\s-2\fP
1936*906afcb8SAndy Fiddamanare skipped when performing a match.
1937*906afcb8SAndy FiddamanIf the pattern to be matched starts with a leading \fB\s+2.\s-2\fP,
1938*906afcb8SAndy Fiddamanthen only files beginning with a \fB\s+2.\s-2\fP,
1939*906afcb8SAndy Fiddamanare examined when reading each directory to find matching files.
1940*906afcb8SAndy FiddamanIf the
1941*906afcb8SAndy Fiddaman\fB\s-1FIGNORE\s+1\fP variable
1942*906afcb8SAndy Fiddamanis set,
1943*906afcb8SAndy Fiddamanthen only files that do not match this pattern
1944*906afcb8SAndy Fiddamanare considered.
1945*906afcb8SAndy FiddamanThis overrides the special meaning of \fB\s+2.\s-2\fP
1946*906afcb8SAndy Fiddamanin a pattern and in a file name.
1947*906afcb8SAndy Fiddaman.P
1948*906afcb8SAndy FiddamanIf the
1949*906afcb8SAndy Fiddaman.B markdirs
1950*906afcb8SAndy Fiddamanoption is set,
1951*906afcb8SAndy Fiddamaneach matching pathname that is the name
1952*906afcb8SAndy Fiddamanof a directory has a trailing
1953*906afcb8SAndy Fiddaman.B /
1954*906afcb8SAndy Fiddamanappended to the name.
1955*906afcb8SAndy Fiddaman.P
1956*906afcb8SAndy Fiddaman.H 2 "Conditional Expressions"
1957*906afcb8SAndy FiddamanThe Bourne shell uses the \f5test\fP
1958*906afcb8SAndy Fiddamancommand, or the equivalent \f5[\fP
1959*906afcb8SAndy Fiddamancommand, to test files for attributes
1960*906afcb8SAndy Fiddamanand to compare strings or numbers.
1961*906afcb8SAndy FiddamanThe problem with \f5test\fP
1962*906afcb8SAndy Fiddamanis that the shell has expanded the words of the \f5test\fP
1963*906afcb8SAndy Fiddamancommand and
1964*906afcb8SAndy Fiddamansplit them into arguments before \f5test\fP begins execution.
1965*906afcb8SAndy Fiddaman\f5test\fP
1966*906afcb8SAndy Fiddamancannot distinguish between operators and operands.
1967*906afcb8SAndy FiddamanIn most cases
1968*906afcb8SAndy Fiddaman\f5test\ "$1"\fP
1969*906afcb8SAndy Fiddamanwill test whether argument 1 is non-null.
1970*906afcb8SAndy FiddamanHowever,
1971*906afcb8SAndy Fiddamanif argument 1 is
1972*906afcb8SAndy Fiddaman.BR \-f ,
1973*906afcb8SAndy Fiddamanthen \f5test\fP
1974*906afcb8SAndy Fiddamanwill treat
1975*906afcb8SAndy Fiddaman.B \-f
1976*906afcb8SAndy Fiddamanas an operator and
1977*906afcb8SAndy Fiddamanyield a syntax error.
1978*906afcb8SAndy FiddamanOne of the most frequent errors with
1979*906afcb8SAndy Fiddaman\f5test\fP
1980*906afcb8SAndy Fiddamanoccurs when its operands are not within double quotes.
1981*906afcb8SAndy FiddamanIn this case, the argument may expand to more than a single
1982*906afcb8SAndy Fiddamanargument or to no argument at all.  In either case this
1983*906afcb8SAndy Fiddamanwill likely cause a syntax error.
1984*906afcb8SAndy FiddamanWhat makes this most insidious is that these errors are frequently
1985*906afcb8SAndy Fiddamandata dependent.  A script that appears to run correctly may abort
1986*906afcb8SAndy Fiddamanif given unexpected data.
1987*906afcb8SAndy Fiddaman.P
1988*906afcb8SAndy FiddamanTo get around these problems,
1989*906afcb8SAndy Fiddaman\f5ksh\fP
1990*906afcb8SAndy Fiddamanhas a compound command for conditional expression testing
1991*906afcb8SAndy Fiddamanas part of the language.
1992*906afcb8SAndy FiddamanThe reserved words
1993*906afcb8SAndy Fiddaman.B [[
1994*906afcb8SAndy Fiddamanand
1995*906afcb8SAndy Fiddaman.B ]]
1996*906afcb8SAndy Fiddamandelimit the range of the command.
1997*906afcb8SAndy FiddamanBecause they are reserved words, not operator characters,
1998*906afcb8SAndy Fiddamanthey require spaces to separate them
1999*906afcb8SAndy Fiddamanfrom arguments.
2000*906afcb8SAndy FiddamanThe words between
2001*906afcb8SAndy Fiddaman.B [[
2002*906afcb8SAndy Fiddamanand
2003*906afcb8SAndy Fiddaman.B ]]
2004*906afcb8SAndy Fiddamanare not processed for field splitting or for pathname generation.
2005*906afcb8SAndy FiddamanIn addition, since \f5ksh\fP
2006*906afcb8SAndy Fiddamandetermines the operators before parameter expansion,
2007*906afcb8SAndy Fiddamanexpansions that yield no argument cause no problem.
2008*906afcb8SAndy FiddamanThe operators within
2009*906afcb8SAndy Fiddaman.BR [[ ... ]]
2010*906afcb8SAndy Fiddamanare almost the same as those for the \f5test\fP
2011*906afcb8SAndy Fiddamancommand.
2012*906afcb8SAndy FiddamanAll unary operators are of the form
2013*906afcb8SAndy Fiddaman.BI \- letter
2014*906afcb8SAndy Fiddamanand are followed by a single operand.
2015*906afcb8SAndy FiddamanInstead of
2016*906afcb8SAndy Fiddaman.B \-a
2017*906afcb8SAndy Fiddamanand
2018*906afcb8SAndy Fiddaman.BR \-o ,
2019*906afcb8SAndy Fiddaman.BR [[ ... ]]
2020*906afcb8SAndy Fiddamanuses
2021*906afcb8SAndy Fiddaman.B &&
2022*906afcb8SAndy Fiddamanand
2023*906afcb8SAndy Fiddaman.B \(bv\(bv
2024*906afcb8SAndy Fiddamanto indicate "and" and "or".
2025*906afcb8SAndy FiddamanParentheses are used without quoting for grouping.
2026*906afcb8SAndy Fiddaman.P
2027*906afcb8SAndy FiddamanThe right hand side of the string comparison operators
2028*906afcb8SAndy Fiddaman.B ==
2029*906afcb8SAndy Fiddamanand
2030*906afcb8SAndy Fiddaman.B !=
2031*906afcb8SAndy Fiddamantakes a pattern and tests whether the left hand operand
2032*906afcb8SAndy Fiddamanmatches this pattern.  Quoting the pattern results
2033*906afcb8SAndy Fiddamanis a string comparison rather than the pattern match.
2034*906afcb8SAndy FiddamanThe operators
2035*906afcb8SAndy Fiddaman.B <
2036*906afcb8SAndy Fiddamanand
2037*906afcb8SAndy Fiddaman.B >
2038*906afcb8SAndy Fiddamanwithin
2039*906afcb8SAndy Fiddaman.BR [[ ... ]]
2040*906afcb8SAndy Fiddamandesignate lexicographical comparison.
2041*906afcb8SAndy Fiddaman.P
2042*906afcb8SAndy FiddamanIn addition there are several other new comparison primitives.
2043*906afcb8SAndy FiddamanThe binary operators
2044*906afcb8SAndy Fiddaman.B \-ot
2045*906afcb8SAndy Fiddamanand
2046*906afcb8SAndy Fiddaman.B \-nt
2047*906afcb8SAndy Fiddamancompare the modification times
2048*906afcb8SAndy Fiddamanof two files to see which file is
2049*906afcb8SAndy Fiddaman.I "older than"
2050*906afcb8SAndy Fiddamanor
2051*906afcb8SAndy Fiddaman.I "newer than"
2052*906afcb8SAndy Fiddamanthe other.
2053*906afcb8SAndy FiddamanThe binary operator
2054*906afcb8SAndy Fiddaman.B \-ef
2055*906afcb8SAndy Fiddamantests whether two files
2056*906afcb8SAndy Fiddamanhave the same device and i-node number,
2057*906afcb8SAndy Fiddamani.\ e., a link to the same file.
2058*906afcb8SAndy Fiddaman.P
2059*906afcb8SAndy FiddamanThe unary operator
2060*906afcb8SAndy Fiddaman.B \-L
2061*906afcb8SAndy Fiddamanreturns true if its operand is a symbolic link.
2062*906afcb8SAndy FiddamanThe unary operator
2063*906afcb8SAndy Fiddaman.B \-O
2064*906afcb8SAndy Fiddaman(\fB\-G\fP)
2065*906afcb8SAndy Fiddamanreturns true if the owner (or group) of the file operand matches
2066*906afcb8SAndy Fiddamanthat of the caller.
2067*906afcb8SAndy FiddamanThe unary operator
2068*906afcb8SAndy Fiddaman.B \-o
2069*906afcb8SAndy Fiddamanreturns true when its operand is the name of an option that is
2070*906afcb8SAndy Fiddamancurrently on.
2071*906afcb8SAndy Fiddaman.P
2072*906afcb8SAndy FiddamanThe following script illustrates some of the uses of
2073*906afcb8SAndy Fiddaman.BR [[ ... ]] .
2074*906afcb8SAndy FiddamanThe reference manual contains the complete list of operators.
2075*906afcb8SAndy Fiddaman.sp
2076*906afcb8SAndy Fiddaman.nf
2077*906afcb8SAndy Fiddaman.in .5i
2078*906afcb8SAndy Fiddaman.ta 4i
2079*906afcb8SAndy Fiddaman\f5for i
2080*906afcb8SAndy Fiddamando      # execute foo for numeric directory
2081*906afcb8SAndy Fiddaman        if      [[ \-d $i && $i == +([0\-9]) ]]
2082*906afcb8SAndy Fiddaman        then    foo
2083*906afcb8SAndy Fiddaman        # otherwise if writable or executable file and not mine
2084*906afcb8SAndy Fiddaman        elif    [[ (\-w $i\(bv\(bv\-x $i) && ! \-O $i ]]
2085*906afcb8SAndy Fiddaman        then    bar
2086*906afcb8SAndy Fiddaman        fi
2087*906afcb8SAndy Fiddamandone\fP
2088*906afcb8SAndy Fiddaman.fi
2089*906afcb8SAndy Fiddaman.ta
2090*906afcb8SAndy Fiddaman.in
2091*906afcb8SAndy Fiddaman.sp
2092*906afcb8SAndy Fiddaman.H 2 "Input and Output"
2093*906afcb8SAndy Fiddaman\f5ksh\fP has
2094*906afcb8SAndy Fiddamanextended I/O capabilities to enhance the
2095*906afcb8SAndy Fiddamanuse of the shell as a programming language.
2096*906afcb8SAndy FiddamanAs with the Bourne shell,
2097*906afcb8SAndy Fiddamanyou use the I/O redirection operator,
2098*906afcb8SAndy Fiddaman.BR < ,
2099*906afcb8SAndy Fiddamanto control where input comes from,
2100*906afcb8SAndy Fiddamanand the I/O redirection operator,
2101*906afcb8SAndy Fiddaman.BR > ,
2102*906afcb8SAndy Fiddamanto control where output goes to.
2103*906afcb8SAndy FiddamanEach of these operators can be preceded with a single digit that
2104*906afcb8SAndy Fiddamanspecifies a file unit number to associate with the file stream.
2105*906afcb8SAndy FiddamanOrdinarily you specify these I/O redirection operators with a specific
2106*906afcb8SAndy Fiddamancommand to which it applies.
2107*906afcb8SAndy FiddamanHowever, if you specify I/O redirections with the \f5exec\fP
2108*906afcb8SAndy Fiddamancommand,
2109*906afcb8SAndy Fiddamanand don't specify arguments to \f5exec\fP,
2110*906afcb8SAndy Fiddamanthen the I/O redirection applies to the current program.
2111*906afcb8SAndy FiddamanFor example, the command
2112*906afcb8SAndy Fiddaman\f5exec\ <\ foobar\fP
2113*906afcb8SAndy Fiddamanopens file \f5foobar\fP
2114*906afcb8SAndy Fiddamanfor reading.
2115*906afcb8SAndy FiddamanThe \f5exec\fP
2116*906afcb8SAndy Fiddamancommand is also used to close files.
2117*906afcb8SAndy FiddamanA file descriptor unit can be opened as a copy of an existing
2118*906afcb8SAndy Fiddamanfile descriptor unit by using either of the
2119*906afcb8SAndy Fiddaman.B <&
2120*906afcb8SAndy Fiddamanor
2121*906afcb8SAndy Fiddaman.B >&
2122*906afcb8SAndy Fiddamanoperators and putting the file descriptor unit of the original file
2123*906afcb8SAndy Fiddamanafter the
2124*906afcb8SAndy Fiddaman.BR & .
2125*906afcb8SAndy FiddamanThus, \f52>&1\fP means open standard error (file descriptor 2)
2126*906afcb8SAndy Fiddamanas a copy of standard output (file descriptor 1).
2127*906afcb8SAndy FiddamanA file descriptor value of
2128*906afcb8SAndy Fiddaman.B \-
2129*906afcb8SAndy Fiddamanafter the
2130*906afcb8SAndy Fiddaman.B &
2131*906afcb8SAndy Fiddamanindicates that the file should be closed.
2132*906afcb8SAndy FiddamanTo close file unit 5, specify
2133*906afcb8SAndy Fiddaman\f5exec\ 5<&-\fP.
2134*906afcb8SAndy FiddamanThere are two additional redirection operators with \f5ksh\fP
2135*906afcb8SAndy Fiddamanand the POSIX shell that are not part of the Bourne shell.
2136*906afcb8SAndy FiddamanThe
2137*906afcb8SAndy Fiddaman.B >|
2138*906afcb8SAndy Fiddamanoperator overrides the effect of the
2139*906afcb8SAndy Fiddaman.B noclobber
2140*906afcb8SAndy Fiddamanoption described earlier.
2141*906afcb8SAndy FiddamanThe
2142*906afcb8SAndy Fiddaman.B <\^>
2143*906afcb8SAndy Fiddamanoperator causes a file to be opened for both reading and writing.
2144*906afcb8SAndy Fiddaman.P
2145*906afcb8SAndy Fiddaman\f5ksh\fP recognizes certain pathnames and treats them
2146*906afcb8SAndy Fiddamanspecially.
2147*906afcb8SAndy FiddamanPathnames of the form
2148*906afcb8SAndy Fiddaman.BI /dev/fd/ n\^
2149*906afcb8SAndy Fiddamanare treated as equivalent to the file defined by file descriptor
2150*906afcb8SAndy Fiddaman.IR n .
2151*906afcb8SAndy FiddamanThese name can be used as the script argument to \f5ksh\fP
2152*906afcb8SAndy Fiddamanand in conditional testing as described above.
2153*906afcb8SAndy FiddamanOn underlying systems that support
2154*906afcb8SAndy Fiddaman.B /dev/fd
2155*906afcb8SAndy Fiddamanin the file system, these names can be passed to other commands.
2156*906afcb8SAndy FiddamanPathnames of the form
2157*906afcb8SAndy Fiddaman.BI /dev/tcp/ hostid / port
2158*906afcb8SAndy Fiddamanand
2159*906afcb8SAndy Fiddaman.BI /dev/udp/ hostid / port
2160*906afcb8SAndy Fiddamancan be used to create
2161*906afcb8SAndy Fiddaman.B tcp
2162*906afcb8SAndy Fiddamanand
2163*906afcb8SAndy Fiddaman.B udp
2164*906afcb8SAndy Fiddamanconnections to services given by the
2165*906afcb8SAndy Fiddaman.I hostid\^
2166*906afcb8SAndy Fiddamannumber and
2167*906afcb8SAndy Fiddaman.I port\^
2168*906afcb8SAndy Fiddamannumber.
2169*906afcb8SAndy FiddamanThe
2170*906afcb8SAndy Fiddaman.I hostid\^
2171*906afcb8SAndy Fiddamancannot use symbolic values. In practice these
2172*906afcb8SAndy Fiddamannumbers are typically generated by command substitution.
2173*906afcb8SAndy FiddamanFor example,
2174*906afcb8SAndy Fiddaman\f5exec\ 5>\ /dev/tcp/$(service\ name)\fP
2175*906afcb8SAndy Fiddamanwould open file descriptor 5 for sending messages
2176*906afcb8SAndy Fiddamanto hostid and port number defined by the output of \f5service\ name\fP.
2177*906afcb8SAndy Fiddaman.P
2178*906afcb8SAndy FiddamanThe Bourne shell has a built-in command \f5read\fP
2179*906afcb8SAndy Fiddamanfor reading lines from standard input (file descriptor 0)
2180*906afcb8SAndy Fiddamanand splitting it into fields based on the value of the
2181*906afcb8SAndy Fiddaman.B \s-1IFS\s+1
2182*906afcb8SAndy Fiddamanvariable, and a command \f5echo\fP
2183*906afcb8SAndy Fiddamanto write strings to standard output.
2184*906afcb8SAndy Fiddaman(On some systems, \f5echo\fP
2185*906afcb8SAndy Fiddamanis not a built-in command and incurs considerable overhead to use.)
2186*906afcb8SAndy FiddamanUnfortunately, neither of these commands
2187*906afcb8SAndy Fiddamanis able to perform some very basic tasks.
2188*906afcb8SAndy FiddamanFor example.
2189*906afcb8SAndy Fiddamanwith the Bourne shell,
2190*906afcb8SAndy Fiddamanthe \f5read\fP
2191*906afcb8SAndy Fiddamanbuilt-in cannot read a single line that ends in
2192*906afcb8SAndy Fiddaman.BR \e .
2193*906afcb8SAndy FiddamanWith \f5ksh\fP
2194*906afcb8SAndy Fiddamanthe \f5read\fP
2195*906afcb8SAndy Fiddamanbuilt-in has a
2196*906afcb8SAndy Fiddaman.B \-r
2197*906afcb8SAndy Fiddamanoption to remove the special meaning for
2198*906afcb8SAndy Fiddaman.B \e
2199*906afcb8SAndy Fiddamanwhich allows it to be
2200*906afcb8SAndy Fiddamantreated as a regular
2201*906afcb8SAndy Fiddamancharacter rather than the line continuation character.
2202*906afcb8SAndy FiddamanWith the Bourne shell,
2203*906afcb8SAndy Fiddamanthere is no simple way to have more than one file open
2204*906afcb8SAndy Fiddamanat any time for reading.
2205*906afcb8SAndy Fiddaman\f5ksh\fP has options on the \f5read\fP
2206*906afcb8SAndy Fiddamancommand to specify the file
2207*906afcb8SAndy Fiddamandescriptor for the input.
2208*906afcb8SAndy FiddamanThe fields that are read from a line can be stored into an indexed
2209*906afcb8SAndy Fiddamanarray with the
2210*906afcb8SAndy Fiddaman.B \-A
2211*906afcb8SAndy Fiddamanoption to read.
2212*906afcb8SAndy FiddamanThis allows a line to be split into an arbitrary number of fields.
2213*906afcb8SAndy Fiddaman.P
2214*906afcb8SAndy FiddamanThe way the Bourne shell uses the
2215*906afcb8SAndy Fiddaman\fB\s-1IFS\s+1\fP variable to
2216*906afcb8SAndy Fiddamansplit lines into fields greatly limits its utility.
2217*906afcb8SAndy FiddamanOften data files consist of lines that use a character such
2218*906afcb8SAndy Fiddamanas
2219*906afcb8SAndy Fiddaman.B :
2220*906afcb8SAndy Fiddamanto delimit fields with two adjacent delimiters that denote
2221*906afcb8SAndy Fiddamana null field.
2222*906afcb8SAndy FiddamanThe Bourne shell treats adjacent delimiters as a single
2223*906afcb8SAndy Fiddamanfield delimiter.
2224*906afcb8SAndy FiddamanWith \f5ksh\fP,
2225*906afcb8SAndy Fiddamandelimiters that are considered white space characters
2226*906afcb8SAndy Fiddamanhave the behavior of the Bourne shell, but other
2227*906afcb8SAndy Fiddamanadjacent delimiters separate
2228*906afcb8SAndy Fiddamannull fields.
2229*906afcb8SAndy Fiddaman.P
2230*906afcb8SAndy FiddamanThe \f5read\fP command is often used in scripts that interact
2231*906afcb8SAndy Fiddamanwith the user by prompting the user and then requesting some
2232*906afcb8SAndy Fiddamaninput.
2233*906afcb8SAndy FiddamanWith the Bourne shell two commands are needed; one to
2234*906afcb8SAndy Fiddamanprompt the user, the other to read the reply.
2235*906afcb8SAndy Fiddaman\f5ksh\fP allows these two commands to be combined.
2236*906afcb8SAndy FiddamanThe first argument of the \f5read\fP
2237*906afcb8SAndy Fiddamancommand can be followed by a
2238*906afcb8SAndy Fiddaman.B ?
2239*906afcb8SAndy Fiddamanand a prompt string which is used whenever the input
2240*906afcb8SAndy Fiddamandevice is a terminal.
2241*906afcb8SAndy FiddamanBecause the prompt is associated with the \f5read\fP built-in,
2242*906afcb8SAndy Fiddamanthe built-in command line editors will be able to re-output
2243*906afcb8SAndy Fiddamanthe prompt whenever the line needs to be refreshed when
2244*906afcb8SAndy Fiddamanreading from a terminal device.
2245*906afcb8SAndy Fiddaman.P
2246*906afcb8SAndy FiddamanWith the Bourne shell,
2247*906afcb8SAndy Fiddamanthere is no way to set a time limit for waiting for the user
2248*906afcb8SAndy Fiddamanresponse to read.
2249*906afcb8SAndy FiddamanThe
2250*906afcb8SAndy Fiddaman.B \-t
2251*906afcb8SAndy Fiddamanoption to \f5read\fP takes a floating
2252*906afcb8SAndy Fiddamanpoint argument that gives the time in seconds,
2253*906afcb8SAndy Fiddamanor fractions of seconds that the shell should wait for a reply.
2254*906afcb8SAndy Fiddaman.P
2255*906afcb8SAndy FiddamanThe version of the \f5echo\fP command in System V
2256*906afcb8SAndy Fiddamantreats certain sequences beginning with
2257*906afcb8SAndy Fiddaman.B \e
2258*906afcb8SAndy Fiddamanas control sequences.
2259*906afcb8SAndy FiddamanThis makes it hard to output strings without interpretation.
2260*906afcb8SAndy FiddamanMost BSD derived systems do not interpret
2261*906afcb8SAndy Fiddaman.B \e
2262*906afcb8SAndy Fiddamancontrol sequences.
2263*906afcb8SAndy FiddamanUnfortunately, the BSD versions of \f5echo\fP accepts a
2264*906afcb8SAndy Fiddaman.B \-n
2265*906afcb8SAndy Fiddamanoption to prevent a trailing new-line, but has no way to
2266*906afcb8SAndy Fiddamancause the string
2267*906afcb8SAndy Fiddaman.B \-n
2268*906afcb8SAndy Fiddamanto be printed.
2269*906afcb8SAndy FiddamanNeither of these versions is adequate. Also, because they
2270*906afcb8SAndy Fiddamanare incompatible, it is very hard to write portable shell scripts
2271*906afcb8SAndy Fiddamanusing \f5echo\fP.
2272*906afcb8SAndy FiddamanThe \f5ksh\fP built-in, \f5print\fP,
2273*906afcb8SAndy Fiddamanoutputs characters to the terminal or to a file and
2274*906afcb8SAndy Fiddamansubsumes the functions of all versions of \f5echo\fP.
2275*906afcb8SAndy FiddamanOrdinarily, escape sequences in arguments beginning with
2276*906afcb8SAndy Fiddaman.B \e
2277*906afcb8SAndy Fiddamanare processed the same as for the System V \f5echo\fP command.
2278*906afcb8SAndy FiddamanHowever \f5print\fP follows the standard conventions for
2279*906afcb8SAndy Fiddamanoptions and has options that make \f5print\fP very versatile.
2280*906afcb8SAndy FiddamanThe
2281*906afcb8SAndy Fiddaman.B \-r
2282*906afcb8SAndy Fiddamanoption can be used to output the arguments without any special meaning.
2283*906afcb8SAndy FiddamanThe
2284*906afcb8SAndy Fiddaman.B \-n
2285*906afcb8SAndy Fiddamanoption can be used here to suppress the trailing new-line
2286*906afcb8SAndy Fiddamanthat is ordinarily appended.
2287*906afcb8SAndy FiddamanAs with \f5read\fP, it is possible to specify the file descriptor number
2288*906afcb8SAndy Fiddamanas an option to the command to avoid having to use
2289*906afcb8SAndy Fiddamanredirection operators with each occurrence of the command.
2290*906afcb8SAndy Fiddaman.P
2291*906afcb8SAndy FiddamanThe IEEE POSIX shell and utilities standard committee was unable
2292*906afcb8SAndy Fiddamanto reconcile the differences between the System V and BSD
2293*906afcb8SAndy Fiddamanversions of \f5echo\fP.
2294*906afcb8SAndy FiddamanThey introduced a new command named \f5printf\fP
2295*906afcb8SAndy Fiddamanwhich takes an ANSI-C format string and a list of options
2296*906afcb8SAndy Fiddamanand outputs the strings using the ANSI-C formatting rules.
2297*906afcb8SAndy FiddamanSince \f5ksh\fP is POSIX conforming, it accepts \f5printf\fP.
2298*906afcb8SAndy FiddamanHowever, there is a
2299*906afcb8SAndy Fiddaman.B \-f
2300*906afcb8SAndy Fiddamanoptions to \f5print\fP that can be used to specify
2301*906afcb8SAndy Fiddamana format string which processes the arguments the same way that
2302*906afcb8SAndy Fiddaman\f5printf\fP does.
2303*906afcb8SAndy Fiddaman.P
2304*906afcb8SAndy FiddamanThe format processing for \f5print\fP and \f5printf\fP has
2305*906afcb8SAndy Fiddamanbeen extended slightly.
2306*906afcb8SAndy FiddamanThere are three additional formatting directives.
2307*906afcb8SAndy FiddamanThe
2308*906afcb8SAndy Fiddaman.B %b
2309*906afcb8SAndy Fiddamanformat causes the
2310*906afcb8SAndy Fiddaman.B \e
2311*906afcb8SAndy Fiddamanescape sequences to be expanded as they are with the System V \f5echo\fP
2312*906afcb8SAndy Fiddamancommand.
2313*906afcb8SAndy FiddamanThe
2314*906afcb8SAndy Fiddaman.B %q
2315*906afcb8SAndy Fiddamanformat causes quotes to
2316*906afcb8SAndy Fiddamanbe placed on the output as required
2317*906afcb8SAndy Fiddamanso that it can be used as shell input.
2318*906afcb8SAndy FiddamanSpecial characters in the output of most \f5ksh\fP built-in commands
2319*906afcb8SAndy Fiddamanand in the output from an execution trace
2320*906afcb8SAndy Fiddamanare quoted in an equivalent fashion.
2321*906afcb8SAndy FiddamanThe
2322*906afcb8SAndy Fiddaman.B %P
2323*906afcb8SAndy Fiddamanformat causes an extended regular expression string to
2324*906afcb8SAndy Fiddamanbe converted into a shell pattern.
2325*906afcb8SAndy FiddamanThis is useful for writing shell applications that have
2326*906afcb8SAndy Fiddamanto accept regular expressions as input.
2327*906afcb8SAndy FiddamanFinally, the escape sequence
2328*906afcb8SAndy Fiddaman.B \e\^E
2329*906afcb8SAndy Fiddamanwhich expands to the terminal escape character (octal 033)
2330*906afcb8SAndy Fiddamanhas been added.
2331*906afcb8SAndy Fiddaman.P
2332*906afcb8SAndy FiddamanThe shell is frequently used as a programming language for
2333*906afcb8SAndy Fiddamaninteractive dialogues.
2334*906afcb8SAndy FiddamanThe
2335*906afcb8SAndy Fiddaman\f5select\fP
2336*906afcb8SAndy Fiddamanstatement has been added to the language
2337*906afcb8SAndy Fiddamanto make it easier to
2338*906afcb8SAndy Fiddamanpresent menu selection alternatives to the
2339*906afcb8SAndy Fiddamanuser and evaluate the reply.
2340*906afcb8SAndy FiddamanThe list of alternatives is numbered and put in columns.
2341*906afcb8SAndy FiddamanA user settable prompt,
2342*906afcb8SAndy Fiddaman\fB\s-1PS3\s+1\fP,
2343*906afcb8SAndy Fiddamanis issued and if the answer is
2344*906afcb8SAndy Fiddamana number corresponding to one of the alternatives,
2345*906afcb8SAndy Fiddamanthe select loop variable is set to this value.
2346*906afcb8SAndy FiddamanIn any case, the
2347*906afcb8SAndy Fiddaman.B \s-1REPLY\s+1
2348*906afcb8SAndy Fiddamanvariable is used to store the user entered reply.
2349*906afcb8SAndy FiddamanThe shell variables
2350*906afcb8SAndy Fiddaman.B \s-1LINES\s+1
2351*906afcb8SAndy Fiddamanand
2352*906afcb8SAndy Fiddaman.B \s-1COLUMNS\s+1
2353*906afcb8SAndy Fiddamanare used to control the layout of select lists.
2354*906afcb8SAndy Fiddaman.H 2 "Option Parsing"
2355*906afcb8SAndy FiddamanThe \f5getopts\fP built-in command can be used
2356*906afcb8SAndy Fiddamanto process command arguments in a manner consistent
2357*906afcb8SAndy Fiddamanwith the way \f5ksh\fP does for its own built-in commands.
2358*906afcb8SAndy Fiddaman.P
2359*906afcb8SAndy FiddamanThe \f5getopts\fP built-in allows users to specify options
2360*906afcb8SAndy Fiddamanas separate arguments or to group options that do not
2361*906afcb8SAndy Fiddamantake arguments together.  Options that require arguments
2362*906afcb8SAndy Fiddamando not require space to separate them from the option argument.
2363*906afcb8SAndy FiddamanThe
2364*906afcb8SAndy Fiddaman.B \s-1OPTARG\s+1
2365*906afcb8SAndy Fiddamanvariable stores the value of the option argument
2366*906afcb8SAndy Fiddamanafter finding a variable that takes an argument.
2367*906afcb8SAndy FiddamanThe
2368*906afcb8SAndy Fiddaman.B \s-1OPTIND\s+1
2369*906afcb8SAndy Fiddamanvariable holds the index of the current options argument.
2370*906afcb8SAndy FiddamanAfter processing options, the arguments should be
2371*906afcb8SAndy Fiddamanshifted by
2372*906afcb8SAndy Fiddaman.B \s-1OPTIND\s+1\-1
2373*906afcb8SAndy Fiddamanto make the
2374*906afcb8SAndy Fiddamanremaining arguments be \f5"$@"\fP.
2375*906afcb8SAndy Fiddaman.P
2376*906afcb8SAndy FiddamanThe \f5getopts\fP argument description allows additional
2377*906afcb8SAndy Fiddamaninformation to be specified along with the options
2378*906afcb8SAndy Fiddamanthat is used to generate \fIusage\fP messages for
2379*906afcb8SAndy Fiddamanincorrect arguments and for the option argument \fB\-?\fP.
2380*906afcb8SAndy FiddamanThe example in the APPENDIX uses \f5getopts\fP to process
2381*906afcb8SAndy Fiddamanits arguments.
2382*906afcb8SAndy Fiddaman.H 2 "Co-process"
2383*906afcb8SAndy Fiddaman\f5ksh\fP can spawn a
2384*906afcb8SAndy Fiddaman.I co-process
2385*906afcb8SAndy Fiddamanby adding a
2386*906afcb8SAndy Fiddaman.B "|&"
2387*906afcb8SAndy Fiddamanafter a command.
2388*906afcb8SAndy FiddamanThis process will be run with its standard input and its
2389*906afcb8SAndy Fiddamanstandard output connected to the shell.  The built-in command \f5print\fP
2390*906afcb8SAndy Fiddamanwith the
2391*906afcb8SAndy Fiddaman.B \-p
2392*906afcb8SAndy Fiddamanoption will write into the standard input of this
2393*906afcb8SAndy Fiddamanprocess and
2394*906afcb8SAndy Fiddamanthe built-in command \f5read\fP
2395*906afcb8SAndy Fiddamanwith the
2396*906afcb8SAndy Fiddaman.B \-p
2397*906afcb8SAndy Fiddamanoption will read from the output of this process.
2398*906afcb8SAndy Fiddaman.P
2399*906afcb8SAndy FiddamanIn addition, the I/O redirection operators \fB<&\fP and \fB>&\fP can
2400*906afcb8SAndy Fiddamanbe used to move the input or output pipe of the co-process
2401*906afcb8SAndy Fiddamanto a numbered file descriptor.
2402*906afcb8SAndy FiddamanUse \f5exec\ 3>&\ p\fP to move the input of the co-process
2403*906afcb8SAndy Fiddamanto file descriptor \fB3\fP.
2404*906afcb8SAndy FiddamanAfter you have connected to file descriptor \fB3\fP, you
2405*906afcb8SAndy Fiddamancan direct the output of any command to the co-process
2406*906afcb8SAndy Fiddamanby running \fIcommand\fP\f5\ >&3\fP.
2407*906afcb8SAndy FiddamanAlso, by moving the input of the co-process to a numbered descriptor,
2408*906afcb8SAndy Fiddamanit is possible to run a second co-process.
2409*906afcb8SAndy FiddamanThe output of both co-processes will be the file descriptor
2410*906afcb8SAndy Fiddamanassociated with \f5read\ -p\fP.
2411*906afcb8SAndy FiddamanYou can use \f5exec\ 4<&\ p\fP to cause the output of these
2412*906afcb8SAndy Fiddamanco-processes to go to file descriptor \fB4\fP of the shell.
2413*906afcb8SAndy FiddamanOnce you have moved the pipe to descriptor \fB4\fP, it is possible
2414*906afcb8SAndy Fiddamanto connect a server to the co-process by running \fIcommand\fP\f5\ 4<&\ p\fP
2415*906afcb8SAndy Fiddamanor to close the co-process pipe with \f5exec\ 4<&\ -\fP.
2416*906afcb8SAndy Fiddaman.H 2 "Functions"
2417*906afcb8SAndy Fiddaman.P
2418*906afcb8SAndy FiddamanFunction definitions are of the form
2419*906afcb8SAndy Fiddaman.sp
2420*906afcb8SAndy Fiddaman.in +.5i
2421*906afcb8SAndy Fiddaman.nf
2422*906afcb8SAndy Fiddaman\f5function\fP \fIname\fP
2423*906afcb8SAndy Fiddaman.br
2424*906afcb8SAndy Fiddaman.B {
2425*906afcb8SAndy Fiddaman.br
2426*906afcb8SAndy Fiddaman        any shell script
2427*906afcb8SAndy Fiddaman.br
2428*906afcb8SAndy Fiddaman.B }
2429*906afcb8SAndy Fiddaman.fi
2430*906afcb8SAndy Fiddaman.sp
2431*906afcb8SAndy Fiddaman.in
2432*906afcb8SAndy FiddamanA function whose name contains a \fB\s+2.\s-2\fP
2433*906afcb8SAndy Fiddamanis called a \fIdiscipline\fP function.
2434*906afcb8SAndy FiddamanThe portion of the name after the last \fB\s+2.\s-2\fP
2435*906afcb8SAndy Fiddamanis the name of the discipline.
2436*906afcb8SAndy FiddamanDiscipline functions named \f5get\fP, \f5set\fP, and \f5unset\fP
2437*906afcb8SAndy Fiddamancan be assigned to any variable to intercept lookups,
2438*906afcb8SAndy Fiddamanassignments and unsetting of the variable
2439*906afcb8SAndy Fiddamandefined by the portion of the name before the last \fB\s+2.\s-2\fP.
2440*906afcb8SAndy FiddamanApplications can create additional disciplines for variables
2441*906afcb8SAndy Fiddamanthat are created as part of user defined built-ins.
2442*906afcb8SAndy FiddamanThe portion of the name before the last \fB\s+2.\s-2\fP
2443*906afcb8SAndy Fiddamanmust refer to the name of an existing variable.
2444*906afcb8SAndy FiddamanThus, if \f5p\fP is a reference to \f5PATH\fP, then
2445*906afcb8SAndy Fiddamanthe function name \f5p.get\fP and \f5PATH.get\fP
2446*906afcb8SAndy Fiddamanrefer to the same function.
2447*906afcb8SAndy Fiddaman.P
2448*906afcb8SAndy FiddamanThe function is invoked either
2449*906afcb8SAndy Fiddamanby specifying
2450*906afcb8SAndy Fiddaman.I name
2451*906afcb8SAndy Fiddamanas the command name
2452*906afcb8SAndy Fiddamanand optionally following it with arguments
2453*906afcb8SAndy Fiddamanor by using it as an option to the \fB\s+2.\s-2\fP
2454*906afcb8SAndy Fiddamanbuilt-in command.
2455*906afcb8SAndy FiddamanPositional parameters are saved before each
2456*906afcb8SAndy Fiddamanfunction call and restored when completed.
2457*906afcb8SAndy FiddamanThe arguments that follow the function name on the calling
2458*906afcb8SAndy Fiddamanline become positional parameters inside the function.
2459*906afcb8SAndy FiddamanThe \f5return\fP
2460*906afcb8SAndy Fiddamanbuilt-in can be used to cause the function to return to
2461*906afcb8SAndy Fiddamanthe statement following
2462*906afcb8SAndy Fiddamanthe point of invocation.
2463*906afcb8SAndy Fiddaman.P
2464*906afcb8SAndy FiddamanFunctions can also be defined with the System V notation,
2465*906afcb8SAndy Fiddaman.sp
2466*906afcb8SAndy Fiddaman.in +.5i
2467*906afcb8SAndy Fiddaman.nf
2468*906afcb8SAndy Fiddaman\fIname\fP \f5()\fP
2469*906afcb8SAndy Fiddaman.br
2470*906afcb8SAndy Fiddaman.B {
2471*906afcb8SAndy Fiddaman.br
2472*906afcb8SAndy Fiddaman        any shell script
2473*906afcb8SAndy Fiddaman.br
2474*906afcb8SAndy Fiddaman.B }
2475*906afcb8SAndy Fiddaman.fi
2476*906afcb8SAndy Fiddaman.sp
2477*906afcb8SAndy Fiddaman.in
2478*906afcb8SAndy FiddamanFunctions defined with this syntax cannot be used as the first
2479*906afcb8SAndy Fiddamanargument to a \fB\s+2.\s-2\fP procedure.
2480*906afcb8SAndy Fiddaman\f5ksh\fP accepts this notation for compatibility only.
2481*906afcb8SAndy FiddamanThere is no need to use this notation when writing
2482*906afcb8SAndy Fiddaman\f5ksh\fP scripts.
2483*906afcb8SAndy Fiddaman.P
2484*906afcb8SAndy FiddamanFunctions defined with the \f5function\fP\ \fIname\fP syntax
2485*906afcb8SAndy Fiddamanand invoked by name
2486*906afcb8SAndy Fiddamanare executed in the current shell environment
2487*906afcb8SAndy Fiddamanand can share named variables with the calling program.
2488*906afcb8SAndy FiddamanOptions, other than execution trace
2489*906afcb8SAndy Fiddaman.BR \-x ,
2490*906afcb8SAndy Fiddamanset by the calling program are
2491*906afcb8SAndy Fiddamanpassed down to a function.
2492*906afcb8SAndy FiddamanThe options are
2493*906afcb8SAndy Fiddamannot shared with
2494*906afcb8SAndy Fiddamanthe function so that any options set within a function are
2495*906afcb8SAndy Fiddamanrestored when the function exits.
2496*906afcb8SAndy FiddamanTraps ignored by the caller are ignored within the function
2497*906afcb8SAndy Fiddamanand cannot be enabled.
2498*906afcb8SAndy FiddamanTraps caught by the calling program are reset to their
2499*906afcb8SAndy Fiddamandefault action within the function.
2500*906afcb8SAndy FiddamanIn most instances, the default action is
2501*906afcb8SAndy Fiddamanto cause the function to terminate.
2502*906afcb8SAndy FiddamanA trap on
2503*906afcb8SAndy Fiddaman\fB\s-1EXIT\s+1\fP
2504*906afcb8SAndy Fiddamandefined within a function executes after the function
2505*906afcb8SAndy Fiddamancompletes but
2506*906afcb8SAndy Fiddamanbefore the caller resumes.
2507*906afcb8SAndy FiddamanTherefore,
2508*906afcb8SAndy Fiddamanany variable assignments and
2509*906afcb8SAndy Fiddamanany options set as part of a trap action will be effective
2510*906afcb8SAndy Fiddamanafter the caller resumes.
2511*906afcb8SAndy Fiddaman.P
2512*906afcb8SAndy FiddamanBy default, variables are inherited by the function and shared
2513*906afcb8SAndy Fiddamanby the calling program.
2514*906afcb8SAndy FiddamanHowever,
2515*906afcb8SAndy Fiddamanfor functions defined with the \f5function\fP\ \fIname\fP syntax
2516*906afcb8SAndy Fiddamanthat are invoked by name,
2517*906afcb8SAndy Fiddamanenvironment substitutions preceding the function call
2518*906afcb8SAndy Fiddamanapply only to the scope of the function call.
2519*906afcb8SAndy FiddamanAlso, variables whose names do not contain a \fB\s+2.\s-2\fP
2520*906afcb8SAndy Fiddamanthat are defined with the \f5typeset\fP
2521*906afcb8SAndy Fiddamanbuilt-in command are local to the function that they are declared in.
2522*906afcb8SAndy FiddamanThus, for the function defined
2523*906afcb8SAndy Fiddaman.sp
2524*906afcb8SAndy Fiddaman.nf
2525*906afcb8SAndy Fiddaman.in .5i
2526*906afcb8SAndy Fiddaman\f5function  name
2527*906afcb8SAndy Fiddaman{
2528*906afcb8SAndy Fiddaman     typeset -i x=10
2529*906afcb8SAndy Fiddaman     let z=x+y
2530*906afcb8SAndy Fiddaman     print $z
2531*906afcb8SAndy Fiddaman}\fP
2532*906afcb8SAndy Fiddaman.fi
2533*906afcb8SAndy Fiddaman.ta
2534*906afcb8SAndy Fiddaman.in
2535*906afcb8SAndy Fiddaman.sp
2536*906afcb8SAndy Fiddamaninvoked as
2537*906afcb8SAndy Fiddaman\f5y=13\ name\fP,
2538*906afcb8SAndy Fiddaman\f5x\fP and \f5y\fP
2539*906afcb8SAndy Fiddamanare local variables with respect to the function
2540*906afcb8SAndy Fiddaman\f5name\fP
2541*906afcb8SAndy Fiddamanwhile
2542*906afcb8SAndy Fiddaman\f5z\fP
2543*906afcb8SAndy Fiddamanis global.
2544*906afcb8SAndy Fiddaman.P
2545*906afcb8SAndy FiddamanFunctions defined with the \fIname\fP\f5()\fP syntax,
2546*906afcb8SAndy Fiddamanand functions invoked as an argument to the \fB\s+2.\s-2\fP
2547*906afcb8SAndy Fiddamancommand,
2548*906afcb8SAndy Fiddamanshare everything other than positional parameters with the caller.
2549*906afcb8SAndy FiddamanAssignments that precede the call remain in effect after the
2550*906afcb8SAndy Fiddamanfunction completes.
2551*906afcb8SAndy Fiddaman.P
2552*906afcb8SAndy FiddamanAlias and function names are not passed down to shell scripts
2553*906afcb8SAndy Fiddamanor carried across separate
2554*906afcb8SAndy Fiddamaninvocations of \f5ksh\fP.
2555*906afcb8SAndy FiddamanThe
2556*906afcb8SAndy Fiddaman.B $\s-1FPATH\s+1
2557*906afcb8SAndy Fiddamanvariable gives a colon separated list of directories that
2558*906afcb8SAndy Fiddamanis searched for function definitions when trying to resolve
2559*906afcb8SAndy Fiddamanthe command name.
2560*906afcb8SAndy FiddamanWhenever a file name contained in
2561*906afcb8SAndy Fiddaman.B $\s-1FPATH\s+1
2562*906afcb8SAndy Fiddamanis found, the complete file is read and all functions
2563*906afcb8SAndy Fiddamancontained within become defined.
2564*906afcb8SAndy Fiddaman.P
2565*906afcb8SAndy FiddamanCalls that reference functions can be recursive.
2566*906afcb8SAndy FiddamanExcept for special built-ins,
2567*906afcb8SAndy Fiddamanfunction names take precedence over built-in names and names
2568*906afcb8SAndy Fiddamanof programs when used as command names.
2569*906afcb8SAndy FiddamanTo write a replacement function that invokes the command that
2570*906afcb8SAndy Fiddamanyou wish to replace,
2571*906afcb8SAndy Fiddamanyou can use the \f5command\fP built-in command.
2572*906afcb8SAndy FiddamanThe arguments to \f5command\fP are the name and arguments
2573*906afcb8SAndy Fiddamanof the program you want to execute.
2574*906afcb8SAndy FiddamanFor example to write a
2575*906afcb8SAndy Fiddaman.B cd
2576*906afcb8SAndy Fiddamanfunction which changes the directory and prints out the directory name,
2577*906afcb8SAndy Fiddamanyou can write
2578*906afcb8SAndy Fiddaman.sp
2579*906afcb8SAndy Fiddaman.nf
2580*906afcb8SAndy Fiddaman.in .5i
2581*906afcb8SAndy Fiddaman\f5function  cd
2582*906afcb8SAndy Fiddaman{
2583*906afcb8SAndy Fiddaman     if      command cd  "$@"
2584*906afcb8SAndy Fiddaman     then    print  -r -- $PWD
2585*906afcb8SAndy Fiddaman     fi
2586*906afcb8SAndy Fiddaman}\fP
2587*906afcb8SAndy Fiddaman.fi
2588*906afcb8SAndy Fiddaman.ta
2589*906afcb8SAndy Fiddaman.in
2590*906afcb8SAndy Fiddaman.sp
2591*906afcb8SAndy Fiddaman.P
2592*906afcb8SAndy FiddamanThe
2593*906afcb8SAndy Fiddaman\fB\s-1FPATH\s+1\fP
2594*906afcb8SAndy Fiddamanvariable is a colon separated list that \f5ksh\fP
2595*906afcb8SAndy Fiddamanuses to search for function definitions.
2596*906afcb8SAndy FiddamanWhen
2597*906afcb8SAndy Fiddaman\f5ksh\fP
2598*906afcb8SAndy Fiddamanencounters an autoload function,
2599*906afcb8SAndy Fiddamanit runs the
2600*906afcb8SAndy Fiddaman.B .
2601*906afcb8SAndy Fiddamancommand on the script containing the function,
2602*906afcb8SAndy Fiddamanand then executes the function.
2603*906afcb8SAndy Fiddaman.P
2604*906afcb8SAndy FiddamanFor interactive shells,
2605*906afcb8SAndy Fiddamanfunction definitions may also be placed in the
2606*906afcb8SAndy Fiddaman\fB\s-1ENV\s+1\fP
2607*906afcb8SAndy Fiddamanfile.
2608*906afcb8SAndy FiddamanHowever, this
2609*906afcb8SAndy Fiddamancauses the shell to take longer to begin executing.
2610*906afcb8SAndy Fiddaman.H 2 "Process Substitution"
2611*906afcb8SAndy Fiddaman.P
2612*906afcb8SAndy FiddamanThis feature is only available
2613*906afcb8SAndy Fiddamanon versions of the UNIX operating system which support the
2614*906afcb8SAndy Fiddaman.B /dev/fd
2615*906afcb8SAndy Fiddamandirectory for naming open files.
2616*906afcb8SAndy FiddamanEach command argument of the form
2617*906afcb8SAndy Fiddaman\fB<(\fP\fIlist\^\fP\fB)\fP
2618*906afcb8SAndy Fiddamanor
2619*906afcb8SAndy Fiddaman\fB>(\fP\fIlist\^\fP\fB)\fP
2620*906afcb8SAndy Fiddamanwill run process
2621*906afcb8SAndy Fiddaman.I list
2622*906afcb8SAndy Fiddamanasynchronously connected to some file in the
2623*906afcb8SAndy Fiddaman.B /dev/fd
2624*906afcb8SAndy Fiddamandirectory.
2625*906afcb8SAndy FiddamanThe name of this file will become the argument to the command.
2626*906afcb8SAndy FiddamanIf the form with
2627*906afcb8SAndy Fiddaman.B >
2628*906afcb8SAndy Fiddamanis selected then writing on this file will provide input for
2629*906afcb8SAndy Fiddaman.IR list .
2630*906afcb8SAndy FiddamanIf
2631*906afcb8SAndy Fiddaman.B <
2632*906afcb8SAndy Fiddamanis used,
2633*906afcb8SAndy Fiddamanthen the file passed as an argument will contain the output of the
2634*906afcb8SAndy Fiddaman.I list
2635*906afcb8SAndy Fiddamanprocess.
2636*906afcb8SAndy FiddamanFor example,
2637*906afcb8SAndy Fiddaman.sp
2638*906afcb8SAndy Fiddaman.nf
2639*906afcb8SAndy Fiddaman.in .5i
2640*906afcb8SAndy Fiddaman\f5paste  <(cut \-f1 \fP\fIfile1\fP\f5)  <(cut \-f2 \fP\fIfile2\fP\f5) | tee >(\fP\fIprocess1\fP\f5)  >(\fP\fIprocess2\fP\f5)\fP
2641*906afcb8SAndy Fiddaman.fi
2642*906afcb8SAndy Fiddaman.ta
2643*906afcb8SAndy Fiddaman.in
2644*906afcb8SAndy Fiddaman.sp
2645*906afcb8SAndy Fiddamanextracts
2646*906afcb8SAndy Fiddamanfields 1 and 3 from
2647*906afcb8SAndy Fiddamanthe files
2648*906afcb8SAndy Fiddaman.I file1
2649*906afcb8SAndy Fiddamanand
2650*906afcb8SAndy Fiddaman.I file2
2651*906afcb8SAndy Fiddamanrespectively,
2652*906afcb8SAndy Fiddamanplaces the
2653*906afcb8SAndy Fiddamanresults side by side, and
2654*906afcb8SAndy Fiddamansends it
2655*906afcb8SAndy Fiddamanto the processes
2656*906afcb8SAndy Fiddaman.I process1
2657*906afcb8SAndy Fiddamanand
2658*906afcb8SAndy Fiddaman.IR process2 ,
2659*906afcb8SAndy Fiddamanas well as putting it onto the standard output.
2660*906afcb8SAndy FiddamanNote that the file which is passed as an argument to the command is
2661*906afcb8SAndy Fiddamana UNIX system
2662*906afcb8SAndy Fiddaman.IR pipe (2)
2663*906afcb8SAndy Fiddamanso that the programs that expect to
2664*906afcb8SAndy Fiddaman.IR lseek (2)
2665*906afcb8SAndy Fiddamanon the file will not work.
2666*906afcb8SAndy Fiddaman.H 2 "Finding Commands"
2667*906afcb8SAndy Fiddaman.P
2668*906afcb8SAndy FiddamanThe addition of aliases, functions,
2669*906afcb8SAndy Fiddamanand more built-ins
2670*906afcb8SAndy Fiddamanhas made it substantially more difficult to know what
2671*906afcb8SAndy Fiddamana given command name really means.
2672*906afcb8SAndy Fiddaman.P
2673*906afcb8SAndy FiddamanCommands that begin with reserved words
2674*906afcb8SAndy Fiddamanare an integral part of the shell language itself
2675*906afcb8SAndy Fiddamanand typically define the control flow of the language.
2676*906afcb8SAndy FiddamanSome control flow commands are not reserved words in
2677*906afcb8SAndy Fiddamanthe language but are \fIspecial\fP built-ins.
2678*906afcb8SAndy FiddamanSpecial built-ins are built-ins that are considered a
2679*906afcb8SAndy Fiddamanpart of the language rather than user definable commands.
2680*906afcb8SAndy FiddamanThe best examples of commands that fit this description
2681*906afcb8SAndy Fiddamanare \f5break\fP and \f5continue\fP.
2682*906afcb8SAndy FiddamanBecause they are not reserved words, they can be the
2683*906afcb8SAndy Fiddamanresult of shell expansions and are not effected by quoting.
2684*906afcb8SAndy FiddamanThese commands have the following special properties:
2685*906afcb8SAndy Fiddaman.BL
2686*906afcb8SAndy Fiddaman.LI
2687*906afcb8SAndy FiddamanAssignments that precede them apply to the current shell process,
2688*906afcb8SAndy Fiddamannot just to the given command.
2689*906afcb8SAndy Fiddaman.LI
2690*906afcb8SAndy FiddamanAn error in the format of these commands cause a shell script
2691*906afcb8SAndy Fiddamanor function that contains them to abort.
2692*906afcb8SAndy Fiddaman.LI
2693*906afcb8SAndy FiddamanThey cannot be overridden by shell functions.
2694*906afcb8SAndy Fiddaman.LE
2695*906afcb8SAndy Fiddaman.P
2696*906afcb8SAndy FiddamanOther commands are built-in because they perform side effects
2697*906afcb8SAndy Fiddamanon the current environment that would be nearly impossible
2698*906afcb8SAndy Fiddamanto implement otherwise.
2699*906afcb8SAndy FiddamanBuilt-ins such as \f5cd\fP and \f5read\fP
2700*906afcb8SAndy Fiddamanare examples of such built-ins.
2701*906afcb8SAndy FiddamanThese built-ins are semantically equivalent to commands that
2702*906afcb8SAndy Fiddamanare not built-in except that they don't take a path search
2703*906afcb8SAndy Fiddamanto locate.
2704*906afcb8SAndy Fiddaman.P
2705*906afcb8SAndy FiddamanA third reason to have a command built-in is so that
2706*906afcb8SAndy Fiddamanit will be unaffected by the setting of the
2707*906afcb8SAndy Fiddaman.B \s-1PATH\s+1
2708*906afcb8SAndy Fiddamanvariable.
2709*906afcb8SAndy FiddamanThe \f5print\fP  command fits this category.
2710*906afcb8SAndy FiddamanScripts that use \f5print\fP will be portable
2711*906afcb8SAndy Fiddamanto all sites that run \f5ksh\fP.
2712*906afcb8SAndy Fiddaman.P
2713*906afcb8SAndy FiddamanThe final reason for having a command be a built-in is
2714*906afcb8SAndy Fiddamanfor performance.
2715*906afcb8SAndy FiddamanOn most systems it is more than an order of magnitude
2716*906afcb8SAndy Fiddamanfaster to initiate a command that is built-in than
2717*906afcb8SAndy Fiddamanto create a separate process to run the command.
2718*906afcb8SAndy FiddamanExamples that fit this category are \f5test\fP
2719*906afcb8SAndy Fiddamanand \f5pwd\fP.
2720*906afcb8SAndy Fiddaman.P
2721*906afcb8SAndy FiddamanGiven a command name \f5ksh\fP decides what it means using
2722*906afcb8SAndy Fiddamanthe following order:
2723*906afcb8SAndy Fiddaman.BL
2724*906afcb8SAndy Fiddaman.LI
2725*906afcb8SAndy FiddamanReserved words define commands that form part of the shell
2726*906afcb8SAndy Fiddamangrammar.
2727*906afcb8SAndy FiddamanThey cannot be quoted.
2728*906afcb8SAndy Fiddaman.LI
2729*906afcb8SAndy FiddamanAlias substitutions occur first as part of the reading of commands.
2730*906afcb8SAndy FiddamanUsing quotes in the command name will prevent alias substitutions.
2731*906afcb8SAndy Fiddaman.LI
2732*906afcb8SAndy FiddamanSpecial built-ins.
2733*906afcb8SAndy Fiddaman.LI
2734*906afcb8SAndy FiddamanFunctions.
2735*906afcb8SAndy Fiddaman.LI
2736*906afcb8SAndy FiddamanCommands that are built-in that are not associated with a pathname
2737*906afcb8SAndy Fiddamansuch as \f5cd\fP and \f5print\fP.
2738*906afcb8SAndy Fiddaman.LI
2739*906afcb8SAndy FiddamanIf the command name contains a
2740*906afcb8SAndy Fiddaman.BR / ,
2741*906afcb8SAndy Fiddamanthe program or script corresponding to the given name is executed.
2742*906afcb8SAndy Fiddaman.LI
2743*906afcb8SAndy FiddamanA path search locates the pathname corresponding to the command.
2744*906afcb8SAndy FiddamanIf the pathname where it is found matches the pathname associated
2745*906afcb8SAndy Fiddamanwith a built-in command, the built-in command is executed.
2746*906afcb8SAndy FiddamanIf the directory where the command is found is listed in the
2747*906afcb8SAndy Fiddaman.B \s-1FPATH\s+1
2748*906afcb8SAndy Fiddamanvariable, the file is read into the shell
2749*906afcb8SAndy Fiddamanlike a dot script, and a function by that name is invoked.
2750*906afcb8SAndy FiddamanOnce a pathname is found, \f5ksh\fP remembers its location
2751*906afcb8SAndy Fiddamanand only checks relative directories in \fB\s-1PATH\s+1\fP
2752*906afcb8SAndy Fiddamanthe next time the command name is used.
2753*906afcb8SAndy FiddamanAssigning a value to \fB\s-1PATH\s+1\fP
2754*906afcb8SAndy Fiddamancauses \f5ksh\fP to forget the location of all command names.
2755*906afcb8SAndy Fiddaman.LI
2756*906afcb8SAndy FiddamanThe
2757*906afcb8SAndy Fiddaman.B \s-1FPATH\s+1
2758*906afcb8SAndy Fiddamanvariable is searched and files found are treated as described above.
2759*906afcb8SAndy Fiddaman.LE
2760*906afcb8SAndy Fiddaman.P
2761*906afcb8SAndy FiddamanThe first argument of the \f5command\fP built-in, described earlier,
2762*906afcb8SAndy Fiddamanskips the checks for reserved words and for function definitions.
2763*906afcb8SAndy FiddamanIn all other ways, \f5command\fP behaves like a built-in
2764*906afcb8SAndy Fiddamanthat is not associated with a pathname.
2765*906afcb8SAndy FiddamanAs a result, if the first argument of \f5command\fP is
2766*906afcb8SAndy Fiddamana special built-in, the special properties of this built-in
2767*906afcb8SAndy Fiddamando not apply.
2768*906afcb8SAndy FiddamanFor example, whereas, \f5exec\ 3<\ foo\fP will cause a script containing
2769*906afcb8SAndy Fiddamanit to abort if the open fails, \f5command\ exec\ 3<\ foo\fP
2770*906afcb8SAndy Fiddamanresults in a non-zero exit status but does not abort the script.
2771*906afcb8SAndy Fiddaman.P
2772*906afcb8SAndy FiddamanYou can get a complete list of the special built-in commands
2773*906afcb8SAndy Fiddamanwith \f5builtin\ -s\fP.
2774*906afcb8SAndy FiddamanIn addition \f5builtin\fP without arguments gives a list of
2775*906afcb8SAndy Fiddamanthe current built-ins and the pathname that they are associated with.
2776*906afcb8SAndy FiddamanA built-in can be bound to another pathname by giving
2777*906afcb8SAndy Fiddamanthe pathname for the built-in.  The basename of this path must
2778*906afcb8SAndy Fiddamanbe the name of an existing built-in for this to succeed.
2779*906afcb8SAndy FiddamanSpecifying the name of the built-in without a pathname causes
2780*906afcb8SAndy Fiddamanthis built-in to be found before a path search.
2781*906afcb8SAndy FiddamanA built-in can be deleted  with the \fB\-d\fP option.
2782*906afcb8SAndy Fiddaman.P
2783*906afcb8SAndy FiddamanOn systems with run time loading of libraries, built-in commands
2784*906afcb8SAndy Fiddamancan be added with the \f5builtin\fP command.
2785*906afcb8SAndy FiddamanEach command that is to be built-in must be written as a
2786*906afcb8SAndy FiddamanC function whose name is of the form \f5b_\fP\fIname\fP, where
2787*906afcb8SAndy Fiddaman\fIname\fP is the name of the built-in that is to be added.
2788*906afcb8SAndy FiddamanThe function has the same argument calling convention as
2789*906afcb8SAndy Fiddaman\f5main\fP.  The lower eight bits of the return value become
2790*906afcb8SAndy Fiddamanthe exit status for this built-in.
2791*906afcb8SAndy FiddamanBuiltins are added by specifying the pathname of the library
2792*906afcb8SAndy Fiddamanas an argument to the \fB\-f\fP option of \f5builtin\fP.
2793*906afcb8SAndy Fiddaman.P
2794*906afcb8SAndy FiddamanThe built-in command,
2795*906afcb8SAndy Fiddaman\f5whence\fP,
2796*906afcb8SAndy Fiddamanwhen used with the
2797*906afcb8SAndy Fiddaman.B \-v
2798*906afcb8SAndy Fiddamanoption, tells how a given command is bound.
2799*906afcb8SAndy FiddamanA line is printed for each argument to \f5whence\fP
2800*906afcb8SAndy Fiddamantelling what would happen if this argument were used as a command name.
2801*906afcb8SAndy FiddamanIt reports on reserved words, aliases, built-ins, and
2802*906afcb8SAndy Fiddamanfunctions.
2803*906afcb8SAndy FiddamanIf the command is none of the above,
2804*906afcb8SAndy Fiddamanit follows the path search rules and prints the full path-name,
2805*906afcb8SAndy Fiddamanif any, otherwise it prints an error message.
2806*906afcb8SAndy Fiddaman.H 2 "Symbolic Names"
2807*906afcb8SAndy FiddamanTo avoid implementation dependencies, \f5ksh\fP
2808*906afcb8SAndy Fiddamanaccepts and generates symbolic names
2809*906afcb8SAndy Fiddamanfor built-ins that use numerical values in the Bourne shell.
2810*906afcb8SAndy FiddamanThe
2811*906afcb8SAndy Fiddaman.B \-S
2812*906afcb8SAndy Fiddamanoption of the
2813*906afcb8SAndy Fiddaman\f5umask\fP built-in command
2814*906afcb8SAndy Fiddamanaccepts and displays
2815*906afcb8SAndy Fiddamandefault file creation permissions
2816*906afcb8SAndy Fiddamansymbolically.
2817*906afcb8SAndy FiddamanIt uses the same symbolic notation as the \f5chmod\fP command.
2818*906afcb8SAndy Fiddaman.P
2819*906afcb8SAndy FiddamanThe \f5trap\fP and \f5kill\fP built-in commands
2820*906afcb8SAndy Fiddamanallows the signal names to be given symbolically.
2821*906afcb8SAndy FiddamanThe names of signals and traps
2822*906afcb8SAndy Fiddamancorresponding to signals are the same as the signal name with
2823*906afcb8SAndy Fiddamanthe
2824*906afcb8SAndy Fiddaman.B \s-1SIG\s+1
2825*906afcb8SAndy Fiddamanprefix removed.
2826*906afcb8SAndy FiddamanThe trap
2827*906afcb8SAndy Fiddaman.B 0
2828*906afcb8SAndy Fiddamanis named
2829*906afcb8SAndy Fiddaman\fB\s-1EXIT\s+1\fP.
2830*906afcb8SAndy Fiddaman.H 2 "Additional Variables"
2831*906afcb8SAndy FiddamanIn addition to the variables discussed earlier, \f5ksh\fP
2832*906afcb8SAndy Fiddamanhas other variables that it handles specially.
2833*906afcb8SAndy FiddamanThe variable \fB\s-1RANDOM\s+1\fP
2834*906afcb8SAndy Fiddamanproduces a random number in the range 0 to 32767 each time it is referenced.
2835*906afcb8SAndy FiddamanAssignment to this variable sets the seed for the
2836*906afcb8SAndy Fiddamanrandom number generator.
2837*906afcb8SAndy Fiddaman.P
2838*906afcb8SAndy FiddamanThe parameter \fB\s-1PPID\s+1\fP
2839*906afcb8SAndy Fiddamanis used to generate the process id of the process which invoked this shell.
2840*906afcb8SAndy Fiddaman.H 2 "Added Traps"
2841*906afcb8SAndy FiddamanA new trap named
2842*906afcb8SAndy Fiddaman\fB\s-1ERR\s+1\fP
2843*906afcb8SAndy Fiddamanhas been added.
2844*906afcb8SAndy FiddamanThis trap is invoked whenever the shell would exit if the
2845*906afcb8SAndy Fiddaman.B \-e
2846*906afcb8SAndy Fiddamanoption were set.
2847*906afcb8SAndy FiddamanThis trap is used by
2848*906afcb8SAndy FiddamanFourth Generation Make\*(Rf
2849*906afcb8SAndy Fiddaman.RS
2850*906afcb8SAndy FiddamanG. S. Fowler,
2851*906afcb8SAndy Fiddaman.I "The Fourth Generation Make,"
2852*906afcb8SAndy FiddamanProceedings of the Portland USENIX meeting, pp. 159-174, 1985.
2853*906afcb8SAndy Fiddaman.RF
2854*906afcb8SAndy Fiddamanwhich runs \f5ksh\fP
2855*906afcb8SAndy Fiddamanas a co-process.
2856*906afcb8SAndy Fiddaman.P
2857*906afcb8SAndy FiddamanA trap named
2858*906afcb8SAndy Fiddaman\fB\s-1DEBUG\s+1\fP
2859*906afcb8SAndy Fiddamangets executed after each command.
2860*906afcb8SAndy FiddamanThis trap can be used for debugging and other purposes.
2861*906afcb8SAndy Fiddaman.P
2862*906afcb8SAndy FiddamanThe
2863*906afcb8SAndy Fiddaman\fB\s-1KEYBD\s+1\fP
2864*906afcb8SAndy Fiddamantrap was described earlier.
2865*906afcb8SAndy Fiddaman.H 2 Debugging
2866*906afcb8SAndy FiddamanThe primary method for debugging Bourne shell scripts is to
2867*906afcb8SAndy Fiddamanuse the
2868*906afcb8SAndy Fiddaman.B \-x
2869*906afcb8SAndy Fiddamanoption to enable the execution trace.
2870*906afcb8SAndy FiddamanAfter all
2871*906afcb8SAndy Fiddamanthe expansions have been performed,
2872*906afcb8SAndy Fiddamanbut before each command is executed,
2873*906afcb8SAndy Fiddamanthe trace writes to standard error the name and arguments
2874*906afcb8SAndy Fiddamanof each command preceded by a
2875*906afcb8SAndy Fiddaman.BR + .
2876*906afcb8SAndy FiddamanWhile the trace is very useful, there is no way
2877*906afcb8SAndy Fiddamanto find out what line of source a given trace line
2878*906afcb8SAndy Fiddamancorresponds to.
2879*906afcb8SAndy FiddamanWith
2880*906afcb8SAndy Fiddaman\f5ksh\fP
2881*906afcb8SAndy Fiddamanthe
2882*906afcb8SAndy Fiddaman\fB\s-1PS4\s+1\fP
2883*906afcb8SAndy Fiddamanvariable
2884*906afcb8SAndy Fiddamanis evaluated for parameter expansion and
2885*906afcb8SAndy Fiddamanis displayed before each command,
2886*906afcb8SAndy Fiddamaninstead of the
2887*906afcb8SAndy Fiddaman.BR + .
2888*906afcb8SAndy Fiddaman.P
2889*906afcb8SAndy FiddamanThe
2890*906afcb8SAndy Fiddaman\fB\s-1LINENO\s+1\fP
2891*906afcb8SAndy Fiddamanvariable is set to the current line number relative to the
2892*906afcb8SAndy Fiddamanbeginning of the current script or function.
2893*906afcb8SAndy FiddamanIt is most useful as part of the
2894*906afcb8SAndy Fiddaman\fB\s-1PS4\s+1\fP
2895*906afcb8SAndy Fiddamanprompt.
2896*906afcb8SAndy Fiddaman.P
2897*906afcb8SAndy FiddamanThe
2898*906afcb8SAndy Fiddaman\fB\s-1DEBUG\s+1\fP
2899*906afcb8SAndy Fiddamantrap can be used to write a break point shell
2900*906afcb8SAndy Fiddamandebugger in \f5ksh\fP.
2901*906afcb8SAndy FiddamanAn example of such a debugger is \f5kshdb\fP.\*(Rf
2902*906afcb8SAndy Fiddaman.RS
2903*906afcb8SAndy FiddamanBill Rosenblatt,
2904*906afcb8SAndy Fiddaman.IR "Debugging Shell Scripts with \f5kshdb\fP" ,
2905*906afcb8SAndy FiddamanUnix World, Volume X, No. 5, 1993.
2906*906afcb8SAndy Fiddaman.RF
2907*906afcb8SAndy Fiddaman.H 2 "Timing Commands"
2908*906afcb8SAndy Fiddaman.P
2909*906afcb8SAndy FiddamanFinding the time it takes to execute commands
2910*906afcb8SAndy Fiddamanhas been a serious problem with the Bourne shell.
2911*906afcb8SAndy FiddamanSince the \f5time\fP command is not part of the
2912*906afcb8SAndy Fiddamanlanguage, it is necessary to write a script
2913*906afcb8SAndy Fiddamanin order to time a \f5for\fP or \f5while\fP loop.
2914*906afcb8SAndy FiddamanThe extra time in invoking the shell and processing
2915*906afcb8SAndy Fiddamanthe script is accumulated along with the time
2916*906afcb8SAndy Fiddamanto execute the script.
2917*906afcb8SAndy Fiddaman.P
2918*906afcb8SAndy FiddamanMore seriously, the Bourne shell does not give correct
2919*906afcb8SAndy Fiddamantimes for pipelines.
2920*906afcb8SAndy FiddamanThe reason for this is that the times for some members
2921*906afcb8SAndy Fiddamanof a pipeline are not counted when computing the time.
2922*906afcb8SAndy FiddamanAs an extreme example,
2923*906afcb8SAndy Fiddamanrunning \f5time\fP on the script
2924*906afcb8SAndy Fiddaman.ce
2925*906afcb8SAndy Fiddaman\f5cat < /dev/null | sort -u bigfile | wc\fP
2926*906afcb8SAndy Fiddamanwith the Bourne shell will show very little
2927*906afcb8SAndy Fiddamanuser and system time no matter how
2928*906afcb8SAndy Fiddamanlarge \f5bigfile\fP is.
2929*906afcb8SAndy Fiddaman.P
2930*906afcb8SAndy FiddamanTo correct these problems,
2931*906afcb8SAndy Fiddamana reserved word \f5time\fP
2932*906afcb8SAndy Fiddamanhas been added to replace
2933*906afcb8SAndy Fiddamanthe \f5time\fP
2934*906afcb8SAndy Fiddamancommand.
2935*906afcb8SAndy FiddamanAny function, command or pipeline can be preceded by this reserved word
2936*906afcb8SAndy Fiddamanto obtain information about the elapsed, user, and system times.
2937*906afcb8SAndy FiddamanSince I/O redirections bind to the command, not to
2938*906afcb8SAndy Fiddaman\f5time\fP,
2939*906afcb8SAndy Fiddamanparentheses should be used to redirect the timing information which
2940*906afcb8SAndy Fiddamanis normally printed on file descriptor 2.
2941*906afcb8SAndy Fiddaman.H 1 SECURITY
2942*906afcb8SAndy FiddamanThere are several documented problems associated with the security of
2943*906afcb8SAndy Fiddamanshell procedures\*(Rf.
2944*906afcb8SAndy Fiddaman.RS
2945*906afcb8SAndy FiddamanF. T. Grampp and R. H. Morris,
2946*906afcb8SAndy Fiddaman.I "UNIX Operating System Security,"
2947*906afcb8SAndy FiddamanAT&T Bell Labs Tech. Journal, Vol. 63, No. 8, Part 2, pp. 1649-1671, 1984.
2948*906afcb8SAndy Fiddaman.RF
2949*906afcb8SAndy FiddamanThese security holes occur primarily because a user can manipulate the
2950*906afcb8SAndy Fiddaman.I environment
2951*906afcb8SAndy Fiddamanto subvert the intent of a
2952*906afcb8SAndy Fiddaman.I setuid
2953*906afcb8SAndy Fiddamanshell procedure.
2954*906afcb8SAndy FiddamanSometimes, shell procedures are initiated from
2955*906afcb8SAndy Fiddamanbinary programs, without the author's
2956*906afcb8SAndy Fiddamanawareness, by library routines which invoke shells to carry out
2957*906afcb8SAndy Fiddamantheir tasks.
2958*906afcb8SAndy FiddamanWhen the binary program is run
2959*906afcb8SAndy Fiddaman.I setuid
2960*906afcb8SAndy Fiddamanthen the shell procedure runs with the permissions afforded to the
2961*906afcb8SAndy Fiddamanowner of the binary file.
2962*906afcb8SAndy Fiddaman.P
2963*906afcb8SAndy FiddamanIn the Bourne shell,
2964*906afcb8SAndy Fiddamanthe
2965*906afcb8SAndy Fiddaman.B \s-1IFS\s+1
2966*906afcb8SAndy Fiddamanparameter is used to split each word into separate command arguments.
2967*906afcb8SAndy FiddamanIf a user knows that some
2968*906afcb8SAndy Fiddaman.I setuid
2969*906afcb8SAndy Fiddamanprogram will run
2970*906afcb8SAndy Fiddaman\f5sh\ -c\ /bin/pwd\fP
2971*906afcb8SAndy Fiddaman(or any other command in
2972*906afcb8SAndy Fiddaman.BR /bin )
2973*906afcb8SAndy Fiddamanthen the user sets and exports
2974*906afcb8SAndy Fiddaman.BR \s-1IFS\s+1=\^/ .
2975*906afcb8SAndy FiddamanInstead of running
2976*906afcb8SAndy Fiddaman.B /bin/pwd
2977*906afcb8SAndy Fiddamanthe shell will run
2978*906afcb8SAndy Fiddaman.B bin
2979*906afcb8SAndy Fiddamanwith
2980*906afcb8SAndy Fiddaman.B pwd
2981*906afcb8SAndy Fiddamanas an argument.
2982*906afcb8SAndy FiddamanThe user puts his or her own \f5bin\fP
2983*906afcb8SAndy Fiddamanprogram into the current directory.
2984*906afcb8SAndy FiddamanThis program can
2985*906afcb8SAndy Fiddamancreate a copy of the shell,
2986*906afcb8SAndy Fiddamanmake this shell
2987*906afcb8SAndy Fiddaman.IR setuid ,
2988*906afcb8SAndy Fiddamanand then run the \f5/bin/pwd\fP
2989*906afcb8SAndy Fiddamanprogram so that the original program continues to run successfully.
2990*906afcb8SAndy FiddamanThis kind of penetration is not possible with
2991*906afcb8SAndy Fiddaman\f5ksh\fP
2992*906afcb8SAndy Fiddamansince the
2993*906afcb8SAndy Fiddaman.B \s-1IFS\s+1
2994*906afcb8SAndy Fiddamanparameter only splits arguments that result from command or parameter
2995*906afcb8SAndy Fiddamansubstitution.
2996*906afcb8SAndy Fiddaman.P
2997*906afcb8SAndy FiddamanSome
2998*906afcb8SAndy Fiddaman.I setuid
2999*906afcb8SAndy Fiddamanprograms run programs using
3000*906afcb8SAndy Fiddaman.I system()
3001*906afcb8SAndy Fiddamanwithout giving the full pathname.
3002*906afcb8SAndy FiddamanIf the
3003*906afcb8SAndy Fiddamanuser sets the
3004*906afcb8SAndy Fiddaman.B \s-1PATH\s+1
3005*906afcb8SAndy Fiddamanvariable so that the desired command will be found
3006*906afcb8SAndy Fiddamanin his or her local bin, then the same technique described above can
3007*906afcb8SAndy Fiddamanbe employed to compromise the security of the system.
3008*906afcb8SAndy FiddamanTo close up this and other security holes,
3009*906afcb8SAndy Fiddaman\f5ksh\fP
3010*906afcb8SAndy Fiddamanresets the effective user id to the real user id and the effective
3011*906afcb8SAndy Fiddamangroup id to the real group id unless the
3012*906afcb8SAndy Fiddaman.I privileged
3013*906afcb8SAndy Fiddamanoption
3014*906afcb8SAndy Fiddaman.RB ( \-p\^ )
3015*906afcb8SAndy Fiddamanis specified at invocation.
3016*906afcb8SAndy FiddamanIn
3017*906afcb8SAndy Fiddamanthis mode, the
3018*906afcb8SAndy Fiddaman.B privileged
3019*906afcb8SAndy Fiddamanmode, the
3020*906afcb8SAndy Fiddaman.B .profile
3021*906afcb8SAndy Fiddamanand
3022*906afcb8SAndy Fiddaman.B \s-1ENV\s+1
3023*906afcb8SAndy Fiddamanfiles are not processed.
3024*906afcb8SAndy FiddamanInstead, the file
3025*906afcb8SAndy Fiddaman.B /etc/suid_profile
3026*906afcb8SAndy Fiddamanis read and executed.
3027*906afcb8SAndy FiddamanThis gives an administrator control over the
3028*906afcb8SAndy Fiddamanenvironment to set the
3029*906afcb8SAndy Fiddaman.B \s-1PATH\s+1
3030*906afcb8SAndy Fiddamanvariable or to log setuid shell invocations.
3031*906afcb8SAndy FiddamanClearly security of the system is compromised if
3032*906afcb8SAndy Fiddaman.B /etc
3033*906afcb8SAndy Fiddamanor this file is publicly writable.
3034*906afcb8SAndy Fiddaman.P
3035*906afcb8SAndy FiddamanSome versions of the UNIX operating system look for the characters
3036*906afcb8SAndy Fiddaman\f5#!\fP
3037*906afcb8SAndy Fiddamanas the first two characters of an executable file.
3038*906afcb8SAndy FiddamanIf these characters are found, then the next word on this line is taken
3039*906afcb8SAndy Fiddamanas the interpreter to
3040*906afcb8SAndy Fiddamaninvoke
3041*906afcb8SAndy Fiddamanfor this command and the interpreter is
3042*906afcb8SAndy Fiddaman.IR exec ed
3043*906afcb8SAndy Fiddamanwith the name of the script as argument zero and argument one.
3044*906afcb8SAndy FiddamanIf the
3045*906afcb8SAndy Fiddaman.I setuid
3046*906afcb8SAndy Fiddamanor
3047*906afcb8SAndy Fiddaman.I setgid
3048*906afcb8SAndy Fiddamanbits are on for this file, then the interpreter
3049*906afcb8SAndy Fiddamanis run with the effective uid and/or gid set accordingly.
3050*906afcb8SAndy FiddamanThis scheme has three major drawbacks.
3051*906afcb8SAndy FiddamanFirst of all,
3052*906afcb8SAndy Fiddamanputting the pathname of the interpreter into the script
3053*906afcb8SAndy Fiddamanmakes the script less portable since the interpreter
3054*906afcb8SAndy Fiddamanmay be installed in a different directory on another system.
3055*906afcb8SAndy FiddamanSecondly, using the
3056*906afcb8SAndy Fiddaman\f5#!\fP
3057*906afcb8SAndy Fiddamannotation forces an
3058*906afcb8SAndy Fiddaman.B exec
3059*906afcb8SAndy Fiddamanof the interpreter even when the call is invoked from the interpreter
3060*906afcb8SAndy Fiddamanwhich it must exec.  This is inefficient since
3061*906afcb8SAndy Fiddaman\f5ksh\fP can handle a failed exec much faster than starting up
3062*906afcb8SAndy Fiddamanagain.
3063*906afcb8SAndy FiddamanMore importantly,
3064*906afcb8SAndy Fiddaman.I setuid
3065*906afcb8SAndy Fiddamanand
3066*906afcb8SAndy Fiddaman.I setgid
3067*906afcb8SAndy Fiddamanprocedures provide an easy target for intrusion.
3068*906afcb8SAndy FiddamanBy linking a
3069*906afcb8SAndy Fiddaman.I setuid
3070*906afcb8SAndy Fiddamanor
3071*906afcb8SAndy Fiddaman.I setgid
3072*906afcb8SAndy Fiddamanprocedure to a name beginning with a
3073*906afcb8SAndy Fiddaman.B \-
3074*906afcb8SAndy Fiddamanthe interpreter is fooled into thinking that it is being invoked with
3075*906afcb8SAndy Fiddamana command line option rather than the name of a file.
3076*906afcb8SAndy FiddamanWhen the interpreter is the shell, the user gets a privileged
3077*906afcb8SAndy Fiddamaninteractive shell.
3078*906afcb8SAndy FiddamanThere is code in
3079*906afcb8SAndy Fiddaman\f5ksh\fP
3080*906afcb8SAndy Fiddamanto guard against this simple form of intrusion.
3081*906afcb8SAndy Fiddaman.P
3082*906afcb8SAndy FiddamanA more reliable way to handle
3083*906afcb8SAndy Fiddaman.I setuid
3084*906afcb8SAndy Fiddamanand
3085*906afcb8SAndy Fiddaman.I setgid
3086*906afcb8SAndy Fiddamanprocedures is provided with
3087*906afcb8SAndy Fiddaman\f5ksh\fP.
3088*906afcb8SAndy FiddamanThe technique does not require any changes to the operating system
3089*906afcb8SAndy Fiddamanand provides better security.
3090*906afcb8SAndy FiddamanAnother advantage to this method is that it also allows scripts which
3091*906afcb8SAndy Fiddamanhave execute permission but no read permission to run.  Taking away read
3092*906afcb8SAndy Fiddamanpermission makes scripts more secure.
3093*906afcb8SAndy Fiddaman.P
3094*906afcb8SAndy FiddamanThe method relies on a setuid
3095*906afcb8SAndy Fiddaman.B root
3096*906afcb8SAndy Fiddamanprogram to authenticate the
3097*906afcb8SAndy Fiddamanrequest and exec the shell with the correct mode bits to carry out
3098*906afcb8SAndy Fiddamanthe task.  This shell is invoked with the requested file already open
3099*906afcb8SAndy Fiddamanfor reading.  A script which cannot be opened for reading or which
3100*906afcb8SAndy Fiddamanhas its setuid and/or setgid bits turned on causes this setuid
3101*906afcb8SAndy Fiddaman.B root
3102*906afcb8SAndy Fiddamanprogram to get \fBexec\fPed.
3103*906afcb8SAndy FiddamanFor security reasons, this program is given the full
3104*906afcb8SAndy Fiddamanpathname
3105*906afcb8SAndy Fiddaman\f5/etc/suid_exec\fP.
3106*906afcb8SAndy FiddamanA description of the implementation of the
3107*906afcb8SAndy Fiddaman\f5/etc/suid_exec\fP
3108*906afcb8SAndy Fiddamanprogram can be found in
3109*906afcb8SAndy Fiddamana separate paper\*(Rf.
3110*906afcb8SAndy Fiddaman.RS
3111*906afcb8SAndy FiddamanD. G Korn
3112*906afcb8SAndy Fiddaman.I "Parlez-vous Kanji?"
3113*906afcb8SAndy FiddamanTM-59554-860602-03, 1986.
3114*906afcb8SAndy Fiddaman.RF
3115*906afcb8SAndy Fiddaman.H 1 "CODE CHANGES"
3116*906afcb8SAndy Fiddaman\f5ksh\fP is written in ANSI-C as a reusable library.
3117*906afcb8SAndy FiddamanThe code can be compiled with C++ and older K&R C as well.
3118*906afcb8SAndy FiddamanThe code uses the IEEE POSIX 1003.1 and ISO 9945-1 standard\*(Rf
3119*906afcb8SAndy Fiddaman.RS
3120*906afcb8SAndy Fiddaman.I "POSIX \- Part 1: System Application Program Interface,"
3121*906afcb8SAndy FiddamanIEEE Std 1003.1-1990, ISO/IEC 9945-1:1990.
3122*906afcb8SAndy Fiddaman.RF
3123*906afcb8SAndy Fiddamanwherever possible so that \f5ksh\fP should be able to run
3124*906afcb8SAndy Fiddamanon any POSIX compliant system.  In addition, it is possible
3125*906afcb8SAndy Fiddamanto compile \f5ksh\fP for older systems.
3126*906afcb8SAndy Fiddaman.P
3127*906afcb8SAndy FiddamanUnlike earlier version of the Bourne shell,
3128*906afcb8SAndy Fiddaman\f5ksh\fP treats eight bit characters transparently
3129*906afcb8SAndy Fiddamanwithout stripping off the
3130*906afcb8SAndy Fiddamanleading bit.
3131*906afcb8SAndy FiddamanThere is also a compile time switch to enable handling multi-byte
3132*906afcb8SAndy Fiddamanand multi-width characters sets.
3133*906afcb8SAndy Fiddaman.P
3134*906afcb8SAndy FiddamanOn systems with dynamic libraries, it is possible to add built-in
3135*906afcb8SAndy Fiddamancommands at run time  with the built-in command \f5builtin\fP
3136*906afcb8SAndy Fiddamandescribed earlier.
3137*906afcb8SAndy FiddamanIt is also possible to embed \f5ksh\fP in applications in
3138*906afcb8SAndy Fiddamana manner analogous to \f5tcl\fP.
3139*906afcb8SAndy Fiddaman.H 1 "EXAMPLE"
3140*906afcb8SAndy Fiddaman.P
3141*906afcb8SAndy FiddamanAn example of a \f5ksh\fP script is included
3142*906afcb8SAndy Fiddamanin the Appendix.
3143*906afcb8SAndy FiddamanThis one page program is a variant of the UNIX system
3144*906afcb8SAndy Fiddaman\f5grep\fP(1) program.
3145*906afcb8SAndy FiddamanPattern matching for this version of \f5grep\fP
3146*906afcb8SAndy Fiddamanmeans shell patterns.
3147*906afcb8SAndy Fiddaman.P
3148*906afcb8SAndy FiddamanThe first half uses the \f5getopts\fP command to
3149*906afcb8SAndy Fiddamanfind the option flags.
3150*906afcb8SAndy FiddamanNearly all options have been implemented.
3151*906afcb8SAndy FiddamanThe second half goes through each line of each file
3152*906afcb8SAndy Fiddamanto look for a pattern match.
3153*906afcb8SAndy Fiddaman.P
3154*906afcb8SAndy FiddamanThis program is not intended to serve as a
3155*906afcb8SAndy Fiddamanreplacement for \f5grep\fP
3156*906afcb8SAndy Fiddamanwhich has been highly tuned for performance.
3157*906afcb8SAndy FiddamanIt does
3158*906afcb8SAndy Fiddamanillustrate the programming power of \f5ksh\fP.
3159*906afcb8SAndy FiddamanNote that no auxiliary processes are spawned by this script.
3160*906afcb8SAndy FiddamanIt was written and debugged in under two hours.
3161*906afcb8SAndy FiddamanWhile performance is acceptable for small files,
3162*906afcb8SAndy Fiddamanthis program runs at only one tenth
3163*906afcb8SAndy Fiddamanthe speed of \f5grep\fP
3164*906afcb8SAndy Fiddamanfor large files.
3165*906afcb8SAndy Fiddaman.H 1 "PERFORMANCE"
3166*906afcb8SAndy Fiddaman.P
3167*906afcb8SAndy Fiddaman\f5ksh\fP executes many scripts faster than the System V Bourne shell;
3168*906afcb8SAndy Fiddamanin some cases more than 10 times as fast.
3169*906afcb8SAndy FiddamanThe primary reason for this is that \f5ksh\fP creates fewer
3170*906afcb8SAndy Fiddamanprocesses.
3171*906afcb8SAndy FiddamanThe time to execute a built-in command or a function is one or two
3172*906afcb8SAndy Fiddamanorders of magnitude faster than performing a \f5fork\fP() and
3173*906afcb8SAndy Fiddaman\f5exec\fP() to create a separate process.
3174*906afcb8SAndy FiddamanCommand substitution and commands inside parentheses
3175*906afcb8SAndy Fiddamanare performed without creating another process, unless necessary
3176*906afcb8SAndy Fiddamanto preserve correct behavior.
3177*906afcb8SAndy Fiddaman.P
3178*906afcb8SAndy FiddamanAnother reason for improved performance is the use of the \fBsfio\fP\*(Rf,
3179*906afcb8SAndy Fiddaman.RS
3180*906afcb8SAndy FiddamanDavid Korn and Kiem-Phong Vo,
3181*906afcb8SAndy Fiddaman.IR "SFIO - A Safe/Fast String/File I/O,"
3182*906afcb8SAndy FiddamanProceedings of the Summer Usenix,
3183*906afcb8SAndy Fiddamanpp. 235-255, 1991.
3184*906afcb8SAndy Fiddaman.RF
3185*906afcb8SAndy Fiddamanlibrary for I/O.  The \fBsfio\fP library buffers all I/O
3186*906afcb8SAndy Fiddamanand buffers are flushed only when required.
3187*906afcb8SAndy FiddamanThe algorithms used in \fBsfio\fP perform better than
3188*906afcb8SAndy Fiddamantraditional versions of standard I/O so that programs that
3189*906afcb8SAndy Fiddamanspend most of their time
3190*906afcb8SAndy Fiddamanformatting output may actually perform better
3191*906afcb8SAndy Fiddamanthan versions written in C.
3192*906afcb8SAndy Fiddaman.P
3193*906afcb8SAndy FiddamanSeveral of the internal algorithms have been changed
3194*906afcb8SAndy Fiddamanso that the number of subroutine calls has been
3195*906afcb8SAndy Fiddamansubstantially reduced.
3196*906afcb8SAndy Fiddaman\f5ksh\fP uses variable sized hash tables for variables.
3197*906afcb8SAndy FiddamanScripts that rely heavily on referencing variables execute faster.
3198*906afcb8SAndy FiddamanMore processing is performed while reading the script
3199*906afcb8SAndy Fiddamanso that execution time is saved while running loops.
3200*906afcb8SAndy FiddamanThese changes are not noticeable for scripts that \f5fork()\fP
3201*906afcb8SAndy Fiddamanand run processes,
3202*906afcb8SAndy Fiddamanbut they reduce the time that it takes to interpret commands by
3203*906afcb8SAndy Fiddamanmore than a factor of two.
3204*906afcb8SAndy Fiddaman.P
3205*906afcb8SAndy FiddamanMost importantly, \f5ksh\fP provide mechanisms to write applications
3206*906afcb8SAndy Fiddamanthat do not require as many processes.
3207*906afcb8SAndy FiddamanThe arithmetic provided by the shell eliminates the need for the
3208*906afcb8SAndy Fiddaman\f5expr\fP command.
3209*906afcb8SAndy FiddamanThe pattern matching and substring capabilities eliminate the
3210*906afcb8SAndy Fiddamanneed to use \f5sed\fP or \f5awk\fP to process strings.
3211*906afcb8SAndy Fiddaman.P
3212*906afcb8SAndy FiddamanThe architecture of \f5ksh\fP makes it easy to make commands
3213*906afcb8SAndy Fiddamanbuilt-ins without changing the semantics at all.
3214*906afcb8SAndy FiddamanSystems that have run-time binding of libraries allow
3215*906afcb8SAndy Fiddamanapplications to be sped up by supplying the critical
3216*906afcb8SAndy Fiddamanprograms as shell built-in commands.
3217*906afcb8SAndy FiddamanImplementations on other systems can add built-in commands
3218*906afcb8SAndy Fiddamanat compile time.
3219*906afcb8SAndy FiddamanThe procedure for writing built-in commands that can be loaded
3220*906afcb8SAndy Fiddamanat run time is in a separate document.\*(Rf,
3221*906afcb8SAndy Fiddaman.RS
3222*906afcb8SAndy FiddamanDavid Korn,
3223*906afcb8SAndy Fiddaman.IR "Guidelines for writing \f5ksh-93\fP built-in commands,"
3224*906afcb8SAndy Fiddamanto be published, 1994.
3225*906afcb8SAndy Fiddaman.RF
3226*906afcb8SAndy Fiddaman.H 1  "CONCLUSION"
3227*906afcb8SAndy Fiddaman.P
3228*906afcb8SAndy FiddamanThe 1988 version of \f5ksh\fP has tens of thousands of regular users
3229*906afcb8SAndy Fiddamanand is a suitable replacement for the Bourne shell.
3230*906afcb8SAndy FiddamanThe 1993 version of \f5ksh\fP is essentially upward compatible with
3231*906afcb8SAndy Fiddamanboth the 1988 version of \f5ksh\fP and with the recent IEEE POSIX
3232*906afcb8SAndy Fiddamanand ISO shell standard.
3233*906afcb8SAndy FiddamanThe 1993 version offers many advantages for programming applications,
3234*906afcb8SAndy Fiddamanand it has been rewritten so that it can be used in embedded applications.
3235*906afcb8SAndy FiddamanIt also offers improved performance.
3236*906afcb8SAndy Fiddaman.SG dgk \"  signature typist initials
3237*906afcb8SAndy Fiddaman\" .CS 14 24 38 0 0 16  \" cover sheet for TM
3238*906afcb8SAndy Fiddaman.bp
3239*906afcb8SAndy Fiddaman.ce
3240*906afcb8SAndy Fiddaman\fIAPPENDIX\fP
3241*906afcb8SAndy Fiddaman.nf
3242*906afcb8SAndy Fiddaman\f5
3243*906afcb8SAndy Fiddaman.ta .66i 1.33i 2i 2.66i 3.33i 4i 4.66i 5.33i 6i 6.66i 7.33i 8i
3244*906afcb8SAndy Fiddaman.so grep.mm
3245*906afcb8SAndy Fiddaman.fi
3246*906afcb8SAndy Fiddaman\fP
3247*906afcb8SAndy Fiddaman
3248*906afcb8SAndy Fiddaman
3249