Annotation of researchv10dc/vol2/rc/rc.ms, revision 1.1.1.1

1.1       root        1: .so ../ADM/mac
                      2: .XX rc 283 "Rc \(em A Shell for Plan 9 and UNIX"
                      3: .fp 5 T CW     \" T for Typewriter
                      4: .Tm shell programming language g
                      5: .de TP \" An indented paragraph describing some command, tagged with the command name
                      6: .IP "\\fT\\$1\\fR" 5
                      7: .if \\w'\\fT\\$1\\fR'-4n .br
                      8: ..
                      9: .de CI
                     10: .nr Sf \\n(.f
                     11: \%\&\\$3\f(CW\\$1\fI\&\\$2\f\\n(Sf
                     12: ..
                     13: .TL
                     14: Rc \(em A Shell for Plan 9 and UNIX
                     15: .AU
                     16: Tom Duff
                     17: .AI
                     18: .MH
                     19: .AB
                     20: .I Rc
                     21: is a command interpreter for Plan 9.
                     22: It also runs on a variety of UNIX systems,
                     23: including SunOS and the Tenth Edition.
                     24: It provides similar facilities to Bourne's
                     25: .I /bin/sh ,
                     26: with some small additions and mostly less idiosyncratic syntax.
                     27: This paper introduces
                     28: .I rc
                     29: with numerous examples, and discusses its design and
                     30: why it varies from Bourne's.
                     31: .AE
                     32: .2C
                     33: .NH
                     34: Introduction
                     35: .PP
                     36: Plan 9 needs a command-programming language.  As porting the
                     37: Bourne shell to a non-UNIX environment seemed a daunting task,
                     38: I chose to write a new command interpreter, called
                     39: .I rc
                     40: because it runs commands.
                     41: Although tinkering with perfection is a dangerous business,
                     42: I could hardly resist trying to `improve' on Bourne's design.
                     43: Thus,
                     44: .I rc
                     45: is similar in spirit, but different in detail from Bourne's
                     46: shell.
                     47: .NH
                     48: Simple commands
                     49: .PP
                     50: For the simplest uses,
                     51: .I rc
                     52: has syntax familiar to Bourne shell users.
                     53: A simple command is a blank-separated sequence of arguments.
                     54: .P1
                     55: date
                     56: .P2
                     57: prints the current date and time, and
                     58: .P1
                     59: con alice
                     60: .P2
                     61: connects the user's terminal to the machine
                     62: .CW alice .
                     63: .NH
                     64: Quotation
                     65: .PP
                     66: An argument that contains a space or one of
                     67: .I rc 's
                     68: other syntax characters should be enclosed in apostrophes
                     69: .CW ' ). (
                     70: For example:
                     71: .P1
                     72: rm 'odd file name'
                     73: .P2
                     74: To include an apostrophe in a quoted name, it must be doubled:
                     75: .P1
                     76: echo 'How''s your father?'
                     77: .P2
                     78: .NH
                     79: Comments and continuation
                     80: .PP
                     81: A number-sign
                     82: .CW # ) (
                     83: and all characters following it up to, but not including, the next newline
                     84: are ignored, except in quotation marks.
                     85: .PP
                     86: A long command line may be continued on subsequent lines by typing a
                     87: backslash
                     88: .CW \e ) (
                     89: followed immediately by a newline, anywhere that white space is required.
                     90: Commands also continue onto the next line when the last symbol on
                     91: a line could not reasonably be the end of the command.
                     92: .NH
                     93: I/O Redirection
                     94: .PP
                     95: Many commands write output on the standard output file, normally the terminal.
                     96: A command's standard output may be made to overwrite a file by writing
                     97: .P1
                     98: who >user.names
                     99: .P2
                    100: This command produces a list of the currently logged in users in a file named
                    101: .CW user.names .
                    102: Standard output may be appended to the end of a file by
                    103: .P1
                    104: who >>user.names
                    105: .P2
                    106: In either case, mentioning a non-existent file causes it to be created.
                    107: .PP
                    108: Likewise, a command's standard input, also normally the terminal, may be connected to
                    109: a file by
                    110: .P1
                    111: wc <file
                    112: .P2
                    113: This command will report the number of characters, lines and words in
                    114: .CW file .
                    115: ........
                    116: .NH
                    117: Pipelines
                    118: .PP
                    119: The standard output of one command may be connected to the standard input of another
                    120: command like this:
                    121: .P1
                    122: who | wc
                    123: .P2
                    124: This prints the number of users currently logged in, and is equivalent to
                    125: .P1
                    126: who >tmp
                    127: wc <tmp
                    128: .P2
                    129: except that no temporary file is produced.  Instead a pipe \(em an
                    130: interprocess channel that looks to one process like an output file and to
                    131: another like an input file \(em is created joining the two commands, which
                    132: run simultaneously.  The pipe contains a data buffer so that the two
                    133: commands need not produce and consume data in perfect lock-step.
                    134: .NH
                    135: Filename patterns
                    136: .PP
                    137: .I Rc
                    138: has several ways to generate argument lists automatically.
                    139: These include filename pattern matching, variable substitution, string concatenation,
                    140: command substitution and pipeline branching.
                    141: .PP
                    142: Any literal word containing one of the meta-characters
                    143: .CW * ,
                    144: .CW ?
                    145: or
                    146: .CW [
                    147: is a pattern used to match filenames.
                    148: A
                    149: .CW *
                    150: matches any sequence of characters
                    151: a
                    152: .CW ?
                    153: matches any single character,
                    154: and a list of characters between
                    155: .CW [
                    156: and
                    157: .CW ]
                    158: matches a single character from the listed set.
                    159: The list may include ranges like
                    160: .CW a-z ,
                    161: specifying all ASCII characters between the two.
                    162: The entire set is complemented if the first character
                    163: after
                    164: .CW [
                    165: is
                    166: .CW ~
                    167: (a tilde.)
                    168: No meta-character can match
                    169: the first character of the filenames
                    170: .CW .
                    171: and
                    172: .CW ..
                    173: or the character
                    174: .CW / .
                    175: .PP
                    176: A pattern is replaced by a list of all the names that it matches.
                    177: If it matches no name, it remains unreplaced.
                    178: .PP
                    179: Meta-characters are active only when they appear literally
                    180: and unquoted.  For example, if a variable (see below) has a
                    181: .CW *
                    182: in it, and the value is substituted into a line, it is
                    183: not used for filename matching.
                    184: .NH
                    185: Variables
                    186: .PP
                    187: .I Rc
                    188: provides variables whose values are lists of arguments.
                    189: Variables may be given values by typing, for example:
                    190: .P1
                    191: path=(. /bin /usr/bin)
                    192: user=td
                    193: tty=/dev/tty8
                    194: .P2
                    195: The parentheses indicate that the value assigned to
                    196: .CW path
                    197: is a list of three strings. The variables
                    198: .CW user
                    199: and
                    200: .CW tty
                    201: are assigned lists containing a single string.
                    202: .PP
                    203: The value of a variable can be substituted into a command by
                    204: preceding its name with a
                    205: .CW $ ,
                    206: like this:
                    207: .P1
                    208: echo $path
                    209: .P2
                    210: If
                    211: .CW path
                    212: had been set as above, this would be equivalent to
                    213: .P1
                    214: echo . /bin /usr/bin
                    215: .P2
                    216: Variables may be subscripted by numbers or lists of numbers,
                    217: like this:
                    218: .P1
                    219: echo $path(2)
                    220: echo $path(3 2 1)
                    221: .P2
                    222: These are equivalent to
                    223: .P1
                    224: echo /bin
                    225: echo /usr/bin /bin .
                    226: .P2
                    227: There can be no space separating the variable's name from the
                    228: left parenthesis.  Otherwise, the subscript would be considered
                    229: a separate parenthesized list.
                    230: .PP
                    231: The number of strings in a variable can be determined by the
                    232: .CW $#
                    233: operator.  For example,
                    234: .P1
                    235: echo $#path
                    236: .P2
                    237: would print the number of entries in
                    238: .CW $path .
                    239: .PP
                    240: The following two assignments are subtly different:
                    241: .P1
                    242: empty=()
                    243: null=''
                    244: .P2
                    245: The first sets
                    246: .CW empty
                    247: to a list containing no strings.
                    248: The second sets
                    249: .CW null
                    250: to a list containing a single string,
                    251: but the string contains no characters.
                    252: .PP
                    253: Although these may seem like more or less
                    254: the same thing (in Bourne's shell, they are
                    255: indistinguishable), they behave differently
                    256: in almost all circumstances.
                    257: Among other things
                    258: .P1
                    259: echo $#empty
                    260: .P2
                    261: prints 0, whereas
                    262: .P1
                    263: echo $#null
                    264: .P2
                    265: prints 1.
                    266: .PP
                    267: All variables that have never been set have the value
                    268: .CW () .
                    269: ......
                    270: .NH
                    271: Arguments
                    272: .PP
                    273: When
                    274: .I rc
                    275: is reading its input from a file, the file has access
                    276: to the arguments supplied on
                    277: .I rc 's
                    278: command line.  The variable
                    279: .CW $*
                    280: initially has the list of arguments assigned to it.
                    281: The names
                    282: .CW $1 ,
                    283: .CW $2 ,
                    284: etc. are synonyms for
                    285: .CW $*(1) ,
                    286: .CW $*(2) ,
                    287: etc.
                    288: In addition,
                    289: .CW $0
                    290: is the name of the file from which
                    291: .I rc 's
                    292: input is being read.
                    293: .PP
                    294: The built-in
                    295: .CW shift
                    296: command deletes the first member of
                    297: .CW $* .
                    298: If
                    299: .CW shift
                    300: is given an argument, it deletes the given
                    301: number of members from
                    302: .CW $*.
                    303: Thus,
                    304: .P1
                    305: *=(Never, ever type rm -fr /)
                    306: shift 2
                    307: echo Please $*
                    308: .P2
                    309: would print
                    310: .P1
                    311: Please type rm -fr /
                    312: .P2
                    313: .NH
                    314: Concatenation
                    315: .PP
                    316: .I Rc
                    317: has a string concatenation operator, the caret 
                    318: .CW ^ ,
                    319: to build a arguments out of pieces.
                    320: .P1
                    321: echo hully^gully
                    322: .P2
                    323: is exactly equivalent to
                    324: .P1
                    325: echo hullygully
                    326: .P2
                    327: Suppose variable
                    328: .CW i
                    329: contains the name of a command.
                    330: Then
                    331: .P1
                    332: cc -o $i $i^.c
                    333: .P2
                    334: might compile the command's source code, leaving the
                    335: result in the appropriate file.
                    336: .PP
                    337: Concatenation distributes over lists. The following
                    338: .P1
                    339: echo (a b c)^(1 2 3)
                    340: src=(main subr io)
                    341: cc $src^.c
                    342: .P2
                    343: are equivalent to
                    344: .P1
                    345: echo a1 b2 c3
                    346: cc main.c subr.c io.c
                    347: .P2
                    348: In detail, the rule is: if both operands of
                    349: .CW ^
                    350: are lists of the same non-zero number of strings, they are concatenated
                    351: pairwise.  Otherwise, if one of the operands is a single string,
                    352: it is concatenated with each member of the other operand in turn.
                    353: Any other combination of operands is an error.
                    354: .NH
                    355: Free carets
                    356: .PP
                    357: User demand has dictated that
                    358: .I rc
                    359: insert carets in certain places, to make the syntax
                    360: look more like the Bourne shell.  For example, this:
                    361: .P1
                    362: cc -$flags $stems.c
                    363: .P2
                    364: is equivalent to
                    365: .P1
                    366: cc -^$flags $stems^.c
                    367: .P2
                    368: In general,
                    369: .I rc
                    370: will insert
                    371: .CW ^
                    372: between two arguments that are not separated by white space.
                    373: Specifically, whenever one of
                    374: .CW "$'`
                    375: follows a quoted or unquoted word, or an unquoted word follows
                    376: a quoted word with no intervening blanks or tabs, a
                    377: .CW ^
                    378: is inserted between the two.  If an unquoted word immediately following a
                    379: .CW $
                    380: contains a character other than an alphanumeric, underscore or
                    381: .CW * ,
                    382: a
                    383: .CW ^
                    384: is inserted before the first such character.
                    385: .NH
                    386: Command substitution
                    387: .PP
                    388: It is often useful to build an argument list from the output of a command.
                    389: .I Rc
                    390: allows a command, enclosed in braces and preceded by a left quote,
                    391: .CW "`{...}" ,
                    392: anywhere that an argument is required.  The command is executed and its
                    393: standard output captured.
                    394: The characters stored in the variable
                    395: .CW ifs
                    396: are used to split the output into arguments.
                    397: For example,
                    398: .P1
                    399: cat `{ls -tr|sed 10q}
                    400: .P2
                    401: will catenate the ten oldest files in the current directory in temporal order.
                    402: .NH
                    403: Pipeline branching
                    404: .PP
                    405: The pipeline notation described above is general enough for almost all cases.
                    406: Very occasionally it is useful to have pipelines that are not linear.
                    407: Pipeline topologies more general than trees can require arbitrarily large pipe buffers,
                    408: or worse, can cause deadlock.
                    409: .I Rc
                    410: has syntax for some kinds of non-linear but treelike pipelines.
                    411: For example,
                    412: .P1
                    413:        cmp <{old} <{new}
                    414: .P2
                    415: will regression test a new version of a command.
                    416: A
                    417: .CW <
                    418: (or
                    419: .CW > )
                    420: followed by a command in braces causes the command to be run with
                    421: its standard output (or input) attached to a pipe.  The parent command
                    422: .CW cmp "" (
                    423: in the example)
                    424: is started with the other end of the pipe attached to some file descriptor
                    425: or other, and with an argument that will connect to the pipe when opened
                    426: (e.g.
                    427: .CW /dev/fd/6 .)
                    428: On systems without
                    429: .CW /dev/fd ,
                    430: or something similar (SunOS for example) this feature does not work.
                    431: .....
                    432: .NH
                    433: Exit status
                    434: .PP
                    435: When a command exits, it returns status to the program that executed it.
                    436: On UNIX, status is a small positive number, with zero indicating normal termination
                    437: and non-zero values encoding error conditions (in a non-standard way).  If a
                    438: UNIX command terminates abnormally rather than by executing
                    439: .CW exit (2),
                    440: .I rc
                    441: takes the status to be 1000 plus the termination status provided to
                    442: .CW wait (2).
                    443: On Plan 9 status is a character string describing an error condition.
                    444: On normal termination it is empty.
                    445: .PP
                    446: .I Rc
                    447: captures commands' exit statuses in the variable
                    448: .CW $status .
                    449: For a simple command, the value of
                    450: .CW $status
                    451: is just as described above.  For a pipeline,
                    452: .CW $status
                    453: is set to the concatenation of the statuses of the pipeline components,
                    454: with
                    455: .CW |
                    456: characters for separators.
                    457: .PP
                    458: .I Rc
                    459: has a number of command forms that various kinds of control flow,
                    460: many of them conditioned by the status returned from previously
                    461: executed commands.  In all cases, any
                    462: .CW $status
                    463: containing only
                    464: .CW 0 's
                    465: and
                    466: .CW | 's
                    467: has boolean value
                    468: .I true .
                    469: Any other status is
                    470: .I false .
                    471: .NH
                    472: Flow of control
                    473: .PP
                    474: .I Rc
                    475: will accept multiple commands on a line, separated by
                    476: .CW &
                    477: or
                    478: .CW ; .
                    479: A command followed by
                    480: .CW &
                    481: is executed asynchronously \(em
                    482: .I rc
                    483: does not wait for it to exit, and it
                    484: disconnects its standard input from the terminal,
                    485: redirecting it to
                    486: .CW /dev/null
                    487: so that the command and
                    488: .I rc
                    489: do not compete for input lines.
                    490: The process id of an asynchronous command is stored in the variable
                    491: .CW $apid ,
                    492: and if
                    493: .I rc
                    494: is running interactively (that is, its input is coming from a terminal),
                    495: the process id is printed when the command starts.
                    496: .PP
                    497: Commands separated by
                    498: .CW ;
                    499: are executed in sequence, but
                    500: .I rc
                    501: waits for the first command to terminate before starting the second.
                    502: Thus
                    503: .P1
                    504: fortune;fortune&
                    505: .P2
                    506: prints out two fortunes (and a process id), not waiting for the
                    507: second to appear before prompting for more commands.
                    508: .NH
                    509: Command grouping
                    510: .PP
                    511: A sequence of commands enclosed in
                    512: .CW {}
                    513: may be used anywhere a command is required.
                    514: For example:
                    515: .P1
                    516: {sleep 3600;echo 'Time''s up!'}&
                    517: .P2
                    518: will wait an hour in the background, then print a message.
                    519: Without the braces:
                    520: .P1
                    521: sleep 3600;echo 'Time''s up!'&
                    522: .P2
                    523: this would lock up the terminal for an hour,
                    524: then print the message in the background!
                    525: .NH
                    526: Conditional execution \(em \f(CW&&\fP and \f(CW||\fP
                    527: .PP
                    528: A pair of commands may be separated by
                    529: .CW &&
                    530: or
                    531: .CW || .
                    532: In either case, the first command is executed and its
                    533: status examined.
                    534: If the operator is
                    535: .CW &&
                    536: and the status is
                    537: .I true ,
                    538: the second command is executed.
                    539: If the operator is
                    540: .CW ||
                    541: the status must be
                    542: .I false
                    543: to execute the second command.
                    544: Thus
                    545: .P1
                    546: cyntax *.c && cc -g -o cmd *.c
                    547: .P2
                    548: compiles
                    549: .CW cmd
                    550: only if
                    551: .CW cyntax
                    552: passes on it, and
                    553: .P1
                    554: {sleep 86400;rm -r /junk} ||
                    555:     echo Failure!|mail td &
                    556: .P2
                    557: waits 24 hours, then tries to remove all files in
                    558: .CW /junk .
                    559: On failure it sends me mail.  It does all of this in
                    560: the background, so I can use my terminal for something
                    561: else in the interim.
                    562: .NH
                    563: Subshells
                    564: .PP
                    565: The
                    566: .CW @
                    567: operator executes the following command in a new process.
                    568: This is useful primarily to insulate the parent process
                    569: from the effects of built-in commands, like this
                    570: .P1
                    571: @ {cd /elsewhere;tar cf - .} |
                    572:     tar -xf -
                    573: .P2
                    574: This dubious but venerated idiom copies
                    575: the contents of
                    576: .CW /elsewhere
                    577: to the current directory by building a
                    578: .CW tar
                    579: file on standard output and immediately
                    580: cracking it at the other end of a pipe.
                    581: The first
                    582: .CW tar
                    583: runs in
                    584: .CW /elsewhere ,
                    585: but, because of the
                    586: .CW @ ,
                    587: the second operates in the original directory.
                    588: .NH
                    589: Control flow \(em \f(CWfor\fP
                    590: .PP
                    591: A command may be executed once for each member of a list
                    592: by typing, for example:
                    593: .P1
                    594: for(i in printf scanf putchar)
                    595:     look $i /usr/td/lib/dw.dat
                    596: .P2
                    597: This looks for each of the words
                    598: .CW printf ,
                    599: .CW scanf
                    600: and
                    601: .CW putchar
                    602: in the given file.
                    603: The general form is
                    604: .P1
                    605: for(\fIname\fP in \fIlist\fP)
                    606:     \fIcommand\fP
                    607: .P2
                    608: or
                    609: .P1
                    610: for(\fIname\fP)
                    611:     \fIcommand\fP
                    612: .P2
                    613: In the first case,
                    614: .I command
                    615: is executed once for each member of
                    616: .I list ,
                    617: with that member assigned to variable
                    618: .I name .
                    619: If
                    620: .CI in " list
                    621: is not given,
                    622: .I $*
                    623: is used.
                    624: .NH
                    625: Conditional execution \(em \f(CWif\fP
                    626: .PP
                    627: .I Rc
                    628: also provides a general if-statement.  For example:
                    629: .P1
                    630: if(cyntax *.c)
                    631:     cc -g -o cmd *.c
                    632: .P2
                    633: is equivalent to the similar example above.
                    634: An `if not' statement provides a two-tailed conditional.
                    635: For example:
                    636: .P1
                    637: for(i){
                    638:     if(test -f /tmp/$i)
                    639:         echo $i already in /tmp
                    640:     if not
                    641:         cp $i /tmp
                    642: }
                    643: .P2
                    644: This loops over each file in
                    645: .CW $* ,
                    646: copying to
                    647: .CW /tmp
                    648: those that do not already appear there, and
                    649: printing a message for those that do.
                    650: .NH
                    651: Control flow \(em \f(CWwhile\fP
                    652: .PP
                    653: .I Rc 's
                    654: while statement looks like this:
                    655: .P1
                    656: while(newer subr.c subr.o) sleep 5
                    657: .P2
                    658: This waits until
                    659: .CW subr.o
                    660: is newer than
                    661: .CW subr.c
                    662: (presumably because the C compiler finished with it.)
                    663: .NH
                    664: Control flow \(em \f(CWswitch\fP
                    665: .PP
                    666: .I Rc
                    667: provides a switch statement to do pattern-matching on
                    668: arbitrary strings.  Its general form is
                    669: .P1
                    670: switch(\fIword\fP){
                    671: case \fIpattern ...\fP
                    672:     \fIcommands\fP
                    673: case \fIpattern ...\fP
                    674:     \fIcommands\fP
                    675: ...
                    676: }
                    677: .P2
                    678: .I Rc
                    679: attempts to match the word against the patterns in each case statement in turn.
                    680: Patterns are the same as for filename matching, except that
                    681: .CW /
                    682: and the first characters of
                    683: .CW .
                    684: and
                    685: .CW ..
                    686: need not be matched explicitly.
                    687: .PP
                    688: If any pattern matches, the
                    689: commands following that case up to
                    690: the next case (or the end of the switch)
                    691: are executed, and execution of the switch
                    692: is complete.  For example,
                    693: .P1
                    694: switch($#*){
                    695: case 1
                    696:     cat >>$1
                    697: case 2
                    698:     cat >>$2 <$1
                    699: case *
                    700:     echo 'Usage: append [from] to'
                    701: }
                    702: .P2
                    703: is an append command.  Called with one file argument,
                    704: it tacks standard input to its end.  With two, the
                    705: first is appended to the second.  Any other number
                    706: elicits a usage message.
                    707: .PP
                    708: The built-in
                    709: .CW ~
                    710: command also matches patterns, and is often more concise than a switch.
                    711: Its arguments are a string and a list of patterns.  It sets
                    712: .CW $status
                    713: to zero if and only if any of the patterns matches the string.
                    714: The following example processes option arguments for the
                    715: .I man (1)
                    716: command:
                    717: .P1
                    718: opt=()
                    719: while(~ $1 -* [1-9] 10){
                    720:     switch($1){
                    721:     case [1-9] 10
                    722:         sec=$1 secn=$1
                    723:     case -f
                    724:         c=f s=f
                    725:     case -[qwnt]
                    726:         cmd=$1
                    727:     case -T*
                    728:         T=$1
                    729:     case -*
                    730:         opt=($opt $1)
                    731:     }
                    732:     shift
                    733: }
                    734: .P2
                    735: .NH
                    736: Functions
                    737: .PP
                    738: Functions may be defined by typing
                    739: .P1
                    740: fn \fIname\fP { \fIcommands\fP }
                    741: .P2
                    742: Subsequently, whenever a command named
                    743: .I name
                    744: is encountered, the remainder of the command's
                    745: argument list will assigned to
                    746: .CW $*
                    747: and
                    748: .I rc
                    749: will execute the
                    750: .I commands .
                    751: The value of
                    752: .CW $*
                    753: will be restored on completion.
                    754: For example:
                    755: .P1
                    756: fn g {
                    757:     gre -e $1 *.[hcyl]
                    758: }
                    759: .P2
                    760: defines
                    761: .CI g " pattern
                    762: to look for occurrences of
                    763: .I pattern
                    764: in all program source files in the current directory.
                    765: .PP
                    766: Function definitions are deleted by writing
                    767: .P1
                    768: fn \fIname\fP
                    769: .P2
                    770: with no function body.
                    771: .....
                    772: .NH
                    773: Command execution
                    774: .PP
                    775: Up to now we've said very little about what
                    776: .I rc
                    777: does to execute a simple command.
                    778: If the command name is the name of a function defined using
                    779: .CW fn ,
                    780: the function is executed.
                    781: Otherwise, if it is the name of a built-in command, the
                    782: built-in is executed directly by
                    783: .I rc .
                    784: Otherwise, if the name contains a
                    785: .CW / ,
                    786: it is taken to be the name of a binary program
                    787: and is executed using
                    788: .I exec (2).
                    789: If the name contains no
                    790: .CW / ,
                    791: then directories mentioned in the variable
                    792: .CW $path
                    793: are searched until an executable file is found.
                    794: .NH
                    795: Built-in commands
                    796: .PP
                    797: Several commands are executed internally by
                    798: .I rc ,
                    799: usually because their execution changes or depends on
                    800: .I rc 's
                    801: internal state.
                    802: .TP ". [-i] \fIfile ...\fT
                    803: Execute commands from
                    804: .I file .
                    805: .CW $*
                    806: is set for the duration to the reminder of the argument list following
                    807: .I file .
                    808: .CW $path
                    809: is used to search for
                    810: .I file .
                    811: Option
                    812: .CW -i
                    813: indicates interactive input \(mi a prompt
                    814: (found in
                    815: .CW $prompt )
                    816: is printed before each command is read.
                    817: .TP "builtin \fIcommand ...\fT
                    818: Execute
                    819: .I command
                    820: as usual except that any function named
                    821: .I command
                    822: is ignored.
                    823: For example,
                    824: .P1
                    825: fn cd{
                    826:     builtin cd $* && pwd
                    827: }
                    828: .P2
                    829: defines a replacement for the
                    830: .CW cd
                    831: built-in (see below) that announces the full name of the new directory.
                    832: .TP "cd [\fIdir\fT]
                    833: Change the current directory to
                    834: .I dir .
                    835: The default argument is
                    836: .CW $home .
                    837: .CW $cdpath
                    838: is a list of places in which to search for
                    839: .I dir .
                    840: .TP "eval [\fIarg ...\fT]
                    841: The arguments are concatenated separated by spaces into a string, read as input to
                    842: .I rc ,
                    843: and executed.  For example,
                    844: .P1
                    845: x='$y'
                    846: y=Doody
                    847: eval echo Howdy, $x
                    848: .P2
                    849: would echo
                    850: .P1
                    851: Howdy, Doody
                    852: .P2
                    853: since arguments of
                    854: .CW eval
                    855: would be
                    856: .P1
                    857: Howdy, $y
                    858: .P2
                    859: .TP "exec \fIcommand ...\fT
                    860: .I Rc
                    861: replaces itself with the given non-built-in
                    862: .I command .
                    863: .TP "exit [\fIstatus\fP]
                    864: Exit with the given status.  If none is given, the current value of
                    865: .CW $status
                    866: is used.
                    867: .TP finit
                    868: Initialize functions imported from the environment.
                    869: Intended for use only by
                    870: .I rc 's
                    871: initialization procedure.
                    872: Currently this is non-functional on Plan 9, as no
                    873: means of environmental function-storage yet exists.
                    874: .TP "flag \fIletter\fP"
                    875: Sets
                    876: .CW $status
                    877: to zero if and only if
                    878: .I rc
                    879: was invoked with option
                    880: .CI - letter
                    881: set.  Intended for use by
                    882: .I rc 's
                    883: initialization procedure.
                    884: .TP "mount \fInew old\fT
                    885: (Plan 9 only.)
                    886: Mount the name
                    887: .I new
                    888: on
                    889: .I old .
                    890: .TP "shift [\fIn\fT]
                    891: Delete the first
                    892: .I n
                    893: (default 1) elements of
                    894: .CW $* .
                    895: .TP "umask [\fIoctal\fP]
                    896: (UNIX only.)  Set
                    897: .I rc 's
                    898: file creation mask to the given octal value.
                    899: If no value is given, the current mask value is printed.
                    900: .TP "unmount [\fInew\fT] \fIold
                    901: (Plan 9 only.)
                    902: Unmount the name
                    903: .I old .
                    904: If
                    905: .I new
                    906: is given, unmount
                    907: .I old
                    908: from
                    909: .I new .
                    910: .TP "wait [\fIpid\fP]
                    911: Wait for the process with the given
                    912: .I pid
                    913: to exit.  If no
                    914: .I pid
                    915: is given, all outstanding processes are waited for.
                    916: .TP "whatis \fIname ...\fT
                    917: Print the value of each
                    918: .I name
                    919: in a form suitable for input to
                    920: .I rc .
                    921: The output is an assignment to any variable, the definition of any function,
                    922: a call to
                    923: .CW builtin
                    924: for any built-in command, or the full path name of any binary program.
                    925: For example,
                    926: .P1
                    927: whatis path g cd who
                    928: .P2
                    929: might print
                    930: .P1
                    931: path=(. /bin /usr/bin)
                    932: fn g {gre -e $1 *.[hycl]}
                    933: builtin cd
                    934: /bin/who
                    935: .P2
                    936: .TP "~ \fIsubject pattern ...
                    937: The
                    938: .I subject
                    939: is matched against each
                    940: .I pattern
                    941: in turn.  On a match,
                    942: .CW $status
                    943: is set to zero.
                    944: Otherwise, it is set to one.
                    945: Patterns are the same as for filename matching,
                    946: except that
                    947: .CW /
                    948: and the first character of
                    949: .CW .
                    950: and
                    951: .CW ..
                    952: need not be matched explicitly.
                    953: The
                    954: .I patterns
                    955: are not subjected to filename replacement before the
                    956: .CW ~
                    957: command is executed, so they need not be enclosed in
                    958: quotation marks, unless of course, a literal match for
                    959: .CW *
                    960: .CW [
                    961: or
                    962: .CW ?
                    963: is required.
                    964: For example
                    965: .P1
                    966: ~ $1 ?
                    967: .P2
                    968: matches any single character, whereas
                    969: .P1
                    970: ~ $1 '?'
                    971: .P2
                    972: only matches a literal question mark.
                    973: .NH
                    974: Special variables
                    975: .PP
                    976: Several variables are set internally by
                    977: .I rc
                    978: or used to guide its execution.
                    979: .TP $*
                    980: Set to
                    981: .I rc 's
                    982: argument list during initialization.
                    983: A
                    984: .CW .
                    985: command or function execution saves
                    986: .CW $*
                    987: on a stack and sets it to the new argument list.  The saved
                    988: value is restored on completion.
                    989: .TP $apid
                    990: Whenever a process is started asynchronously with
                    991: .CW & ,
                    992: .CW $apid
                    993: receives its process id.
                    994: .TP $cflag
                    995: Set to the string provided on
                    996: .I rc 's
                    997: command line with the
                    998: .CW -c
                    999: option, if any.  This is provided for the
                   1000: use of
                   1001: .I rc's initialization procedure.
                   1002: .TP $home
                   1003: The default directory for
                   1004: .CW cd .
                   1005: On UNIX, if
                   1006: .CW $home
                   1007: is not initially set, and
                   1008: .CW $HOME
                   1009: is, then
                   1010: .CW $home
                   1011: is set to
                   1012: .CW $HOME .
                   1013: .TP $ifs
                   1014: The input field separators used in command substitution.
                   1015: If not set in
                   1016: .I rc 's
                   1017: environment, it is initialized to blank, tab and newline.
                   1018: .TP $path
                   1019: The search path used to find commands and input files for the
                   1020: .CW .
                   1021: command.
                   1022: If not set in the environment, it is initialized to
                   1023: .CW "(. /bin /usr/bin)
                   1024: on UNIX,
                   1025: .CW "(. /bin)
                   1026: on Plan 9.
                   1027: .TP $pid
                   1028: Set during initialization to
                   1029: .I rc 's
                   1030: process id.
                   1031: .TP $prompt
                   1032: When
                   1033: .I rc
                   1034: is run interactively, the first member of
                   1035: .CW $prompt
                   1036: is printed before reading each command.
                   1037: The second member is printed if
                   1038: .I rc
                   1039: expects a command to be continued on another line.
                   1040: If not set in the environment,
                   1041: .I rc
                   1042: initializes it to
                   1043: .CW "('% ' '   ')" .
                   1044: .TP $status
                   1045: On UNIX, this is set to the low 8 bits of the
                   1046: .I exit (2)
                   1047: argument of a normally terminating binary (unless started with
                   1048: .CW & ),
                   1049: or to 1000 plus the termination status on abnormal termination.
                   1050: On Plan 9,
                   1051: .CW $status
                   1052: is set to the process's termination message.
                   1053: On either system, the statuses of all processes in a pipeline
                   1054: are captured and concatenated, separated by
                   1055: .CW |
                   1056: characters.
                   1057: .CW !
                   1058: and
                   1059: .CW ~
                   1060: also set
                   1061: .CW $status .
                   1062: Its value is used to control execution in
                   1063: .CW && ,
                   1064: .CW || ,
                   1065: .CW if
                   1066: and
                   1067: .CW while
                   1068: commands.
                   1069: When
                   1070: .I rc
                   1071: exits at end-of-file of its input or on executing an
                   1072: .CW exit
                   1073: command with no argument,
                   1074: .CW $status
                   1075: is its exit status.
                   1076: (This is only strictly true on Plan 9.  On UNIX, the exit status
                   1077: must be numeric.  Therefore, if the value of
                   1078: .CW $status
                   1079: contains
                   1080: .CW |
                   1081: characters, they are deleted before converting it to a number, and if
                   1082: .CW $status
                   1083: contains other non-numeric characters,
                   1084: .I rc
                   1085: exits with status 1.)
                   1086: .NH
                   1087: Advanced I/O Redirection
                   1088: .PP
                   1089: .I Rc
                   1090: allows redirection of file descriptors other than 0 and 1
                   1091: (standard input and output) by specifying the file descriptor
                   1092: in square brackets
                   1093: .CW "[ ]
                   1094: after the
                   1095: .CW <
                   1096: or
                   1097: .CW > .
                   1098: For example,
                   1099: .P1
                   1100: cc junk.c >[2]junk.diag
                   1101: .P2
                   1102: saves the compiler's diagnostics in
                   1103: .CW junk.diag .
                   1104: .PP
                   1105: File descriptors may be replaced by a copy, in the sense of
                   1106: .I dup (2),
                   1107: of an already-open file by typing, for example
                   1108: .P1
                   1109: cc junk.c >[2=1]
                   1110: .P2
                   1111: This replaces file descriptor 2 with a copy of file descriptor 1.
                   1112: It is more useful in conjunction with other redirections, like this
                   1113: .P1
                   1114: cc junk.c >junk.out >[2=1]
                   1115: .P2
                   1116: Redirections are evaluated from left to right, so this redirects
                   1117: file descriptor 1 to
                   1118: .CW junk.out ,
                   1119: then points file descriptor 2 at the same file.
                   1120: By contrast,
                   1121: .P1
                   1122: cc junk.c >[2=1] >junk.out
                   1123: .P2
                   1124: Redirects file descriptor 2 to a copy of file descriptor 1
                   1125: (presumably the terminal), and then directs file descriptor 1
                   1126: at a file.  In the first case, standard and diagnostic output
                   1127: will be intermixed in
                   1128: .CW junk.out .
                   1129: In the second, diagnostic output will appear on the terminal,
                   1130: and standard output will be sent to the file.
                   1131: .PP
                   1132: File descriptors may be closed by using the duplication notation
                   1133: with an empty right-hand side.
                   1134: For example,
                   1135: .P1
                   1136: cc junk.c >[2=]
                   1137: .P2
                   1138: will discard diagnostics from the compilation.
                   1139: Often closing a file descriptor will not have the
                   1140: expected effect, because many UNIX programs do not
                   1141: behave politely when started with file descriptors
                   1142: 0, 1 or 2 closed.  Consider, for example,
                   1143: .P1
                   1144: who | tee a b c >[1=]
                   1145: .P2
                   1146: One might expect this to produce copies of the output of
                   1147: .CW who
                   1148: on files
                   1149: .CW a ,
                   1150: .CW b
                   1151: and
                   1152: .CW c ,
                   1153: discarding the copy that
                   1154: .CW tee
                   1155: normally writes on its standard output.
                   1156: However,
                   1157: .CW tee
                   1158: does not check for its standard output being closed.
                   1159: When it opens
                   1160: .CW a ,
                   1161: the file descriptor returned is 1, and unsurprisingly,
                   1162: .CW tee
                   1163: writes two interleaved copies of its input onto
                   1164: .CW a .
                   1165: It is better explicitly to direct the output at
                   1166: .CW /dev/null .
                   1167: .PP
                   1168: Arbitrary file descriptors may be sent through
                   1169: a pipe by typing, for example
                   1170: .P1
                   1171: cc junk.c |[2] grep -v '^$'
                   1172: .P2
                   1173: This deletes those ever-so-annoying blank lines
                   1174: from the C compiler's output.  Note that the output
                   1175: of
                   1176: .CW grep
                   1177: still appears on file descriptor 1.
                   1178: .PP
                   1179: Very occasionally you may wish to connect the input side of
                   1180: a pipe to some file descriptor other than zero.
                   1181: The notation
                   1182: .P1
                   1183: cmd1 |[5=19] cmd2
                   1184: .P2
                   1185: creates a pipeline with
                   1186: .CW cmd1 's
                   1187: file descriptor 5 connected through a pipe to
                   1188: .CW cmd2 's
                   1189: file descriptor 19.
                   1190: .NH
                   1191: Here documents
                   1192: .PP
                   1193: .I Rc
                   1194: procedures may include data, called ``here documents'',
                   1195: to be provided as input to commands, as in this version of the
                   1196: .I tel
                   1197: command
                   1198: .P1
                   1199: for(i) grep $i <<!
                   1200: ...
                   1201: nls 2T-402 2912
                   1202: norman 2C-514 2842
                   1203: pjw 2T-502 7214
                   1204: ...
                   1205: !
                   1206: .P2
                   1207: A here document is introduced by the redirection symbol
                   1208: .CW << ,
                   1209: followed by an arbitrary eof marker
                   1210: .CW ! "" (
                   1211: in the example).  Lines following the command,
                   1212: up to a line containing only the eof marker are saved
                   1213: in a temporary file that it connected to the command's
                   1214: standard input when it is run.
                   1215: .PP
                   1216: .I Rc
                   1217: does variable substitution in here documents.  The following
                   1218: .I subst
                   1219: command:
                   1220: .P1
                   1221: ed $3 <<EOF
                   1222: g/$1/s//$2/g
                   1223: w
                   1224: EOF
                   1225: .P2
                   1226: changes all occurrences of
                   1227: .CW $1
                   1228: to
                   1229: .CW $2
                   1230: in file
                   1231: .CW $3 .
                   1232: To include a literal
                   1233: .CW $
                   1234: in a here document, type
                   1235: .CW $$ .
                   1236: If the name of a variable is followed immediately by
                   1237: .CW ^ ,
                   1238: the caret is deleted.
                   1239: .PP
                   1240: Variable substitution can be entirely suppressed by enclosing
                   1241: the eof marker following
                   1242: .CW <<
                   1243: in quotation marks.
                   1244: .PP
                   1245: Here documents may be provided on file descriptors other than 0 by typing, for example
                   1246: .P1
                   1247: cmd <<[4]End
                   1248: ...
                   1249: End
                   1250: .P2
                   1251: .NH
                   1252: Signals
                   1253: .PP
                   1254: .I Rc
                   1255: scripts normally terminate when an interrupt is received from the terminal.
                   1256: A function with the name of a signal, in lower case, is defined in the usual way,
                   1257: but called when
                   1258: .I rc
                   1259: receives the signal.  Signals of interest are:
                   1260: .TP sighup
                   1261: Hangup.  The controlling teletype has disconnected from
                   1262: .I rc .
                   1263: .TP sigint
                   1264: The interrupt character (usually ASCII del) was typed on the controlling terminal.
                   1265: .TP sigquit
                   1266: The quit character (usually ASCII fs, ctrl-\e) was typed on the controlling terminal.
                   1267: .TP sigterm
                   1268: This signal is normally sent by
                   1269: .I kill (1).
                   1270: .TP sigexit
                   1271: An artificial signal sent when
                   1272: .I rc
                   1273: is about to exit.
                   1274: .LP
                   1275: As an example,
                   1276: .P1
                   1277: fn sigint{
                   1278:     rm /tmp/junk
                   1279:     exit
                   1280: }
                   1281: .P2
                   1282: sets a trap for the keyboard interrupt that
                   1283: removes a temporary file before exiting.
                   1284: .PP
                   1285: Signals will be ignored if the signal routine is set to
                   1286: .CW {} .
                   1287: Signals revert to their default behavior when their handlers'
                   1288: definitions are deleted.
                   1289: .NH
                   1290: Environment
                   1291: .PP
                   1292: The environment is a list of name-value pairs made available to
                   1293: executing binaries.  On UNIX the environment is passed
                   1294: to commands as a second argument list containing
                   1295: an entry for each variable whose value is non-empty, and
                   1296: an entry for each function.  UNIX does not directly support
                   1297: environment entries containing multiple strings, so if a variable
                   1298: has more than one component, these are separated by ctrl-a
                   1299: .CW \e001 ) (
                   1300: characters.
                   1301: .PP
                   1302: On Plan 9, the environment is stored in a file system named
                   1303: .CW #e ,
                   1304: normally mounted on
                   1305: .CW /env .
                   1306: The value of each variable is stored in a separate file, with components
                   1307: terminated by ASCII nuls.
                   1308: (This is not quite as horrendous as it sounds, the file system is
                   1309: maintained entirely in core, so no disk or network access is involved.)
                   1310: The contents of
                   1311: .CW /env
                   1312: are shared on a per-process group basis \(mi when a new process group is
                   1313: created it effectively attaches
                   1314: .CW /env
                   1315: to a new file system initialized with a copy of the old one.
                   1316: A consequence of this organization is that commands can change environment
                   1317: entries and see the changes reflected in
                   1318: .I rc .
                   1319: This is not possible on UNIX, as the environment is passed to children by
                   1320: .I exec (2),
                   1321: but is not passed back by
                   1322: .I fork (2)
                   1323: and
                   1324: .I wait (2).
                   1325: .PP
                   1326: There is not currently a way on Plan 9 to place functions in the environment,
                   1327: although this could easily done by mounting another instance of
                   1328: .CW #e
                   1329: on another directory.  The problem is that currently there can be only one instance of
                   1330: .CW #e
                   1331: per process group.
                   1332: .NH
                   1333: Local Variables
                   1334: .PP
                   1335: It is often useful to set a variable for the duration
                   1336: of a single command.  An assignment followed by a command
                   1337: has this effect.  For example
                   1338: .P1
                   1339: a=global
                   1340: a=local echo $a
                   1341: echo $a
                   1342: .P2
                   1343: will print
                   1344: .P1
                   1345: local
                   1346: global
                   1347: .P2
                   1348: This works even for compound commands, like
                   1349: .P1
                   1350: f=/fairly/long/file/name {
                   1351:     {   wc $f
                   1352:         spell $f
                   1353:         diff $f.old $f
                   1354:     } | pr -h 'Facts about '$f |
                   1355:         lp -ddp
                   1356: }
                   1357: .P2
                   1358: .NH
                   1359: Invocation
                   1360: .PP
                   1361: When
                   1362: .I rc
                   1363: starts, it digests its option arguments, initializes variables
                   1364: and functions from the environment, sets
                   1365: .CW $* ,
                   1366: .CW $pid
                   1367: and, if the
                   1368: .CW -c
                   1369: option is given,
                   1370: .CW $cflag ,
                   1371: and starts reading commands.
                   1372: .PP
                   1373: Most of
                   1374: .I rc 's
                   1375: initialization is done in a command file that is run at startup.
                   1376: On UNIX the file is called
                   1377: .CW /usr/lib/rcmain .
                   1378: On Plan 9 it is
                   1379: .CW /sys/lib/rcmain .
                   1380: .LP
                   1381: Legal options are:
                   1382: .TP "-c \fIstring
                   1383: Commands are read from
                   1384: .I string .
                   1385: .TP -e
                   1386: Exit if
                   1387: .CW $status
                   1388: is non-zero after executing any simple command.
                   1389: .TP -i
                   1390: Interactive mode.
                   1391: Also set if
                   1392: .I rc
                   1393: is given no arguments and its standard input is a terminal,
                   1394: as determined by
                   1395: .I isatty (3)
                   1396: on UNIX, or by presumption on Plan 9.
                   1397: Commands are prompted for using
                   1398: .CW $prompt .
                   1399: .CW SIGINT
                   1400: and
                   1401: .CW SIGQUIT
                   1402: are caught and sloughed off.
                   1403: .TP -I
                   1404: Non-interactive mode.
                   1405: Suppresses interactive mode even if
                   1406: .I rc
                   1407: is given no arguments and its standard input is a terminal.
                   1408: .TP -l
                   1409: Login mode.
                   1410: Also set if the first character of argument zero is
                   1411: .CW - 
                   1412: (this is an obscure UNIX convention).
                   1413: .I Rc
                   1414: reads commands from
                   1415: .CW $home/.rcrc ,
                   1416: if it exists, before reading its normal input.
                   1417: .TP -p
                   1418: Protected mode.
                   1419: .CW $path
                   1420: is set to
                   1421: .CW "(/bin /usr/bin)
                   1422: on UNIX, or
                   1423: .CW "/bin
                   1424: on Plan 9, regardless of the setting in the environment.
                   1425: Furthermore, functions are not initialized from the environment.
                   1426: This provides a ``protected environment'' in which it is
                   1427: difficult for malicious users to subvert an
                   1428: .I rc
                   1429: script by placing Trojan-horse versions of commands in
                   1430: the environment or an unprotected directory.  On Plan 9 this is
                   1431: not much use, since the meaning of all names, including those in
                   1432: .CW /bin ,
                   1433: is determined by the user.
                   1434: .TP -v
                   1435: Echo input on file descriptor 2 (diagnostic output) as it is read.
                   1436: Useful for clarifying syntax problems in
                   1437: .I rc
                   1438: scripts.
                   1439: .TP -x
                   1440: Print each simple command on diagnostic output before executing it.
                   1441: Useful for debugging
                   1442: .I rc
                   1443: scripts.
                   1444: .PP
                   1445: The following flags are useful primarily for debugging
                   1446: .I rc .
                   1447: .TP -d
                   1448: Causes
                   1449: .I rc
                   1450: only to catch
                   1451: .CW SIGINT ,
                   1452: so that
                   1453: .CW SIGQUIT
                   1454: will cause it to dump core.
                   1455: .TP -r
                   1456: .I Rc 's
                   1457: interpreter will print a running commentary on its state.
                   1458: This is useful only for debugging
                   1459: .I rc .
                   1460: .TP -V
                   1461: Echo input on diagnostic output as it is read, including
                   1462: .CW rcmain ,
                   1463: which is normally suppressed when using
                   1464: .CW -v .
                   1465: .NH
                   1466: Examples \(em \fIcd, pwd\fP
                   1467: .PP
                   1468: Here is a pair of functions that provide
                   1469: enhanced versions of the standard
                   1470: .CW cd
                   1471: and
                   1472: .CW pwd
                   1473: commands.  (Thanks to Rob Pike for these.)
                   1474: .P1
                   1475: ps1='% '       # default prompt
                   1476: tab='  '       # a tab character
                   1477: fn pbd{
                   1478:   /bin/pwd|sed 's;.*/;;'
                   1479: }
                   1480: fn cd{
                   1481:   builtin cd $1 &&
                   1482:   switch($#*){
                   1483:   case 0
                   1484:     dir=$home
                   1485:     prompt=($ps1 $tab)
                   1486:   case *
                   1487:     switch($1)
                   1488:     case /*
                   1489:       dir=$1
                   1490:       prompt=(`{pbd}^$ps1 $tab)
                   1491:     case */* ..*
                   1492:       dir=()
                   1493:       prompt=(`{pbd}^$ps1 $tab)
                   1494:     case *
                   1495:       dir=()
                   1496:       prompt=($1^$ps1 $tab)
                   1497:     }
                   1498:   }
                   1499: }
                   1500: fn pwd{
                   1501:   if(~ $#dir 0)
                   1502:     dir=`{/bin/pwd}
                   1503:   echo $dir
                   1504: }
                   1505: .P2
                   1506: Function
                   1507: .CW pwd
                   1508: is a version of the standard
                   1509: .CW pwd
                   1510: that caches its value in variable
                   1511: .CW $dir ,
                   1512: because the genuine
                   1513: .CW pwd
                   1514: can be quite slow to execute.
                   1515: .PP
                   1516: Function
                   1517: .CW pbd
                   1518: is a helper that prints the last component of a directory name.
                   1519: Function
                   1520: .CW cd
                   1521: calls the
                   1522: .CW cd
                   1523: built-in, and checks that it was successful.
                   1524: If so, it sets
                   1525: .CW $dir
                   1526: and
                   1527: .CW $prompt .
                   1528: The prompt will include the last component of the
                   1529: current directory (except in the home directory,
                   1530: where it will be null), and
                   1531: .CW $dir
                   1532: will be reset either to the correct value or to
                   1533: .CW () ,
                   1534: so that the
                   1535: .CW pwd
                   1536: function will work correctly.
                   1537: .NH
                   1538: Examples \(em \fIman\fP
                   1539: .PP
                   1540: The
                   1541: .I man
                   1542: command prints pages from of the UNIX Programmer's Manual.
                   1543: It is called, for example, as
                   1544: .P1
                   1545: man 3 isatty
                   1546: man rc
                   1547: man -t cat
                   1548: .P2
                   1549: In the first case, the page for
                   1550: .I isatty
                   1551: in section 3 is printed.
                   1552: In the second case, the manual page for
                   1553: .I rc
                   1554: is printed.  Since no manual section is specified,
                   1555: all sections are searched for the page, and it is found
                   1556: in section 1.
                   1557: In the third case, the page for
                   1558: .I cat
                   1559: is typeset (the
                   1560: .CW -t
                   1561: option).
                   1562: .P1
                   1563: cd /n/bowell/usr/man || {
                   1564:   echo $0: Manual not on line! >[1=2]
                   1565:   exit 1
                   1566: }
                   1567: NT=n  # default nroff
                   1568: s='*' # section, default try all
                   1569: for(i) switch($i){
                   1570: case -t
                   1571:   NT=t
                   1572: case -n
                   1573:   NT=n
                   1574: case -*
                   1575:   echo Usage: $0\e
                   1576:     '[-nt] [section] page ...' >[1=2]
                   1577:   exit 1
                   1578: case [1-9] 10
                   1579:   s=$i
                   1580: case *
                   1581:   eval 'pages=man'$s/$i'.*'
                   1582:   for(page in $pages){
                   1583:     if(test -f $page)
                   1584:       $NT^roff -man $page
                   1585:     if not
                   1586:       echo $0: $i not found >[1=2]
                   1587:   }
                   1588: }
                   1589: .P2
                   1590: Note the use of
                   1591: .CW eval
                   1592: to make a list of candidate manual pages.
                   1593: Without
                   1594: .CW eval ,
                   1595: the
                   1596: .CW *
                   1597: stored in
                   1598: .CW $s
                   1599: would not trigger filename matching
                   1600: \(em it's enclosed in quotation marks,
                   1601: and even if it weren't, it would be expanded
                   1602: when assigned to
                   1603: .CW $s .
                   1604: Eval causes its arguments
                   1605: to be re-processed by
                   1606: .I rc 's
                   1607: parser and interpreter, effectively delaying
                   1608: evaluation of the
                   1609: .CW *
                   1610: until the assignment to
                   1611: .CW $pages .
                   1612: .NH
                   1613: Examples \(em \fIholmdel\fP
                   1614: .PP
                   1615: The following
                   1616: .I rc
                   1617: script plays the deceptively simple game
                   1618: .I holmdel ,
                   1619: in which the players alternately name Bell Labs locations,
                   1620: the winner being the first to mention Holmdel.
                   1621: .KF
                   1622: .P1
                   1623: t=/tmp/holmdel$pid
                   1624: fn read{
                   1625:        $1=`{awk '{print;exit}'}
                   1626: }
                   1627: ifs='
                   1628: \&'    # just a newline
                   1629: fn sigexit sigint sigquit sighup{
                   1630:        rm -f $t
                   1631:        exit
                   1632: }
                   1633: cat <<'!' >$t
                   1634: Allentown 
                   1635: Atlanta
                   1636: Cedar Crest
                   1637: Chester
                   1638: Columbus
                   1639: Elmhurst
                   1640: Fullerton
                   1641: Holmdel
                   1642: Indian Hill
                   1643: Merrimack Valley
                   1644: Morristown
                   1645: Piscataway
                   1646: Reading
                   1647: Short Hills
                   1648: South Plainfield
                   1649: Summit
                   1650: Whippany
                   1651: West Long Branch
                   1652: !
                   1653: while(true){
                   1654:    lab=`{/usr/games/fortune $t}
                   1655:    echo $lab
                   1656:    if(~ $lab Holmdel){
                   1657:       echo You lose.
                   1658:       exit
                   1659:    }
                   1660:    while(read lab
                   1661:           ! grep -i -s $lab $t)
                   1662:       echo No such location.
                   1663:    if(~ $lab [hH]olmdel){
                   1664:       echo You win.
                   1665:       exit
                   1666:    }
                   1667: }
                   1668: .P2
                   1669: .KE
                   1670: .LP
                   1671: This script is worth describing in detail
                   1672: (rather, it would be if it weren't so silly.)
                   1673: .PP
                   1674: Variable
                   1675: .CW $t
                   1676: is an abbreviation for the name of a temporary file.
                   1677: Including
                   1678: .CW $pid
                   1679: in the names of temporary files insures that their
                   1680: names won't collide, in case more than one instance
                   1681: of the script is running at a time.
                   1682: .PP
                   1683: Function
                   1684: .CW read 's
                   1685: argument is the name of a variable into which a
                   1686: line gathered from standard input is read.
                   1687: .CW $ifs
                   1688: is set to just a newline.  Thus
                   1689: .CW read 's
                   1690: input is not split apart at spaces, but the terminating
                   1691: newline is deleted.
                   1692: .PP
                   1693: A handler is set to catch
                   1694: .CW sigint ,
                   1695: .CW sigquit ,
                   1696: and
                   1697: .CW sighup,
                   1698: and the artificial
                   1699: .CW sigexit
                   1700: signal.  It just removes the temporary file and exits.
                   1701: .PP
                   1702: The temporary file is initialized from a here
                   1703: document containing a list of Bell Labs locations, and
                   1704: the main loop starts.
                   1705: .PP
                   1706: First, the program guesses a location (in
                   1707: .CW $lab )
                   1708: using the
                   1709: .CW fortune
                   1710: program to pick a random line from the location list.
                   1711: It prints the location, and if it guessed Holmdel, prints
                   1712: a message and exits.
                   1713: .PP
                   1714: Then it uses the
                   1715: .CW read
                   1716: function to get lines from standard input and validity-check
                   1717: them until it gets a legal name.
                   1718: Note that the condition part of a
                   1719: .CW while
                   1720: can be a compound command.  Only the exit status of the
                   1721: last command in the sequence is checked.
                   1722: .PP
                   1723: Again, if the result
                   1724: is Holmdel, it prints a message and exits.
                   1725: Otherwise it goes back to the top of the loop.
                   1726: .NH
                   1727: Discussion
                   1728: .PP
                   1729: Steve Bourne's
                   1730: .CW /bin/sh
                   1731: is extremely well-designed; any successor is bound to
                   1732: suffer in comparison.  I have tried to fix its
                   1733: best-acknowledged shortcomings and to simplify things
                   1734: wherever possible, usually by omitting unessential features.
                   1735: Only when irresistibly tempted have I introduced novel ideas.
                   1736: Obviously I have tinkered extensively with Bourne's syntax,
                   1737: that being where his work was most open to criticism.
                   1738: .PP
                   1739: The most important principle in
                   1740: .I rc 's
                   1741: design is that it's not a macro processor.  Input is never
                   1742: scanned more than once by the lexical and syntactic analysis
                   1743: code (except, of course, by the
                   1744: .CW eval
                   1745: command, whose
                   1746: .I "raison d'etre
                   1747: is to break the rule).
                   1748: .PP
                   1749: Bourne shell scripts can often be made
                   1750: to run wild by passing them arguments containing spaces.
                   1751: These will be split into multiple arguments using
                   1752: .CW IFS ,
                   1753: often as inopportune times.
                   1754: In
                   1755: .I rc ,
                   1756: values of variables, including command line arguments, are not re-read
                   1757: when substituted into a command.
                   1758: Arguments have presumably been scanned in the parent process, and ought
                   1759: not to be re-read.
                   1760: .PP
                   1761: Why does Bourne re-scan commands after variable substitution?
                   1762: He needs to be able to store lists of arguments in variables whose values are
                   1763: character strings.
                   1764: If we eliminate re-scanning, we must change the type of variables, so that
                   1765: they can explicitly carry lists of strings.
                   1766: .PP
                   1767: This introduces some
                   1768: conceptual complications.  We need a notation for lists of words.
                   1769: There are two different kinds of concatenation, for strings \(em
                   1770: .CW $a^$b ,
                   1771: and lists \(em
                   1772: .CW "($a $b)" .
                   1773: The difference between
                   1774: .CW ()
                   1775: and
                   1776: .CW ''
                   1777: is confusing to novices,
                   1778: although the distinction is arguably sensible \(em
                   1779: a null argument is not the same as no argument.
                   1780: .PP
                   1781: Bourne also rescans input when doing command substitution.
                   1782: This is because the text enclosed in back-quotes is not
                   1783: properly a string, but a command.  Properly, it ought to
                   1784: be parsed when the enclosing command is, but this makes
                   1785: it difficult to
                   1786: handle nested command substitutions, like this:
                   1787: .P1                            
                   1788: size=`wc -l \e`ls -t|sed 1q\e``
                   1789: .P2
                   1790: The inner back-quotes must be escaped
                   1791: to avoid terminating the outer command.
                   1792: This can get much worse than the above example;
                   1793: the number of
                   1794: .CW \e 's
                   1795: required is exponential in the nesting depth.
                   1796: .I Rc
                   1797: fixes this by making the backquote a unary operator
                   1798: whose argument is a command, like this:
                   1799: .P1
                   1800: size=`{wc -l `{ls -t|sed 1q}}
                   1801: .P2
                   1802: No escapes are ever required, and the whole thing
                   1803: is parsed in one pass.
                   1804: .PP
                   1805: A similar rationale explains why
                   1806: .I rc
                   1807: defines signal handlers as though they were functions,
                   1808: instead of associating a string with each signal, as Bourne does,
                   1809: with the attendant possibility of getting a syntax error message
                   1810: in response to typing the interrupt character.  Since
                   1811: .I rc
                   1812: parses input when typed, it reports errors when you make them.
                   1813: .PP
                   1814: For all this trouble, we gain substantial semantic simplifications.
                   1815: There is no need for the distinction between
                   1816: .CW $*
                   1817: and
                   1818: .CW $@ .
                   1819: There is no need for four types of quotation, nor the
                   1820: extremely complicated rules that govern them.  In
                   1821: .I rc
                   1822: you use quotation marks exactly when you want a syntax character
                   1823: to appear in an argument.
                   1824: .CW IFS
                   1825: is no longer used, except in the one case where it was indispensable:
                   1826: converting command output into argument lists during command substitution.
                   1827: .PP
                   1828: This also avoids an important security hole|reference(reeds loophole).
                   1829: .I System (3)
                   1830: and
                   1831: .I popen (3)
                   1832: call
                   1833: .CW /bin/sh
                   1834: to execute a command.  It is impossible to use either
                   1835: of these routines with any assurance that the specified command will
                   1836: be executed, even if the caller of
                   1837: .I system
                   1838: or
                   1839: .I popen
                   1840: specifies a full path name for the command.  This can be devastating
                   1841: if it occurs in a set-userid program.
                   1842: The problem is that
                   1843: .CW IFS
                   1844: is used to split the command into words, so an attacker can just
                   1845: set
                   1846: .CW IFS=/
                   1847: in his environment and leave a Trojan horse
                   1848: named
                   1849: .CW usr
                   1850: or
                   1851: .CW bin
                   1852: in the current working directory before running the privileged program.
                   1853: .I Rc
                   1854: fixes this by not ever rescanning input for any reason.
                   1855: .PP
                   1856: Most of the other differences between
                   1857: .I rc
                   1858: and the Bourne shell are not so serious.  I eliminated Bourne's
                   1859: peculiar forms of variable substitution, like
                   1860: .P1
                   1861: echo ${a=b} ${c-d} ${e?error}
                   1862: .P2
                   1863: because they are little used, redundant and easily
                   1864: expressed in less abstruse terms.
                   1865: I deleted the builtins
                   1866: .CW export ,
                   1867: .CW readonly ,
                   1868: .CW break ,
                   1869: .CW continue ,
                   1870: .CW read ,
                   1871: .CW return ,
                   1872: .CW set ,
                   1873: .CW times
                   1874: and
                   1875: .CW unset
                   1876: because they seem redundant or
                   1877: only marginally useful.
                   1878: .PP
                   1879: Where Bourne's syntax draws from Algol 68,
                   1880: .I rc 's
                   1881: is based on C or Awk.  This is harder to defend.
                   1882: I believe that, for example
                   1883: .P1
                   1884: if(test -f junk) rm junk
                   1885: .P2
                   1886: is better syntax than
                   1887: .P1
                   1888: if test -f junk; then rm junk; fi
                   1889: .P2
                   1890: because it is less cluttered with keywords,
                   1891: it avoids the semicolons that Bourne requires
                   1892: in odd places,
                   1893: and the syntax characters better set off the
                   1894: active parts of the command.
                   1895: .PP
                   1896: The one bit of large-scale syntax that Bourne
                   1897: unquestionably does better than
                   1898: .I rc
                   1899: is the
                   1900: .CW if
                   1901: statement with
                   1902: .CW "else
                   1903: clause.
                   1904: .I Rc 's
                   1905: .CW if
                   1906: has no terminating
                   1907: .CW fi -like
                   1908: bracket.  As a result, the parser cannot
                   1909: tell whether or not to expect an
                   1910: .CW "else
                   1911: clause without looking ahead in its input.
                   1912: The problem is that after reading, for example
                   1913: .P1
                   1914: if(test -f junk) echo junk found
                   1915: .P2
                   1916: in interactive mode,
                   1917: .I rc
                   1918: cannot decide whether to execute it immediately and print
                   1919: .CW $prompt(1) ,
                   1920: or to print
                   1921: .CW $prompt(2)
                   1922: and wait for the
                   1923: .CW "else
                   1924: to be typed.
                   1925: In the Bourne shell, this is not a problem, because the
                   1926: .CW if
                   1927: command must end with
                   1928: .CW fi ,
                   1929: regardless of whether it contains an
                   1930: .CW else
                   1931: or not.
                   1932: .PP
                   1933: .I Rc 's
                   1934: admittedly feeble solution is to declare that the
                   1935: .CW else
                   1936: clause is a separate statement, with the semantic
                   1937: proviso that it must immediately follow an
                   1938: .CW if ,
                   1939: and to call it
                   1940: .CW "if not
                   1941: rather than
                   1942: .CW else ,
                   1943: as a reminder that something odd is going on.
                   1944: The only noticeable consequences of this is that
                   1945: the braces are required in the construction
                   1946: .P1
                   1947: for(i){
                   1948:     if(test -f $i) echo $i found
                   1949:     if not echo $i not found
                   1950: }
                   1951: .P2
                   1952: and that
                   1953: .I rc
                   1954: resolves the ``dangling else'' ambiguity in opposition
                   1955: to most people's expectations.
                   1956: .PP
                   1957: It is remarkable that in the four most recent editions of the UNIX
                   1958: programmer's manual the Bourne shell grammar described in the manual page
                   1959: does not admit the command
                   1960: .CW who|wc .
                   1961: This is surely an oversight, but it suggests something darker:
                   1962: nobody really knows what the Bourne shell's grammar is.  Even examination
                   1963: of the source code is little help.  The parser is implemented by recursive
                   1964: descent, but the routines corresponding to the syntactic categories all
                   1965: have a flag argument that subtly changes their operation depending on the
                   1966: context.
                   1967: .I Rc 's
                   1968: parser is implemented using
                   1969: .I yacc ,
                   1970: so I can say precisely what the grammar is \(em it's reproduced in the appendix.
                   1971: .PP
                   1972: Its lexical structure is harder to describe.
                   1973: I would simplify it considerably
                   1974: except for two things.
                   1975: There is a lexical kludge to distinguish between parentheses that immediately
                   1976: follow a word with no intervening spaces and those that don't that I would
                   1977: eliminate if there were a reasonable pair of characters to use
                   1978: for subscript brackets.  I could also eliminate the insertion of
                   1979: free carets if users were not adamant about it.
                   1980: .NH
                   1981: Acknowledgements
                   1982: .PP
                   1983: Rob Pike, Howard Trickey and other Plan 9 users have been insistent, incessant
                   1984: sources of good ideas and criticism.  Some examples in this document are plagiarized
                   1985: from |reference(bstj shell), as are most of
                   1986: .I rc 's
                   1987: good features.
                   1988: .NH
                   1989: References
                   1990: .LP
                   1991: |reference_placement
                   1992: .SH
                   1993: Appendix \(em an
                   1994: .I rc
                   1995: grammar
                   1996: .PP
                   1997: Below is reproduced
                   1998: .I rc 's
                   1999: .I yacc
                   2000: grammar, extracted directly from the source code, edited only
                   2001: to remove semantic actions.  The grammar describes a single
                   2002: command.  An
                   2003: .I rc
                   2004: script is a sequence of zero or more of these.
                   2005: .PP
                   2006: In the grammar, the token
                   2007: .CW WORD
                   2008: represents either a quoted string or
                   2009: a non-empty string of characters other
                   2010: than blank, tab, newline or any of the following:
                   2011: .P1
                   2012: # ; & | ^ $ = ` ' { } ( ) < >
                   2013: .P2
                   2014: with the proviso that a word that immediately follows a
                   2015: .CW $
                   2016: or
                   2017: .CW $#
                   2018: ends at the first character that is not alphanumeric or
                   2019: .CW _
                   2020: or
                   2021: .CW * .
                   2022: .PP
                   2023: The token
                   2024: .CW SUB
                   2025: represents a left parenthesis that follows a
                   2026: .CW WORD
                   2027: with no intervening spaces and therefore should be interpreted
                   2028: as the start of a subscript.
                   2029: .CW REDIR
                   2030: represents any of the redirection symbols,
                   2031: .P1
                   2032: > >[\fIn\fT]
                   2033: < <[\fIn\fT]
                   2034: >> >>[\fIn\fT]
                   2035: << <<[\fIn\fT]
                   2036: .P2
                   2037: .CW PIPE
                   2038: is any of the pipe symbols
                   2039: .P1
                   2040: | |[\fIn\fT] |[\fIn\fT=\fIm\fT]
                   2041: .P2
                   2042: .CW DUP
                   2043: is any of the file-descriptor duplication or closing symbols
                   2044: .P1
                   2045: >[\fIn\fT=\fIm\fT] <[\fIn\fT=\fIm\fT] >>[\fIn\fT=\fIm\fT]
                   2046: >[\fIn\fT=] <[\fIn\fT=] >>[\fIn\fT=]
                   2047: .P2
                   2048: .CW ANDAND
                   2049: stands for
                   2050: .CW && ,
                   2051: .CW OROR
                   2052: stands for
                   2053: .CW || ,
                   2054: and
                   2055: .CW COUNT
                   2056: stands for
                   2057: .CW $# .
                   2058: The other token names stand for or key words, which are lexically
                   2059: indistinguishable from
                   2060: .CW WORD s:
                   2061: .P1
                   2062: BANG   !
                   2063: FN     fn
                   2064: FOR    for
                   2065: IF     if
                   2066: IN     in
                   2067: NOT    not
                   2068: SUBSHELL       @
                   2069: SWITCH switch
                   2070: TWIDDLE        ~
                   2071: WHILE  while
                   2072: .P2
                   2073: .PP
                   2074: Comments start with
                   2075: .CW #
                   2076: and continue to the end of the line, and are deleted by lexical
                   2077: analysis, which also converts a backslash
                   2078: .CW \e ) (
                   2079: followed by a newline into a space, and
                   2080: inserts free carets whenever a
                   2081: .CW WORD
                   2082: is followed by another
                   2083: .CW WORD
                   2084: or a
                   2085: .CW `
                   2086: or
                   2087: .CW $ ,
                   2088: with no intervening spaces.
                   2089: .PP
                   2090: Here then is
                   2091: .I rc 's
                   2092: grammar.  Semantic actions that call function
                   2093: .CW skipnl
                   2094: have been included at places where a command
                   2095: may be continued on a new line.
                   2096: .br
                   2097: \X'PARM CT 80'
                   2098: .KS
                   2099: .P1
                   2100: %term FOR IN WHILE IF NOT
                   2101: %term TWIDDLE BANG SUBSHELL
                   2102: %term SWITCH FN WORD REDIR DUP
                   2103: %term PIPE SUB
                   2104: %left IF WHILE FOR SWITCH ')' NOT
                   2105: %left ANDAND OROR
                   2106: %left BANG SUBSHELL
                   2107: %left PIPE
                   2108: %left '^'
                   2109: %right '$' COUNT
                   2110: %left SUB
                   2111: %%
                   2112: rc:
                   2113:        |  line '\en'
                   2114: line: cmd
                   2115:        |  cmdsa line
                   2116: body: cmd
                   2117:        |  cmdsan body
                   2118: cmdsa: cmd ';'
                   2119:        |  cmd '&'
                   2120: cmdsan: cmdsa
                   2121:        |  cmd '\en'
                   2122: brace: '{' body '}'
                   2123: paren: '(' body ')'
                   2124: assign: first '=' word
                   2125: epilog:
                   2126:        |  redir epilog
                   2127: redir: REDIR word
                   2128:        |  DUP
                   2129: cmd:
                   2130:        |  brace epilog
                   2131:        |  IF paren {skipnl();} cmd
                   2132:        |  IF NOT {skipnl();} cmd
                   2133:        |  FOR '(' word IN words ')'
                   2134:         {skipnl();} cmd
                   2135:        |  FOR '(' word ')'
                   2136:         {skipnl();} cmd
                   2137:        |  WHILE paren {skipnl();} cmd
                   2138:        |  SWITCH word {skipnl();} brace
                   2139:        |  simple
                   2140:        |  TWIDDLE word words
                   2141:        |  cmd ANDAND cmd
                   2142:        |  cmd OROR cmd
                   2143:        |  cmd PIPE cmd
                   2144:        |  redir cmd  %prec BANG
                   2145:        |  assign cmd %prec BANG
                   2146:        |  BANG cmd
                   2147:        |  SUBSHELL cmd
                   2148:        |  FN words brace
                   2149:        |  FN words
                   2150: .P2
                   2151: .KE
                   2152: .KS
                   2153: .P1
                   2154: simple: first
                   2155:        |  simple word
                   2156:        |  simple redir
                   2157: first: comword  
                   2158:        |  first '^' word
                   2159: word: keyword
                   2160:        |  comword
                   2161:        |  word '^' word
                   2162: comword: '$' word
                   2163:        |  '$' word SUB words ')'
                   2164:        |  COUNT word
                   2165:        |  WORD
                   2166:        |  '`' brace
                   2167:        |  '(' words ')'
                   2168:        |  REDIR brace
                   2169: keyword: FOR|IN|WHILE|IF|NOT
                   2170:        |  TWIDDLE|BANG|SUBSHELL|SWITCH
                   2171:        |  FN
                   2172: words:
                   2173:        |  words word
                   2174: .P2
                   2175: .KE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.