|
|
1.1 ! root 1: .\" @(#)t2 6.2 (Berkeley) 9/12/88 ! 2: .\" ! 3: .SH ! 4: 2.0\ Shell\ procedures ! 5: .LP ! 6: The shell may be used to read and execute commands ! 7: contained in a file. ! 8: For example, ! 9: .DS ! 10: sh file [ args \*(ZZ ] ! 11: .DE ! 12: calls the shell to read commands from \fIfile.\fP ! 13: Such a file is called a \fIcommand procedure\fP ! 14: or \fIshell procedure.\fP ! 15: Arguments may be supplied with the call ! 16: and are referred to in \fIfile\fP ! 17: using the positional parameters ! 18: \fB$1, $2, \*(ZZ\|.\fR ! 19: For example, if the file \fIwg\fP contains ! 20: .DS ! 21: who \*(VT grep $1 ! 22: .DE ! 23: then ! 24: .DS ! 25: sh wg fred ! 26: .DE ! 27: is equivalent to ! 28: .DS ! 29: who \*(VT grep fred ! 30: .DE ! 31: .LP ! 32: UNIX files have three independent attributes, ! 33: \fIread,\fP \fIwrite\fP and \fIexecute.\fP ! 34: The UNIX command \fIchmod\fP (1) may be used ! 35: to make a file executable. ! 36: For example, ! 37: .DS ! 38: chmod +x wg ! 39: .DE ! 40: will ensure that the file \fIwg\fP has execute status. ! 41: Following this, the command ! 42: .DS ! 43: wg fred ! 44: .DE ! 45: is equivalent to ! 46: .DS ! 47: sh wg fred ! 48: .DE ! 49: This allows shell procedures and programs ! 50: to be used interchangeably. ! 51: In either case a new process is created to ! 52: run the command. ! 53: .LP ! 54: As well as providing names for the positional ! 55: parameters, ! 56: the number of positional parameters in the call ! 57: is available as \fB$#\|.\fP ! 58: The name of the file being executed ! 59: is available as \fB$0\|.\fP ! 60: .LP ! 61: A special shell parameter \fB$\*(ST\fP ! 62: is used to substitute for all positional parameters ! 63: except \fB$0\|.\fP ! 64: A typical use of this is to provide ! 65: some default arguments, ! 66: as in, ! 67: .DS ! 68: nroff \(miT450 \(mims $\*(ST ! 69: .DE ! 70: which simply prepends some arguments ! 71: to those already given. ! 72: .SH ! 73: 2.1\ Control\ flow\ -\ for ! 74: .LP ! 75: A frequent use of shell procedures is to loop ! 76: through the arguments (\fB$1, $2, \*(ZZ\fR) ! 77: executing commands once for each argument. ! 78: An example of such a procedure is ! 79: \fItel\fP that searches the file ! 80: \fB/usr/lib/telnos\fR ! 81: that contains lines of the form ! 82: .DS ! 83: \*(ZZ ! 84: fred mh0123 ! 85: bert mh0789 ! 86: \*(ZZ ! 87: .DE ! 88: The text of \fItel\fP is ! 89: .DS ! 90: for i ! 91: do grep $i /usr/lib/telnos; done ! 92: .DE ! 93: The command ! 94: .DS ! 95: tel fred ! 96: .DE ! 97: prints those lines in \fB/usr/lib/telnos\fR ! 98: that contain the string \fIfred\|.\fP ! 99: .DS ! 100: tel fred bert ! 101: .DE ! 102: prints those lines containing \fIfred\fP ! 103: followed by those for \fIbert.\fP ! 104: .LP ! 105: The \fBfor\fP loop notation is recognized by the shell ! 106: and has the general form ! 107: .DS ! 108: \fBfor\fR \fIname\fR \fBin\fR \fIw1 w2 \*(ZZ\fR ! 109: \fBdo\fR \fIcommand-list\fR ! 110: \fBdone\fR ! 111: .DE ! 112: A \fIcommand-list\fP is a sequence of one or more ! 113: simple commands separated or terminated by a newline or semicolon. ! 114: Furthermore, reserved words ! 115: like \fBdo\fP and \fBdone\fP are only ! 116: recognized following a newline or ! 117: semicolon. ! 118: \fIname\fP is a shell variable that is set ! 119: to the words \fIw1 w2 \*(ZZ\fR in turn each time the \fIcommand-list\fP ! 120: following \fBdo\fP ! 121: is executed. ! 122: If \fBin\fR \fIw1 w2 \*(ZZ\fR ! 123: is omitted then the loop ! 124: is executed once for each positional parameter; ! 125: that is, \fBin\fR \fI$\*(ST\fR is assumed. ! 126: .LP ! 127: Another example of the use of the \fBfor\fP ! 128: loop is the \fIcreate\fP command ! 129: whose text is ! 130: .DS ! 131: for i do >$i; done ! 132: .DE ! 133: The command ! 134: .DS ! 135: create alpha beta ! 136: .DE ! 137: ensures that two empty files ! 138: \fIalpha\fP and \fIbeta\fP exist ! 139: and are empty. ! 140: The notation \fI>file\fP may be used on its ! 141: own to create or clear the contents of a file. ! 142: Notice also that a semicolon (or newline) is required before \fBdone.\fP ! 143: .SH ! 144: 2.2\ Control\ flow\ -\ case ! 145: .LP ! 146: A multiple way branch is provided for by the ! 147: \fBcase\fP notation. ! 148: For example, ! 149: .DS ! 150: case $# in ! 151: \*(Ca1) cat \*(AP$1 ;; ! 152: \*(Ca2) cat \*(AP$2 <$1 ;; ! 153: \*(Ca\*(ST) echo \\'usage: append [ from ] to\\' ;; ! 154: esac ! 155: .DE ! 156: is an \fIappend\fP command. ! 157: When called ! 158: with one argument as ! 159: .DS ! 160: append file ! 161: .DE ! 162: \fB$#\fP is the string \fI1\fP and ! 163: the standard input is copied onto the ! 164: end of \fIfile\fP ! 165: using the \fIcat\fP command. ! 166: .DS ! 167: append file1 file2 ! 168: .DE ! 169: appends the contents of \fIfile1\fP ! 170: onto \fIfile2.\fP ! 171: If the number of arguments supplied to ! 172: \fIappend\fP is other than 1 or 2 ! 173: then a message is printed indicating ! 174: proper usage. ! 175: .LP ! 176: The general form of the \fBcase\fP command ! 177: is ! 178: .DS ! 179: \fBcase \fIword \fBin ! 180: \*(Ca\fIpattern\|\fB)\ \fIcommand-list\fB\|;; ! 181: \*(Ca\*(ZZ ! 182: \fBesac\fR ! 183: .DE ! 184: The shell attempts to match ! 185: \fIword\fR with each \fIpattern,\fR ! 186: in the order in which the patterns ! 187: appear. ! 188: If a match is found the ! 189: associated \fIcommand-list\fP is ! 190: executed and execution ! 191: of the \fBcase\fP is complete. ! 192: Since \*(ST is the pattern that matches any ! 193: string it can be used for the default case. ! 194: .LP ! 195: A word of caution: ! 196: no check is made to ensure that only ! 197: one pattern matches ! 198: the case argument. ! 199: The first match found defines the set of commands ! 200: to be executed. ! 201: In the example below the commands following ! 202: the second \*(ST will never be executed. ! 203: .DS ! 204: case $# in ! 205: \*(Ca\*(ST) \*(ZZ ;; ! 206: \*(Ca\*(ST) \*(ZZ ;; ! 207: esac ! 208: .DE ! 209: .LP ! 210: Another example of the use of the \fBcase\fP ! 211: construction is to distinguish ! 212: between different forms ! 213: of an argument. ! 214: The following example is a fragment of a \fIcc\fP command. ! 215: .DS ! 216: for i ! 217: do case $i in ! 218: \*(DC\(mi[ocs]) \*(ZZ ;; ! 219: \*(DC\(mi\*(ST) echo \\"unknown flag $i\\" ;; ! 220: \*(DC\*(ST.c) /lib/c0 $i \*(ZZ ;; ! 221: \*(DC\*(ST) echo \\"unexpected argument $i\\" ;; ! 222: \*(DOesac ! 223: done ! 224: .DE ! 225: .LP ! 226: To allow the same commands to be associated ! 227: with more than one pattern ! 228: the \fBcase\fP command provides ! 229: for alternative patterns ! 230: separated by a \*(VT\|. ! 231: For example, ! 232: .DS ! 233: case $i in ! 234: \*(Ca\(mix\*(VT\(miy) \*(ZZ ! 235: esac ! 236: .DE ! 237: is equivalent to ! 238: .DS ! 239: case $i in ! 240: \*(Ca\(mi[xy]) \*(ZZ ! 241: esac ! 242: .DE ! 243: .LP ! 244: The usual quoting conventions apply ! 245: so that ! 246: .DS ! 247: case $i in ! 248: \*(Ca\\\\?) \*(ZZ ! 249: .DE ! 250: will match the character \fB?\|.\fP ! 251: .SH ! 252: 2.3\ Here\ documents ! 253: .LP ! 254: The shell procedure \fItel\fP ! 255: in section 2.1 uses the file \fB/usr/lib/telnos\fR ! 256: to supply the data ! 257: for \fIgrep.\fP ! 258: An alternative is to include this ! 259: data ! 260: within the shell procedure as a \fIhere\fP document, as in, ! 261: .DS ! 262: for i ! 263: do grep $i \*(HE! ! 264: \*(DO\*(ZZ ! 265: \*(DOfred mh0123 ! 266: \*(DObert mh0789 ! 267: \*(DO\*(ZZ ! 268: ! ! 269: done ! 270: .DE ! 271: In this example ! 272: the shell takes the lines between \fB\*(HE!\fR and \fB!\fR ! 273: as the standard input for \fIgrep.\fP ! 274: The string \fB!\fR is arbitrary, the document ! 275: being terminated by a line that consists ! 276: of the string following \*(HE\|. ! 277: .LP ! 278: Parameters are substituted in the document ! 279: before it is made available to \fIgrep\fP ! 280: as illustrated by the following procedure ! 281: called \fIedg\|.\fP ! 282: .DS ! 283: ed $3 \*(HE% ! 284: g/$1/s//$2/g ! 285: w ! 286: % ! 287: .DE ! 288: The call ! 289: .DS ! 290: edg string1 string2 file ! 291: .DE ! 292: is then equivalent to the command ! 293: .DS ! 294: ed file \*(HE% ! 295: g/string1/s//string2/g ! 296: w ! 297: % ! 298: .DE ! 299: and changes all occurrences of \fIstring1\fP ! 300: in \fIfile\fP to \fIstring2\|.\fP ! 301: Substitution can be prevented using \\ ! 302: to quote the special character \fB$\fP ! 303: as in ! 304: .DS ! 305: ed $3 \*(HE+ ! 306: 1,\\\\$s/$1/$2/g ! 307: w ! 308: + ! 309: .DE ! 310: (This version of \fIedg\fP is equivalent to ! 311: the first except that \fIed\fP will print ! 312: a \fB?\fR if there are no occurrences of ! 313: the string \fB$1\|.\fP) ! 314: Substitution within a \fIhere\fP document ! 315: may be prevented entirely by quoting ! 316: the terminating string, ! 317: for example, ! 318: .DS ! 319: grep $i \*(HE\\\\# ! 320: \*(ZZ ! 321: # ! 322: .DE ! 323: The document is presented ! 324: without modification to \fIgrep.\fP ! 325: If parameter substitution is not required ! 326: in a \fIhere\fP document this latter form ! 327: is more efficient. ! 328: .SH ! 329: 2.4\ Shell\ variables ! 330: .LP ! 331: The shell ! 332: provides string-valued variables. ! 333: Variable names begin with a letter ! 334: and consist of letters, digits and ! 335: underscores. ! 336: Variables may be given values by writing, for example, ! 337: .DS ! 338: user=fred\ box=m000\ acct=mh0000 ! 339: .DE ! 340: which assigns values to the variables ! 341: \fBuser, box\fP and \fBacct.\fP ! 342: A variable may be set to the null string ! 343: by saying, for example, ! 344: .DS ! 345: null= ! 346: .DE ! 347: The value of a variable is substituted ! 348: by preceding its name with \fB$\|;\fP ! 349: for example, ! 350: .DS ! 351: echo $user ! 352: .DE ! 353: will echo \fIfred.\fP ! 354: .LP ! 355: Variables may be used interactively ! 356: to provide abbreviations for frequently ! 357: used strings. ! 358: For example, ! 359: .DS ! 360: b=/usr/fred/bin ! 361: mv pgm $b ! 362: .DE ! 363: will move the file \fIpgm\fP ! 364: from the current directory to the directory \fB/usr/fred/bin\|.\fR ! 365: A more general notation is available for parameter ! 366: (or variable) ! 367: substitution, as in, ! 368: .DS ! 369: echo ${user} ! 370: .DE ! 371: which is equivalent to ! 372: .DS ! 373: echo $user ! 374: .DE ! 375: and is used when the parameter name is ! 376: followed by a letter or digit. ! 377: For example, ! 378: .DS ! 379: tmp=/tmp/ps ! 380: ps a >${tmp}a ! 381: .DE ! 382: will direct the output of \fIps\fR ! 383: to the file \fB/tmp/psa,\fR ! 384: whereas, ! 385: .DS ! 386: ps a >$tmpa ! 387: .DE ! 388: would cause the value of the variable \fBtmpa\fP ! 389: to be substituted. ! 390: .LP ! 391: Except for \fB$?\fP the following ! 392: are set initially by the shell. ! 393: \fB$?\fP is set after executing each command. ! 394: .RS ! 395: .IP \fB$?\fP 8 ! 396: The exit status (return code) ! 397: of the last command executed ! 398: as a decimal string. ! 399: Most commands return a zero exit status ! 400: if they complete successfully, ! 401: otherwise a non-zero exit status is returned. ! 402: Testing the value of return codes is dealt with ! 403: later under \fBif\fP and \fBwhile\fP commands. ! 404: .IP \fB$#\fP 8 ! 405: The number of positional parameters ! 406: (in decimal). ! 407: Used, for example, in the \fIappend\fP command ! 408: to check the number of parameters. ! 409: .IP \fB$$\fP 8 ! 410: The process number of this shell (in decimal). ! 411: Since process numbers are unique among ! 412: all existing processes, this string is ! 413: frequently used to generate ! 414: unique ! 415: temporary file names. ! 416: For example, ! 417: .DS ! 418: ps a >/tmp/ps$$ ! 419: \*(ZZ ! 420: rm /tmp/ps$$ ! 421: .DE ! 422: .IP \fB$\|!\fP 8 ! 423: The process number of the last process ! 424: run in the background (in decimal). ! 425: .IP \fB$\(mi\fP 8 ! 426: The current shell flags, such as ! 427: \fB\(mix\fR and \fB\(miv\|.\fR ! 428: .RE ! 429: .LP ! 430: Some variables have a special meaning to the ! 431: shell and should be avoided for general ! 432: use. ! 433: .RS ! 434: .IP \fB$\s-1MAIL\s0\fP 8 ! 435: When used interactively ! 436: the shell looks at the file ! 437: specified by this variable ! 438: before it issues a prompt. ! 439: If the specified file has been modified ! 440: since it ! 441: was last looked at the shell ! 442: prints the message ! 443: \fIyou have mail\fP before prompting ! 444: for the next command. ! 445: This variable is typically set ! 446: in the file \fB.profile,\fP ! 447: in the user's login directory. ! 448: For example, ! 449: .DS ! 450: \s-1MAIL\s0=/usr/spool/mail/fred ! 451: .DE ! 452: .IP \fB$\s-1HOME\s0\fP 8 ! 453: The default argument ! 454: for the \fIcd\fP command. ! 455: The current directory is used to resolve ! 456: file name references that do not begin with ! 457: a \fB/\|,\fR ! 458: and is changed using the \fIcd\fP command. ! 459: For example, ! 460: .DS ! 461: cd /usr/fred/bin ! 462: .DE ! 463: makes the current directory \fB/usr/fred/bin\|.\fR ! 464: .DS ! 465: cat wn ! 466: .DE ! 467: will print on the terminal the file \fIwn\fP ! 468: in this directory. ! 469: The command ! 470: \fIcd\fP with no argument ! 471: is equivalent to ! 472: .DS ! 473: cd $\s-1HOME\s0 ! 474: .DE ! 475: This variable is also typically set in the ! 476: the user's login profile. ! 477: .IP \fB$\s-1PATH\s0\fP 8 ! 478: A list of directories that contain commands (the \fIsearch path\fR\|). ! 479: Each time a command is executed by the shell ! 480: a list of directories is searched ! 481: for an executable file. ! 482: .ne 5 ! 483: If \fB$\s-1PATH\s0\fP is not set ! 484: then the current directory, ! 485: \fB/bin\fP, and \fB/usr/bin\fP are searched by default. ! 486: .ne 5 ! 487: Otherwise \fB$\s-1PATH\s0\fP consists of directory ! 488: names separated by \fB:\|.\fP ! 489: For example, ! 490: .DS ! 491: \s-1PATH\s0=\fB:\fP/usr/fred/bin\fB:\fP/bin\fB:\fP/usr/bin ! 492: .DE ! 493: specifies that the current directory ! 494: (the null string before the first \fB:\fP\|), ! 495: \fB/usr/fred/bin, /bin \fRand\fP /usr/bin\fR ! 496: are to be searched in that order. ! 497: In this way individual users ! 498: can have their own `private' commands ! 499: that are accessible independently ! 500: of the current directory. ! 501: If the command name contains a \fB/\fR then this directory search ! 502: is not used; a single attempt ! 503: is made to execute the command. ! 504: .IP \fB$\s-1PS1\s0\fP 8 ! 505: The primary shell prompt string, by default, `\fB$\ \fR'. ! 506: .IP \fB$\s-1PS2\s0\fP 8 ! 507: The shell prompt when further input is needed, ! 508: by default, `\fB>\ \fR'. ! 509: .IP \fB$\s-1IFS\s0\fP 8 ! 510: The set of characters used by \fIblank ! 511: interpretation\fR (see section 3.4). ! 512: .RE ! 513: .SH ! 514: 2.5\ The\ test\ command ! 515: .LP ! 516: The \fItest\fP command, although not part of the shell, ! 517: is intended for use by shell programs. ! 518: For example, ! 519: .DS ! 520: test \(mif file ! 521: .DE ! 522: returns zero exit status if \fIfile\fP ! 523: exists and non-zero exit status otherwise. ! 524: In general \fItest\fP evaluates a predicate ! 525: and returns the result as its exit status. ! 526: Some of the more frequently used \fItest\fP ! 527: arguments are given here, see \fItest\fP (1) ! 528: for a complete specification. ! 529: .DS ! 530: test s true if the argument \fIs\fP is not the null string ! 531: test \(mif file true if \fIfile\fP exists ! 532: test \(mir file true if \fIfile\fP is readable ! 533: test \(miw file true if \fIfile\fP is writable ! 534: test \(mid file true if \fIfile\fP is a directory ! 535: .DE ! 536: .SH ! 537: 2.6\ Control\ flow\ -\ while ! 538: .LP ! 539: The actions of ! 540: the \fBfor\fP loop and the \fBcase\fP ! 541: branch are determined by data available to the shell. ! 542: A \fBwhile\fP or \fBuntil\fP loop ! 543: and an \fBif then else\fP branch ! 544: are also provided whose ! 545: actions are determined by the exit status ! 546: returned by commands. ! 547: A \fBwhile\fP loop has the general form ! 548: .DS ! 549: \fBwhile\fP \fIcommand-list\*1\fP ! 550: \fBdo\fP \fIcommand-list\*2\fP ! 551: \fBdone\fP ! 552: .DE ! 553: .LP ! 554: The value tested by the \fBwhile\fP command ! 555: is the exit status of the last simple command ! 556: following \fBwhile.\fP ! 557: Each time round the loop ! 558: \fIcommand-list\*1\fP is executed; ! 559: if a zero exit status is returned then ! 560: \fIcommand-list\*2\fP ! 561: is executed; ! 562: otherwise, the loop terminates. ! 563: For example, ! 564: .DS ! 565: while test $1 ! 566: do \*(ZZ ! 567: \*(DOshift ! 568: done ! 569: .DE ! 570: is equivalent to ! 571: .DS ! 572: for i ! 573: do \*(ZZ ! 574: done ! 575: .DE ! 576: \fIshift\fP is a shell command that ! 577: renames the positional parameters ! 578: \fB$2, $3, \*(ZZ\fR as \fB$1, $2, \*(ZZ\fR ! 579: and loses \fB$1\|.\fP ! 580: .LP ! 581: Another kind of use for the \fBwhile/until\fP ! 582: loop is to wait until some ! 583: external event occurs and then run ! 584: some commands. ! 585: In an \fBuntil\fP loop ! 586: the termination condition is reversed. ! 587: For example, ! 588: .DS ! 589: until test \(mif file ! 590: do sleep 300; done ! 591: \fIcommands\fP ! 592: .DE ! 593: will loop until \fIfile\fP exists. ! 594: Each time round the loop it waits for ! 595: 5 minutes before trying again. ! 596: (Presumably another process ! 597: will eventually create the file.) ! 598: .SH ! 599: 2.7\ Control\ flow\ -\ if ! 600: .LP ! 601: Also available is a ! 602: general conditional branch ! 603: of the form, ! 604: .DS ! 605: \fBif\fP \fIcommand-list ! 606: \fBthen \fIcommand-list ! 607: \fBelse \fIcommand-list ! 608: \fBfi\fR ! 609: .DE ! 610: that tests the value returned by the last simple command ! 611: following \fBif.\fP ! 612: .LP ! 613: The \fBif\fP command may be used ! 614: in conjunction with the \fItest\fP command ! 615: to test for the existence of a file as in ! 616: .DS ! 617: if test \(mif file ! 618: then \fIprocess file\fP ! 619: else \fIdo something else\fP ! 620: fi ! 621: .DE ! 622: .LP ! 623: An example of the use of \fBif, case\fP ! 624: and \fBfor\fP constructions is given in ! 625: section 2.10\|. ! 626: .LP ! 627: A multiple test \fBif\fP command ! 628: of the form ! 629: .DS ! 630: if \*(ZZ ! 631: then \*(ZZ ! 632: else if \*(ZZ ! 633: then \*(ZZ ! 634: else if \*(ZZ ! 635: \*(ZZ ! 636: fi ! 637: fi ! 638: fi ! 639: .DE ! 640: may be written using an extension of the \fBif\fP ! 641: notation as, ! 642: .DS ! 643: if \*(ZZ ! 644: then \*(ZZ ! 645: elif \*(ZZ ! 646: then \*(ZZ ! 647: elif \*(ZZ ! 648: \*(ZZ ! 649: fi ! 650: .DE ! 651: .LP ! 652: The following example is the \fItouch\fP command ! 653: which changes the `last modified' time for a list ! 654: of files. ! 655: The command may be used in conjunction ! 656: with \fImake\fP (1) to force recompilation of a list ! 657: of files. ! 658: .DS ! 659: flag= ! 660: for i ! 661: do case $i in ! 662: \*(DC\(mic) flag=N ;; ! 663: \*(DC\*(ST) if test \(mif $i ! 664: \*(DC then ln $i junk$$; rm junk$$ ! 665: \*(DC elif test $flag ! 666: \*(DC then echo file \\\\\'$i\\\\\' does not exist ! 667: \*(DC else >$i ! 668: \*(DC fi ! 669: \*(DO esac ! 670: done ! 671: .DE ! 672: The \fB\(mic\fP flag is used in this command to ! 673: force subsequent files to be created if they do not already exist. ! 674: Otherwise, if the file does not exist, an error message is printed. ! 675: The shell variable \fIflag\fP ! 676: is set to some non-null string if the \fB\(mic\fP ! 677: argument is encountered. ! 678: The commands ! 679: .DS ! 680: ln \*(ZZ; rm \*(ZZ ! 681: .DE ! 682: make a link to the file and then remove it ! 683: thus causing the last modified date to be updated. ! 684: .LP ! 685: The sequence ! 686: .DS ! 687: if command1 ! 688: then command2 ! 689: fi ! 690: .DE ! 691: may be written ! 692: .DS ! 693: command1 && command2 ! 694: .DE ! 695: Conversely, ! 696: .DS ! 697: command1 \*(VT\*(VT command2 ! 698: .DE ! 699: executes \fIcommand2\fP only if \fIcommand1\fP ! 700: fails. ! 701: In each case the value returned ! 702: is that of the last simple command executed. ! 703: .SH ! 704: 2.8\ Command\ grouping ! 705: .LP ! 706: Commands may be grouped in two ways, ! 707: .DS ! 708: \fB{\fI command-list\fB ; }\fR ! 709: .DE ! 710: and ! 711: .DS ! 712: \fB(\fI command-list\fB )\fR ! 713: .DE ! 714: .LP ! 715: In the first \fIcommand-list\fP is simply executed. ! 716: The second form executes \fIcommand-list\fP ! 717: as a separate process. ! 718: For example, ! 719: .DS ! 720: (cd x; rm junk ) ! 721: .DE ! 722: executes \fIrm junk\fP in the directory ! 723: \fBx\fP without changing the current ! 724: directory of the invoking shell. ! 725: .LP ! 726: The commands ! 727: .DS ! 728: cd x; rm junk ! 729: .DE ! 730: have the same effect but leave the invoking ! 731: shell in the directory \fBx.\fP ! 732: .SH ! 733: 2.9\ Debugging\ shell\ procedures ! 734: .LP ! 735: The shell provides two tracing mechanisms ! 736: to help when debugging shell procedures. ! 737: The first is invoked within the procedure ! 738: as ! 739: .DS ! 740: set \(miv ! 741: .DE ! 742: (\fBv\fP for verbose) and causes lines of the ! 743: procedure to be printed as they are read. ! 744: It is useful to help isolate syntax errors. ! 745: It may be invoked without modifying the procedure ! 746: by saying ! 747: .DS ! 748: sh \(miv proc \*(ZZ ! 749: .DE ! 750: where \fIproc\fP is the name of the shell procedure. ! 751: This flag may be used in conjunction ! 752: with the \fB\(min\fP flag which prevents ! 753: execution of subsequent commands. ! 754: (Note that saying \fIset \(min\fP at a terminal ! 755: will render the terminal useless ! 756: until an end-of-file is typed.) ! 757: .LP ! 758: The command ! 759: .DS ! 760: set \(mix ! 761: .DE ! 762: will produce an execution ! 763: trace. ! 764: Following parameter substitution ! 765: each command is printed as it is executed. ! 766: (Try these at the terminal to see ! 767: what effect they have.) ! 768: Both flags may be turned off by saying ! 769: .DS ! 770: set \(mi ! 771: .DE ! 772: and the current setting of the shell flags is available as \fB$\(mi\|.\fR ! 773: .SH ! 774: 2.10\ The\ man\ command ! 775: .LP ! 776: The following is the \fIman\fP command ! 777: which is used to diplay sections of the UNIX manual on your terminal. ! 778: It is called, for example, as ! 779: .DS ! 780: man sh ! 781: man \(mit ed ! 782: man 2 fork ! 783: .DE ! 784: In the first the manual section for \fIsh\fP ! 785: is displayed.. ! 786: Since no section is specified, section 1 is used. ! 787: The second example will typeset (\fB\(mit\fP option) ! 788: the manual section for \fIed.\fP ! 789: The last prints the \fIfork\fP manual page ! 790: from section 2, which covers system calls. ! 791: .sp 2 ! 792: .DS ! 793: cd /usr/man ! 794: ! 795: : \'colon is the comment command\' ! 796: : \'default is nroff ($N), section 1 ($s)\' ! 797: N=n\ s=1 ! 798: ! 799: for i ! 800: do case $i in ! 801: .sp .5 ! 802: \*(DC[1\(mi9]\*(ST) s=$i ;; ! 803: .sp .5 ! 804: \*(DC\(mit) N=t ;; ! 805: .sp .5 ! 806: \*(DC\(min) N=n ;; ! 807: .sp .5 ! 808: \*(DC\(mi\*(ST) echo unknown flag \\\\\'$i\\\\\' ;; ! 809: .sp .5 ! 810: \*(DC\*(ST) if test \(mif man$s/$i.$s ! 811: \*(DC then ${N}roff man0/${N}aa man$s/$i.$s ! 812: \*(DC else : \'look through all manual sections\' ! 813: \*(DC found=no ! 814: \*(DC for j in 1 2 3 4 5 6 7 8 9 ! 815: \*(DC do if test \(mif man$j/$i.$j ! 816: \*(DC \*(DOthen man $j $i ! 817: \*(DC \*(DO\*(THfound=yes ! 818: \*(DC \*(DOfi ! 819: \*(DC done ! 820: \*(DC case $found in ! 821: \*(DC \*(Cano) echo \\'$i: manual page not found\\' ! 822: \*(DC esac ! 823: \*(DC fi ! 824: \*(DOesac ! 825: done ! 826: .DE ! 827: .ce ! 828: .ft B ! 829: Figure 1. A version of the man command ! 830: .ft R
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.