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