BSD 3 development
[unix-history] / usr / doc / cacm / p4
CommitLineData
8340f87c
BJ
1.SH
2VI. THE SHELL
3.PP
4For most users,
5communication with
6the system
7is carried on with the
8aid of a program called the \&shell.
9The \&shell is a
10command-line interpreter: it reads lines typed by the user and
11interprets them as requests to execute
12other programs.
13(The \&shell is described fully elsewhere,
14.[
15bourne shell bstj
16%Q This issue
17.]
18so this section will discuss only the theory of its operation.)
19In simplest form, a command line consists of the command
20name followed by arguments to the command, all separated
21by spaces:
22.P1
23command arg\*s\d1\u\*n arg\*s\d2\u\*n .\|.\|. arg\*s\dn\u\*n
24.P2
25The \&shell splits up the command name and the arguments into
26separate strings.
27Then a file with name
28.UL command
29is sought;
30.UL command
31may be a path name including the ``/'' character to
32specify any file in the system.
33If
34.UL command
35is found, it is brought into
36memory and executed.
37The arguments
38collected by the \&shell are accessible
39to the command.
40When the command is finished, the \&shell
41resumes its own execution, and indicates its readiness
42to accept another command by typing a prompt character.
43.PP
44If file
45.UL command
46cannot be found,
47the \&shell generally prefixes a string
48such as
49.UL /\|bin\|/
50to
51.UL command
52and
53attempts again to find the file.
54Directory
55.UL /\|bin
56contains commands
57intended to be generally used.
58(The sequence of directories to be searched
59may be changed by user request.)
60.SH
616.1 Standard I/O
62.PP
63The discussion of I/O in Section III above seems to imply that
64every file used by a program must be opened or created by the program in
65order to get a file descriptor for the file.
66Programs executed by the \&shell, however, start off with
67three open files with file descriptors
680, 1, and 2.
69As such a program begins execution, file 1 is open for writing,
70and is best understood as the standard output file.
71Except under circumstances indicated below, this file
72is the user's terminal.
73Thus programs that wish to write informative
74information ordinarily use file descriptor 1.
75Conversely, file 0 starts off open for reading, and programs that
76wish to read messages typed by the user
77read this file.
78.PP
79The \&shell is able to change the standard assignments of
80these file descriptors from the
81user's terminal printer and keyboard.
82If one of the
83arguments to a command is prefixed by ``>'', file descriptor
841 will, for the duration of the command, refer to the
85file named after the ``>''.
86For example:
87.P1
88ls
89.P2
90ordinarily lists, on the typewriter, the names of the files in the current
91directory.
92The command:
93.P1
94ls >there
95.P2
96creates a file called
97.UL there
98and places the listing there.
99Thus the argument
100.UL >there
101means
102``place output on
103.UL there .''
104On the other hand:
105.P1
106ed
107.P2
108ordinarily enters the editor, which takes requests from the
109user via his keyboard.
110The command
111.P1
112ed <script
113.P2
114interprets
115.UL script
116as a file of editor commands;
117thus
118.UL <script
119means ``take input from
120.UL script .''
121.PP
122Although the file name following ``<'' or ``>'' appears
123to be an argument to the command, in fact it is interpreted
124completely by the \&shell and is not passed to the
125command at all.
126Thus no special coding to handle I/O redirection is needed within each
127command; the command need merely use the standard file
128descriptors 0 and 1 where appropriate.
129.PP
130File descriptor 2 is, like file 1,
131ordinarily associated with the terminal output stream.
132When an output-diversion request with ``>'' is specified,
133file 2 remains attached to the terminal, so that commands
134may produce diagnostic messages that
135do not silently end up in the output file.
136.SH
1376.2 Filters
138.PP
139An extension of the standard I/O notion is used
140to direct output from one command to
141the input of another.
142A sequence of commands separated by
143vertical bars causes the \&shell to
144execute all the commands simultaneously and to arrange
145that the standard output of each command
146be delivered to the standard input of
147the next command in the sequence.
148Thus in the command line:
149.P1
150ls | pr \(mi2 | opr
151.P2
152.UL ls
153lists the names of the files in the current directory;
154its output is passed to
155.UL pr ,
156which
157paginates its input with dated headings.
158(The argument ``\(mi2'' requests
159double-column output.)
160Likewise, the output from
161.UL pr
162is input to
163.UL opr ;
164this command spools its input onto a file for off-line
165printing.
166.PP
167This procedure could have been carried out
168more clumsily by:
169.P1
170ls >temp1
171pr \(mi2 <temp1 >temp2
172opr <temp2
173.P2
174followed by removal of the temporary files.
175In the absence of the ability
176to redirect output and input,
177a still clumsier method would have been to
178require the
179.UL ls
180command
181to accept user requests to paginate its output,
182to print in multi-column format, and to arrange
183that its output be delivered off-line.
184Actually it would be surprising, and in fact
185unwise for efficiency reasons,
186to expect authors of
187commands such as
188.UL ls
189to provide such a wide variety of output options.
190.PP
191A program
192such as
193.UL pr
194which copies its standard input to its standard output
195(with processing)
196is called a
197.IT filter .
198Some filters that we have found useful
199perform
200character transliteration,
201selection of lines according to a pattern,
202sorting of the input,
203and encryption and decryption.
204.SH
2056.3 Command separators; multitasking
206.PP
207Another feature provided by the \&shell is relatively straightforward.
208Commands need not be on different lines; instead they may be separated
209by semicolons:
210.P1
211ls; ed
212.P2
213will first list the contents of the current directory, then enter
214the editor.
215.PP
216A related feature is more interesting.
217If a command is followed
218by ``\f3&\f1,'' the \&shell will not wait for the command to finish before
219prompting again; instead, it is ready immediately
220to accept a new command.
221For example:
222.bd 3
223.P1
224as source >output &
225.P2
226causes
227.UL source
228to be assembled, with diagnostic
229output going to
230.UL output ;
231no matter how long the
232assembly takes, the \&shell returns immediately.
233When the \&shell does not wait for
234the completion of a command,
235the identification number of the
236process running that command is printed.
237This identification may be used to
238wait for the completion of the command or to
239terminate it.
240The ``\f3&\f1'' may be used
241several times in a line:
242.P1
243as source >output & ls >files &
244.P2
245does both the assembly and the listing in the background.
246In these examples, an output file
247other than the terminal was provided; if this had not been
248done, the outputs of the various commands would have been
249intermingled.
250.PP
251The \&shell also allows parentheses in the above operations.
252For example:
253.P1
254(\|date; ls\|) >x &
255.P2
256writes the current date and time followed by
257a list of the current directory onto the file
258.UL x .
259The \&shell also returns immediately for another request.
260.SH 1
2616.4 The \&shell as a command; command files
262.PP
263The \&shell is itself a command, and may be called recursively.
264Suppose file
265.UL tryout
266contains the lines:
267.P1
268as source
269mv a.out testprog
270testprog
271.P2
272The
273.UL mv
274command causes the file
275.UL a.out
276to be renamed
277.UL testprog.
278.UL \&a.out
279is the (binary) output of the assembler, ready to be executed.
280Thus if the three lines above were typed on the keyboard,
281.UL source
282would be assembled, the resulting program renamed
283.UL testprog ,
284and
285.UL testprog
286executed.
287When the lines are in
288.UL tryout ,
289the command:
290.P1
291sh <tryout
292.P2
293would cause the \&shell
294.UL sh
295to execute the commands
296sequentially.
297.PP
298The \&shell has further capabilities, including the
299ability to substitute parameters
300and
301to construct argument lists from a specified
302subset of the file names in a directory.
303It also provides general conditional and looping constructions.
304.SH 1
3056.5 Implementation of the \&shell
306.PP
307The outline of the operation of the \&shell can now be understood.
308Most of the time, the \&shell
309is waiting for the user to type a command.
310When the
311newline character ending the line
312is typed, the \&shell's
313.UL read
314call returns.
315The \&shell analyzes the command line, putting the
316arguments in a form appropriate for
317.UL execute .
318Then
319.UL fork
320is called.
321The child process, whose code
322of course is still that of the \&shell, attempts
323to perform an
324.UL execute
325with the appropriate arguments.
326If successful, this will bring in and start execution of the program whose name
327was given.
328Meanwhile, the other process resulting from the
329.UL fork ,
330which is the
331parent process,
332.UL wait s
333for the child process to die.
334When this happens, the \&shell knows the command is finished, so
335it types its prompt and reads the keyboard to obtain another
336command.
337.PP
338Given this framework, the implementation of background processes
339is trivial; whenever a command line contains ``\f3&\f1,''
340the \&shell merely refrains from waiting for the process
341that it created
342to execute the command.
343.PP
344Happily, all of this mechanism meshes very nicely with
345the notion of standard input and output files.
346When a process is created by the
347.UL fork
348primitive, it
349inherits not only the memory image of its parent
350but also all the files currently open in its parent,
351including those with file descriptors 0, 1, and 2.
352The \&shell, of course, uses these files to read command
353lines and to write its prompts and diagnostics, and in the ordinary case
354its children\(emthe command programs\(eminherit them automatically.
355When an argument with ``<'' or ``>'' is given, however, the
356offspring process, just before it performs
357.UL execute,
358makes the standard I/O
359file descriptor (0 or 1, respectively) refer to the named file.
360This is easy
361because, by agreement,
362the smallest unused file descriptor is assigned
363when a new file is
364.UL open ed
365(or
366.UL create d);
367it is only necessary to close file 0 (or 1)
368and open the named file.
369Because the process in which the command program runs simply terminates
370when it is through, the association between a file
371specified after ``<'' or ``>'' and file descriptor 0 or 1 is ended
372automatically when the process dies.
373Therefore
374the \&shell need not know the actual names of the files
375that are its own standard input and output, because it need
376never reopen them.
377.PP
378Filters are straightforward extensions
379of standard I/O redirection with pipes used
380instead of files.
381.PP
382In ordinary circumstances, the main loop of the \&shell never
383terminates.
384(The main loop includes the
385branch of the return from
386.UL fork
387belonging to the
388parent process; that is, the branch that does a
389.UL wait ,
390then
391reads another command line.)
392The one thing that causes the \&shell to terminate is
393discovering an end-of-file condition on its input file.
394Thus, when the \&shell is executed as a command with
395a given input file, as in:
396.P1
397sh <comfile
398.P2
399the commands in
400.UL comfile
401will be executed until
402the end of
403.UL comfile
404is reached; then the instance of the \&shell
405invoked by
406.UL sh
407will terminate.
408Because this \&shell process
409is the child of another instance of the \&shell, the
410.UL wait
411executed in the latter will return, and another
412command may then be processed.
413.SH
4146.6 Initialization
415.PP
416The instances of the \&shell to which users type
417commands are themselves children of another process.
418The last step in the initialization of
419the system
420is the creation of
421a single process and the invocation (via
422.UL execute )
423of a program called
424.UL init .
425The role of
426.UL init
427is to create one process
428for each terminal channel.
429The various subinstances of
430.UL init
431open the appropriate terminals
432for input and output
433on files 0, 1, and 2,
434waiting, if necessary, for carrier to be established on dial-up lines.
435Then a message is typed out requesting that the user log in.
436When the user types a name or other identification,
437the appropriate instance of
438.UL init
439wakes up, receives the log-in
440line, and reads a password file.
441If the user's name is found, and if
442he is able to supply the correct password,
443.UL init
444changes to the user's default current directory, sets
445the process's user \*sID\*n to that of the person logging in, and performs
446an
447.UL execute
448of the \&shell.
449At this point, the \&shell is ready to receive commands
450and the logging-in protocol is complete.
451.PP
452Meanwhile, the mainstream path of
453.UL init
454(the parent of all
455the subinstances of itself that will later become \&shells)
456does a
457.UL wait .
458If one of the child processes terminates, either
459because a \&shell found an end of file or because a user
460typed an incorrect name or password, this path of
461.UL init
462simply recreates the defunct process, which in turn reopens the appropriate
463input and output files and types another log-in message.
464Thus a user may log out simply by typing the end-of-file
465sequence to the \&shell.
466.SH
4676.7 Other programs as \&shell
468.PP
469The \&shell as described above is designed to allow users
470full access to the facilities of the system, because it will
471invoke the execution of any program
472with appropriate protection mode.
473Sometimes, however, a different interface to the system
474is desirable, and this feature is easily arranged for.
475.PP
476Recall that after a user has successfully logged in by supplying
477a name and password,
478.UL init
479ordinarily invokes the \&shell
480to interpret command lines.
481The user's entry
482in the password file may contain the name
483of a program to be invoked after log-in instead of the \&shell.
484This program is free to interpret the user's messages
485in any way it wishes.
486.PP
487For example, the password file entries
488for users of a secretarial editing system
489might
490specify that the
491editor
492.UL ed
493is to be used instead of the \&shell.
494Thus when users of the editing system log in, they are inside the editor and
495can begin work immediately; also, they can be prevented from
496invoking
497programs not intended for their use.
498In practice, it has proved desirable to allow a temporary
499escape from the editor
500to execute the formatting program and other utilities.
501.PP
502Several of the games (e.g., chess, blackjack, 3D tic-tac-toe)
503available on
504the system
505illustrate
506a much more severely restricted environment.
507For each of these, an entry exists
508in the password file specifying that the appropriate game-playing
509program is to be invoked instead of the \&shell.
510People who log in as a player
511of one of these games find themselves limited to the
512game and unable to investigate the (presumably more interesting)
513offerings of
514the
515.UX
516system
517as a whole.