xref: /plan9/sys/doc/rc.ms (revision 426d2b71458df9b491ba6c167f699b3f1f7b0428)
1.HTML "Rc — The Plan 9 Shell
2.	\" /*% refer -k -e -n -l3,2 -s < % | tbl | troff -ms | lp -dfn
3.Tm shell programming language	g
4.de TP	\" An indented paragraph describing some command, tagged with the command name
5.IP "\\f(CW\\$1\\fR" 5
6.if \\w'\\f(CW\\$1\\fR'-4n .br
7..
8.de CI
9.nr Sf \\n(.f
10\%\&\\$3\f(CW\\$1\fI\&\\$2\f\\n(Sf
11..
12.TL
13Rc \(em The Plan 9 Shell
14.AU
15Tom Duff
16td@plan9.bell-labs.com
17.AB
18.I Rc
19is a command interpreter for Plan 9 that
20provides similar facilities to UNIX's
21Bourne shell,
22with some small additions and less idiosyncratic syntax.
23This paper uses numerous examples to describe
24.I rc 's
25features, and contrasts
26.I rc
27with the Bourne shell, a model that many readers will be familiar with.
28.AE
29.NH
30Introduction
31.PP
32.I Rc
33is similar in spirit but different in detail from UNIX's
34Bourne shell.  This paper describes
35.I rc 's
36principal features with many small examples and a few larger ones.
37It assumes familiarity with the Bourne shell.
38.NH
39Simple commands
40.PP
41For the simplest uses
42.I rc
43has syntax familiar to Bourne-shell users.
44All of the following behave as expected:
45.P1
46date
47cat /lib/news/build
48who >user.names
49who >>user.names
50wc <file
51echo [a-f]*.c
52who | wc
53who; date
54vc *.c &
55mk && v.out /*/bin/fb/*
56rm -r junk || echo rm failed!
57.P2
58.NH
59Quotation
60.PP
61An argument that contains a space or one of
62.I rc 's
63other syntax characters must be enclosed in apostrophes
64.CW ' ): (
65.P1
66rm 'odd file name'
67.P2
68An apostrophe in a quoted argument must be doubled:
69.P1
70echo 'How''s your father?'
71.P2
72.NH
73Patterns
74.PP
75An unquoted argument that contains any of the characters
76.CW *
77.CW ?
78.CW [
79is a pattern to be matched against file names.
80A
81.CW *
82character matches any sequence of characters,
83.CW ?
84matches any single character, and
85.CW [\fIclass\fP]
86matches any character in the
87.CW class ,
88unless the first character of
89.I class
90is
91.CW ~ ,
92in which case the class is complemented.
93The
94.I class
95may also contain pairs of characters separated by
96.CW - ,
97standing for all characters lexically between the two.
98The character
99.CW /
100must appear explicitly in a pattern, as must the path name components
101.CW .
102and
103.CW .. .
104A pattern is replaced by a list of arguments, one for each path name matched,
105except that a pattern matching no names is not replaced by the empty list;
106rather it stands for itself.
107.NH
108Variables
109.PP
110UNIX's Bourne shell offers string-valued variables.
111.I Rc
112provides variables whose values are lists of arguments \(em
113that is, arrays of strings.  This is the principal difference
114between
115.I rc
116and traditional UNIX command interpreters.
117Variables may be given values by typing, for example:
118.P1
119path=(. /bin)
120user=td
121font=/lib/font/bit/pelm/ascii.9.font
122.P2
123The parentheses indicate that the value assigned to
124.CW path
125is a list of two strings. The variables
126.CW user
127and
128.CW font
129are assigned lists containing a single string.
130.PP
131The value of a variable can be substituted into a command by
132preceding its name with a
133.CW $ ,
134like this:
135.P1
136echo $path
137.P2
138If
139.CW path
140had been set as above, this would be equivalent to
141.P1
142echo . /bin
143.P2
144Variables may be subscripted by numbers or lists of numbers,
145like this:
146.P1
147echo $path(2)
148echo $path(2 1 2)
149.P2
150These are equivalent to
151.P1
152echo /bin
153echo /bin . /bin
154.P2
155There can be no space separating the variable's name from the
156left parenthesis; otherwise, the subscript would be considered
157a separate parenthesized list.
158.PP
159The number of strings in a variable can be determined by the
160.CW $#
161operator.  For example,
162.P1
163echo $#path
164.P2
165would print 2 for this example.
166.PP
167The following two assignments are subtly different:
168.P1
169empty=()
170null=''
171.P2
172The first sets
173.CW empty
174to a list containing no strings.
175The second sets
176.CW null
177to a list containing a single string,
178but the string contains no characters.
179.PP
180Although these may seem like more or less
181the same thing (in Bourne's shell, they are
182indistinguishable), they behave differently
183in almost all circumstances.
184Among other things
185.P1
186echo $#empty
187.P2
188prints 0, whereas
189.P1
190echo $#null
191.P2
192prints 1.
193.PP
194All variables that have never been set have the value
195.CW () .
196.PP
197Occasionally, it is convenient to treat a variable's value
198as a single string.  The elements of a string are concatenated
199into a single string, with spaces between the elements, by
200the
201.CW $"
202operator.
203Thus, if we set
204.P1
205list=(How now brown cow)
206string=$"list
207.P2
208then both
209.P1
210echo $list
211.P2
212and
213.P1
214echo $string
215.P2
216cause the same output, viz:
217.P1
218How now brown cow
219.P2
220but
221.P1
222echo $#list $#string
223.P2
224will output
225.P1
2264 1
227.P2
228because
229.CW $list
230has four members, but
231.CW $string
232has a single member, with three spaces separating its words.
233.NH
234Arguments
235.PP
236When
237.I rc
238is reading its input from a file, the file has access
239to the arguments supplied on
240.I rc 's
241command line.  The variable
242.CW $*
243initially has the list of arguments assigned to it.
244The names
245.CW $1 ,
246.CW $2 ,
247etc. are synonyms for
248.CW $*(1) ,
249.CW $*(2) ,
250etc.
251In addition,
252.CW $0
253is the name of the file from which
254.I rc 's
255input is being read.
256.NH
257Concatenation
258.PP
259.I Rc
260has a string concatenation operator, the caret
261.CW ^ ,
262to build arguments out of pieces.
263.P1
264echo hully^gully
265.P2
266is exactly equivalent to
267.P1
268echo hullygully
269.P2
270Suppose variable
271.CW i
272contains the name of a command.
273Then
274.P1
275vc $i^.c
276vl -o $1 $i^.v
277.P2
278might compile the command's source code, leaving the
279result in the appropriate file.
280.PP
281Concatenation distributes over lists. The following
282.P1
283echo (a b c)^(1 2 3)
284src=(main subr io)
285cc $src^.c
286.P2
287are equivalent to
288.P1
289echo a1 b2 c3
290cc main.c subr.c io.c
291.P2
292In detail, the rule is: if both operands of
293.CW ^
294are lists of the same non-zero number of strings, they are concatenated
295pairwise.  Otherwise, if one of the operands is a single string,
296it is concatenated with each member of the other operand in turn.
297Any other combination of operands is an error.
298.NH
299Free carets
300.PP
301User demand has dictated that
302.I rc
303insert carets in certain places, to make the syntax
304look more like the Bourne shell.  For example, this:
305.P1
306cc -$flags $stems.c
307.P2
308is equivalent to
309.P1
310cc -^$flags $stems^.c
311.P2
312In general,
313.I rc
314will insert
315.CW ^
316between two arguments that are not separated by white space.
317Specifically, whenever one of
318.CW "$'`
319follows a quoted or unquoted word, or an unquoted word follows
320a quoted word with no intervening blanks or tabs, an implicit
321.CW ^
322is inserted between the two.  If an unquoted word immediately following a
323.CW $
324contains a character other than an alphanumeric, underscore or
325.CW * ,
326a
327.CW ^
328is inserted before the first such character.
329.NH
330Command substitution
331.PP
332It is often useful to build an argument list from the output of a command.
333.I Rc
334allows a command, enclosed in braces and preceded by a left quote,
335.CW "`{...}" ,
336anywhere that an argument is required.  The command is executed and its
337standard output captured.
338The characters stored in the variable
339.CW ifs
340are used to split the output into arguments.
341For example,
342.P1
343cat `{ls -tr|sed 10q}
344.P2
345will concatenate the ten oldest files in the current directory in temporal order, given the
346default
347.CW ifs
348setting of space, tab, and newline.
349.NH
350Pipeline branching
351.PP
352The normal pipeline notation is general enough for almost all cases.
353Very occasionally it is useful to have pipelines that are not linear.
354Pipeline topologies more general than trees can require arbitrarily large pipe buffers,
355or worse, can cause deadlock.
356.I Rc
357has syntax for some kinds of non-linear but treelike pipelines.
358For example,
359.P1
360	cmp <{old} <{new}
361.P2
362will regression-test a new version of a command.
363.CW <
364or
365.CW >
366followed by a command in braces causes the command to be run with
367its standard output or input attached to a pipe.  The parent command
368.CW cmp "" (
369in the example)
370is started with the other end of the pipe attached to some file descriptor
371or other, and with an argument that will connect to the pipe when opened
372(e.g.,
373.CW /dev/fd/6 ).
374Some commands are unprepared to deal with input files that turn out not to be seekable.
375For example
376.CW diff
377needs to read its input twice.
378.NH
379Exit status
380.PP
381When a command exits it returns status to the program that executed it.
382On Plan 9 status is a character string describing an error condition.
383On normal termination it is empty.
384.PP
385.I Rc
386captures command exit status in the variable
387.CW $status .
388For a simple command the value of
389.CW $status
390is just as described above.  For a pipeline
391.CW $status
392is set to the concatenation of the statuses of the pipeline components with
393.CW |
394characters for separators.
395.PP
396.I Rc
397has a several kinds of control flow,
398many of them conditioned by the status returned from previously
399executed commands.  Any
400.CW $status
401containing only
402.CW 0 's
403and
404.CW | 's
405has boolean value
406.I true .
407Any other status is
408.I false .
409.NH
410Command grouping
411.PP
412A sequence of commands enclosed in
413.CW {}
414may be used anywhere a command is required.
415For example:
416.P1
417{sleep 3600;echo 'Time''s up!'}&
418.P2
419will wait an hour in the background, then print a message.
420Without the braces,
421.P1
422sleep 3600;echo 'Time''s up!'&
423.P2
424would lock up the terminal for an hour,
425then print the message in the background.
426.NH
427Control flow \(em \f(CWfor\fP
428.PP
429A command may be executed once for each member of a list
430by typing, for example:
431.P1
432for(i in printf scanf putchar) look $i /usr/td/lib/dw.dat
433.P2
434This looks for each of the words
435.CW printf ,
436.CW scanf
437and
438.CW putchar
439in the given file.
440The general form is
441.P1
442for(\fIname\fP in \fIlist\fP) \fIcommand\fP
443.P2
444or
445.P1
446for(\fIname\fP) \fIcommand\fP
447.P2
448In the first case
449.I command
450is executed once for each member of
451.I list
452with that member assigned to variable
453.I name .
454If the clause
455.CW in "" ``
456.I list ''
457is missing,
458.CW in "" ``
459.CW $* ''
460is assumed.
461.NH
462Conditional execution \(em \f(CWif\fP
463.PP
464.I Rc
465also provides a general if-statement.  For example:
466.P1
467for(i in *.c) if(cpp $i >/tmp/$i) vc /tmp/$i
468.P2
469runs the C compiler on each C source program that
470cpp processes without error.
471An `if not' statement provides a two-tailed conditional.
472For example:
473.P1
474for(i){
475    if(test -f /tmp/$i) echo $i already in /tmp
476    if not cp $i /tmp
477}
478.P2
479This loops over each file in
480.CW $* ,
481copying to
482.CW /tmp
483those that do not already appear there, and
484printing a message for those that do.
485.NH
486Control flow \(em \f(CWwhile\fP
487.PP
488.I Rc 's
489while statement looks like this:
490.P1
491while(newer subr.v subr.c) sleep 5
492.P2
493This waits until
494.CW subr.v
495is newer than
496.CW subr.c ,
497presumably because the C compiler finished with it.
498.PP
499If the controlling command is empty, the loop will not terminate.
500Thus,
501.P1
502while() echo y
503.P2
504emulates the
505.I yes
506command.
507.NH
508Control flow \(em \f(CWswitch\fP
509.PP
510.I Rc
511provides a switch statement to do pattern-matching on
512arbitrary strings.  Its general form is
513.P1
514switch(\fIword\fP){
515case \fIpattern ...\fP
516    \fIcommands\fP
517case \fIpattern ...\fP
518    \fIcommands\fP
519\&...
520}
521.P2
522.I Rc
523attempts to match the word against the patterns in each case statement in turn.
524Patterns are the same as for filename matching, except that
525.CW /
526and
527.CW .
528and
529.CW ..
530need not be matched explicitly.
531.PP
532If any pattern matches, the
533commands following that case up to
534the next case (or the end of the switch)
535are executed, and execution of the switch
536is complete.  For example,
537.P1
538switch($#*){
539case 1
540    cat >>$1
541case 2
542    cat >>$2 <$1
543case *
544    echo 'Usage: append [from] to'
545}
546.P2
547is an append command.  Called with one file argument,
548it appends its standard input to the named file.  With two, the
549first is appended to the second.  Any other number
550elicits an error message.
551.PP
552The built-in
553.CW ~
554command also matches patterns, and is often more concise than a switch.
555Its arguments are a string and a list of patterns.  It sets
556.CW $status
557to true if and only if any of the patterns matches the string.
558The following example processes option arguments for the
559.I man (1)
560command:
561.P1
562opt=()
563while(~ $1 -* [1-9] 10){
564    switch($1){
565    case [1-9] 10
566        sec=$1 secn=$1
567    case -f
568        c=f s=f
569    case -[qwnt]
570        cmd=$1
571    case -T*
572        T=$1
573    case -*
574        opt=($opt $1)
575    }
576    shift
577}
578.P2
579.NH
580Functions
581.PP
582Functions may be defined by typing
583.P1
584fn \fIname\fP { \fIcommands\fP }
585.P2
586Subsequently, whenever a command named
587.I name
588is encountered, the remainder of the command's
589argument list will assigned to
590.CW $*
591and
592.I rc
593will execute the
594.I commands .
595The value of
596.CW $*
597will be restored on completion.
598For example:
599.P1
600fn g {
601    grep $1 *.[hcyl]
602}
603.P2
604defines
605.CI g " pattern
606to look for occurrences of
607.I pattern
608in all program source files in the current directory.
609.PP
610Function definitions are deleted by writing
611.P1
612fn \fIname\fP
613.P2
614with no function body.
615.NH
616Command execution
617.PP
618.I Rc
619does one of several things to execute a simple command.
620If the command name is the name of a function defined using
621.CW fn ,
622the function is executed.
623Otherwise, if it is the name of a built-in command, the
624built-in is executed directly by
625.I rc .
626Otherwise, directories mentioned in the variable
627.CW $path
628are searched until an executable file is found.
629Extensive use of the
630.CW $path
631variable is discouraged in Plan 9.  Instead, use the default
632.CW (.
633.CW /bin)
634and bind what you need into
635.CW /bin .
636.NH
637Built-in commands
638.PP
639Several commands are executed internally by
640.I rc
641because they are difficult to implement otherwise.
642.TP ". [-i] \fIfile ...\f(CW
643Execute commands from
644.I file .
645.CW $*
646is set for the duration to the reminder of the argument list following
647.I file .
648.CW $path
649is used to search for
650.I file .
651Option
652.CW -i
653indicates interactive input \(em a prompt
654(found in
655.CW $prompt )
656is printed before each command is read.
657.TP "builtin \fIcommand ...\f(CW
658Execute
659.I command
660as usual except that any function named
661.I command
662is ignored.
663For example,
664.P1
665fn cd{
666    builtin cd $* && pwd
667}
668.P2
669defines a replacement for the
670.CW cd
671built-in (see below) that announces the full name of the new directory.
672.TP "cd [\fIdir\f(CW]
673Change the current directory to
674.I dir .
675The default argument is
676.CW $home .
677.CW $cdpath
678is a list of places in which to search for
679.I dir .
680.TP "eval [\fIarg ...\f(CW]
681The arguments are concatenated (separated by spaces) into a string, read as input to
682.I rc ,
683and executed.  For example,
684.P1
685x='$y'
686y=Doody
687eval echo Howdy, $x
688.P2
689would echo
690.P1
691Howdy, Doody
692.P2
693since the arguments of
694.CW eval
695would be
696.P1
697echo Howdy, $y
698.P2
699after substituting for
700.CW $x .
701.TP "exec [\fIcommand ...\f(CW]
702.I Rc
703replaces itself with the given
704.I command .
705This is like a
706.I goto
707\(em
708.I rc
709does not wait for the command to exit, and does not return to read any more commands.
710.TP "exit [\fIstatus\f(CW]
711.I Rc
712exits immediately with the given status.  If none is given, the current value of
713.CW $status
714is used.
715.TP "flag \fIf\f(CW [+-]
716This command manipulates and tests the command line flags (described below).
717.P1
718flag \fIf\f(CW +
719.P2
720sets flag
721.I f .
722.P1
723flag \fIf\f(CW -
724.P2
725clears flag
726.I f .
727.P1
728flag \fIf\f(CW
729.P2
730tests flag
731.I f ,
732setting
733.CW $status
734appropriately.
735Thus
736.P1
737if(flag x) flag v +
738.P2
739sets the
740.CW -v
741flag if the
742.CW -x
743flag is already set.
744.TP "rfork [nNeEsfF]
745This uses the Plan 9
746.I rfork
747system entry to put
748.I rc
749into a new process group with the following attributes:
750.TS
751box;
752l l l
753lfCW l l.
754Flag	Name	Function
755_
756n	RFNAMEG	Make a copy of the parent's name space
757N	RFCNAMEG	Start with a new, empty name space
758e	RFENVG	Make a copy of the parent's environment
759E	RFCENVG	Start with a new, empty environment
760s	RFNOTEG	Make a new note group
761f	RFFDG	Make a copy of the parent's file descriptor space
762F	RFCFDG	Make a new, empty file descriptor space
763.TE
764Section
765.I fork (2)
766of the Programmer's Manual describes these attributes in more detail.
767.TP "shift [\fIn\f(CW]
768Delete the first
769.I n
770(default 1) elements of
771.CW $* .
772.TP "wait [\fIpid\fP]
773Wait for the process with the given
774.I pid
775to exit.  If no
776.I pid
777is given, all outstanding processes are waited for.
778.TP "whatis \fIname ...\f(CW
779Print the value of each
780.I name
781in a form suitable for input to
782.I rc .
783The output is an assignment to a variable, the definition of a function,
784a call to
785.CW builtin
786for a built-in command, or the path name of a binary program.
787For example,
788.P1
789whatis path g cd who
790.P2
791might print
792.P1
793path=(. /bin)
794fn g {gre -e $1 *.[hycl]}
795builtin cd
796/bin/who
797.P2
798.TP "~ \fIsubject pattern ...\f(CW
799The
800.I subject
801is matched against each
802.I pattern
803in turn.  On a match,
804.CW $status
805is set to true.
806Otherwise, it is set to
807.CW "'no match'" .
808Patterns are the same as for filename matching.
809The
810.I patterns
811are not subjected to filename replacement before the
812.CW ~
813command is executed, so they need not be enclosed in
814quotation marks, unless of course, a literal match for
815.CW *
816.CW [
817or
818.CW ?
819is required.
820For example
821.P1
822~ $1 ?
823.P2
824matches any single character, whereas
825.P1
826~ $1 '?'
827.P2
828only matches a literal question mark.
829.NH
830Advanced I/O Redirection
831.PP
832.I Rc
833allows redirection of file descriptors other than 0 and 1
834(standard input and output) by specifying the file descriptor
835in square brackets
836.CW "[ ]
837after the
838.CW <
839or
840.CW > .
841For example,
842.P1
843vc junk.c >[2]junk.diag
844.P2
845saves the compiler's diagnostics from standard error in
846.CW junk.diag .
847.PP
848File descriptors may be replaced by a copy, in the sense of
849.I dup (2),
850of an already-open file by typing, for example
851.P1
852vc junk.c >[2=1]
853.P2
854This replaces file descriptor 2 with a copy of file descriptor 1.
855It is more useful in conjunction with other redirections, like this
856.P1
857vc junk.c >junk.out >[2=1]
858.P2
859Redirections are evaluated from left to right, so this redirects
860file descriptor 1 to
861.CW junk.out ,
862then points file descriptor 2 at the same file.
863By contrast,
864.P1
865vc junk.c >[2=1] >junk.out
866.P2
867redirects file descriptor 2 to a copy of file descriptor 1
868(presumably the terminal), and then directs file descriptor 1
869to a file.  In the first case, standard and diagnostic output
870will be intermixed in
871.CW junk.out .
872In the second, diagnostic output will appear on the terminal,
873and standard output will be sent to the file.
874.PP
875File descriptors may be closed by using the duplication notation
876with an empty right-hand side.
877For example,
878.P1
879vc junk.c >[2=]
880.P2
881will discard diagnostics from the compilation.
882.PP
883Arbitrary file descriptors may be sent through
884a pipe by typing, for example,
885.P1
886vc junk.c |[2] grep -v '^$'
887.P2
888This deletes blank lines
889from the C compiler's error output.  Note that the output
890of
891.CW grep
892still appears on file descriptor 1.
893.PP
894Occasionally you may wish to connect the input side of
895a pipe to some file descriptor other than zero.
896The notation
897.P1
898cmd1 |[5=19] cmd2
899.P2
900creates a pipeline with
901.CW cmd1 's
902file descriptor 5 connected through a pipe to
903.CW cmd2 's
904file descriptor 19.
905.NH
906Here documents
907.PP
908.I Rc
909procedures may include data, called ``here documents'',
910to be provided as input to commands, as in this version of the
911.I tel
912command
913.P1
914for(i) grep $i <<!
915\&...
916tor 2T-402 2912
917kevin 2C-514 2842
918bill 2C-562 7214
919\&...
920!
921.P2
922A here document is introduced by the redirection symbol
923.CW << ,
924followed by an arbitrary EOF marker
925.CW ! "" (
926in the example).  Lines following the command,
927up to a line containing only the EOF marker are saved
928in a temporary file that is connected to the command's
929standard input when it is run.
930.PP
931.I Rc
932does variable substitution in here documents.  The following command:
933.P1
934ed $3 <<EOF
935g/$1/s//$2/g
936w
937EOF
938.P2
939changes all occurrences of
940.CW $1
941to
942.CW $2
943in file
944.CW $3 .
945To include a literal
946.CW $
947in a here document, type
948.CW $$ .
949If the name of a variable is followed immediately by
950.CW ^ ,
951the caret is deleted.
952.PP
953Variable substitution can be entirely suppressed by enclosing
954the EOF marker following
955.CW <<
956in quotation marks, as in
957.CW <<'EOF' .
958.PP
959Here documents may be provided on file descriptors other than 0 by typing, for example,
960.P1
961cmd <<[4]End
962\&...
963End
964.P2
965.PP
966If a here document appears within a compound block, the contents of the document
967must be after the whole block:
968.P1
969for(i in $*){
970	mail $i <<EOF
971}
972words to live by
973EOF
974.P2
975.NH
976Catching Notes
977.PP
978.I Rc
979scripts normally terminate when an interrupt is received from the terminal.
980A function with the name of a UNIX signal, in lower case, is defined in the usual way,
981but called when
982.I rc
983receives the corresponding note.
984The
985.I notify (2)
986section of the Programmer's Manual discusses notes in some detail.
987Notes of interest are:
988.TP sighup
989The note was `hangup'.
990Plan 9 sends this when the terminal has disconnected from
991.I rc .
992.TP sigint
993The note was `interrupt', usually sent when
994the interrupt character (ASCII DEL) is typed on the terminal.
995.TP sigterm
996The note was `kill', normally sent by
997.I kill (1).
998.TP sigexit
999An artificial note sent when
1000.I rc
1001is about to exit.
1002.PP
1003As an example,
1004.P1
1005fn sigint{
1006    rm /tmp/junk
1007    exit
1008}
1009.P2
1010sets a trap for the keyboard interrupt that
1011removes a temporary file before exiting.
1012.PP
1013Notes will be ignored if the note routine is set to
1014.CW {} .
1015Signals revert to their default behavior when their handlers'
1016definitions are deleted.
1017.NH
1018Environment
1019.PP
1020The environment is a list of name-value pairs made available to
1021executing binaries.
1022On Plan 9, the environment is stored in a file system named
1023.CW #e ,
1024normally mounted on
1025.CW /env .
1026The value of each variable is stored in a separate file, with components
1027terminated by zero bytes.
1028(The file system is
1029maintained entirely in core, so no disk or network access is involved.)
1030The contents of
1031.CW /env
1032are shared on a per-process group basis \(mi when a new process group is
1033created it effectively attaches
1034.CW /env
1035to a new file system initialized with a copy of the old one.
1036A consequence of this organization is that commands can change environment
1037entries and see the changes reflected in
1038.I rc .
1039.PP
1040Functions also appear in the environment, named by prefixing
1041.CW fn#
1042to their names, like
1043.CW /env/fn#roff .
1044.NH
1045Local Variables
1046.PP
1047It is often useful to set a variable for the duration
1048of a single command.  An assignment followed by a command
1049has this effect.  For example
1050.P1
1051a=global
1052a=local echo $a
1053echo $a
1054.P2
1055will print
1056.P1
1057local
1058global
1059.P2
1060This works even for compound commands, like
1061.P1
1062f=/fairly/long/file/name {
1063    { wc $f; spell $f; diff $f.old $f } |
1064      pr -h 'Facts about '$f | lp -dfn
1065}
1066.P2
1067.NH
1068Examples \(em \fIcd, pwd\fP
1069.PP
1070Here is a pair of functions that provide
1071enhanced versions of the standard
1072.CW cd
1073and
1074.CW pwd
1075commands.  (Thanks to Rob Pike for these.)
1076.P1
1077ps1='% '	# default prompt
1078tab='	'	# a tab character
1079fn cd{
1080  builtin cd $1 &&
1081  switch($#*){
1082  case 0
1083    dir=$home
1084    prompt=($ps1 $tab)
1085  case *
1086    switch($1)
1087    case /*
1088      dir=$1
1089      prompt=(`{basename `{pwd}}^$ps1 $tab)
1090    case */* ..*
1091      dir=()
1092      prompt=(`{basename `{pwd}}^$ps1 $tab)
1093    case *
1094      dir=()
1095      prompt=($1^$ps1 $tab)
1096    }
1097  }
1098}
1099fn pwd{
1100  if(~ $#dir 0)
1101    dir=`{/bin/pwd}
1102  echo $dir
1103}
1104.P2
1105Function
1106.CW pwd
1107is a version of the standard
1108.CW pwd
1109that caches its value in variable
1110.CW $dir ,
1111because the genuine
1112.CW pwd
1113can be quite slow to execute.
1114(Recent versions of Plan 9 have very fast implementations of
1115.CW pwd ,
1116reducing the advantage of the
1117.CW pwd
1118function.)
1119.PP
1120Function
1121.CW cd
1122calls the
1123.CW cd
1124built-in, and checks that it was successful.
1125If so, it sets
1126.CW $dir
1127and
1128.CW $prompt .
1129The prompt will include the last component of the
1130current directory (except in the home directory,
1131where it will be null), and
1132.CW $dir
1133will be reset either to the correct value or to
1134.CW () ,
1135so that the
1136.CW pwd
1137function will work correctly.
1138.NH
1139Examples \(em \fIman\fP
1140.PP
1141The
1142.I man
1143command prints pages of the Programmer's Manual.
1144It is called, for example, as
1145.P1
1146man 2 sinh
1147man rc
1148man -t cat
1149.P2
1150In the first case, the page for
1151.I sinh
1152in section 2 is printed.
1153In the second case, the manual page for
1154.I rc
1155is printed.  Since no manual section is specified,
1156all sections are searched for the page, and it is found
1157in section 1.
1158In the third case, the page for
1159.I cat
1160is typeset (the
1161.CW -t
1162option).
1163.P1
1164cd /sys/man || {
1165  echo $0: No manual! >[1=2]
1166  exit 1
1167}
1168NT=n  # default nroff
1169s='*' # section, default try all
1170for(i) switch($i){
1171case -t
1172  NT=t
1173case -n
1174  NT=n
1175case -*
1176  echo Usage: $0 '[-nt] [section] page ...' >[1=2]
1177  exit 1
1178case [1-9] 10
1179  s=$i
1180case *
1181  eval 'pages='$s/$i
1182  for(page in $pages){
1183    if(test -f $page)
1184      $NT^roff -man $page
1185    if not
1186      echo $0: $i not found >[1=2]
1187  }
1188}
1189.P2
1190Note the use of
1191.CW eval
1192to make a list of candidate manual pages.
1193Without
1194.CW eval ,
1195the
1196.CW *
1197stored in
1198.CW $s
1199would not trigger filename matching
1200\(em it's enclosed in quotation marks,
1201and even if it weren't, it would be expanded
1202when assigned to
1203.CW $s .
1204Eval causes its arguments
1205to be re-processed by
1206.I rc 's
1207parser and interpreter, effectively delaying
1208evaluation of the
1209.CW *
1210until the assignment to
1211.CW $pages .
1212.NH
1213Examples \(em \fIholmdel\fP
1214.PP
1215The following
1216.I rc
1217script plays the deceptively simple game
1218.I holmdel ,
1219in which the players alternately name Bell Labs locations,
1220the winner being the first to mention Holmdel.
1221.KF
1222.P1
1223t=/tmp/holmdel$pid
1224fn read{
1225	$1=`{awk '{print;exit}'}
1226}
1227ifs='
1228\&'	# just a newline
1229fn sigexit sigint sigquit sighup{
1230	rm -f $t
1231	exit
1232}
1233cat <<'!' >$t
1234Allentown
1235Atlanta
1236Cedar Crest
1237Chester
1238Columbus
1239Elmhurst
1240Fullerton
1241Holmdel
1242Indian Hill
1243Merrimack Valley
1244Morristown
1245Neptune
1246Piscataway
1247Reading
1248Short Hills
1249South Plainfield
1250Summit
1251Whippany
1252West Long Branch
1253!
1254while(){
1255   lab=`{fortune $t}
1256   echo $lab
1257   if(~ $lab Holmdel){
1258      echo You lose.
1259      exit
1260   }
1261   while(read lab; ! grep -i -s $lab $t) echo No such location.
1262   if(~ $lab [hH]olmdel){
1263      echo You win.
1264      exit
1265   }
1266}
1267.P2
1268.KE
1269.PP
1270This script is worth describing in detail
1271(rather, it would be if it weren't so silly.)
1272.PP
1273Variable
1274.CW $t
1275is an abbreviation for the name of a temporary file.
1276Including
1277.CW $pid ,
1278initialized by
1279.I rc
1280to its process-id,
1281in the names of temporary files insures that their
1282names won't collide, in case more than one instance
1283of the script is running at a time.
1284.PP
1285Function
1286.CW read 's
1287argument is the name of a variable into which a
1288line gathered from standard input is read.
1289.CW $ifs
1290is set to just a newline.  Thus
1291.CW read 's
1292input is not split apart at spaces, but the terminating
1293newline is deleted.
1294.PP
1295A handler is set to catch
1296.CW sigint ,
1297.CW sigquit ,
1298and
1299.CW sighup,
1300and the artificial
1301.CW sigexit
1302signal.  It just removes the temporary file and exits.
1303.PP
1304The temporary file is initialized from a here
1305document containing a list of Bell Labs locations, and
1306the main loop starts.
1307.PP
1308First, the program guesses a location (in
1309.CW $lab )
1310using the
1311.CW fortune
1312program to pick a random line from the location list.
1313It prints the location, and if it guessed Holmdel, prints
1314a message and exits.
1315.PP
1316Then it uses the
1317.CW read
1318function to get lines from standard input and validity-check
1319them until it gets a legal name.
1320Note that the condition part of a
1321.CW while
1322can be a compound command.  Only the exit status of the
1323last command in the sequence is checked.
1324.PP
1325Again, if the result
1326is Holmdel, it prints a message and exits.
1327Otherwise it goes back to the top of the loop.
1328.NH
1329Design Principles
1330.PP
1331.I Rc
1332draws heavily from Steve Bourne's
1333.CW /bin/sh .
1334Any successor of the Bourne shell is bound to
1335suffer in comparison.  I have tried to fix its
1336best-acknowledged shortcomings and to simplify things
1337wherever possible, usually by omitting inessential features.
1338Only when irresistibly tempted have I introduced novel ideas.
1339Obviously I have tinkered extensively with Bourne's syntax.
1340.PP
1341The most important principle in
1342.I rc 's
1343design is that it's not a macro processor.  Input is never
1344scanned more than once by the lexical and syntactic analysis
1345code (except, of course, by the
1346.CW eval
1347command, whose
1348.I "raison d'être
1349is to break the rule).
1350.PP
1351Bourne shell scripts can often be made
1352to run wild by passing them arguments containing spaces.
1353These will be split into multiple arguments using
1354.CW IFS ,
1355often at inopportune times.
1356In
1357.I rc ,
1358values of variables, including command line arguments, are not re-read
1359when substituted into a command.
1360Arguments have presumably been scanned in the parent process, and ought
1361not to be re-read.
1362.PP
1363Why does Bourne re-scan commands after variable substitution?
1364He needs to be able to store lists of arguments in variables whose values are
1365character strings.
1366If we eliminate re-scanning, we must change the type of variables, so that
1367they can explicitly carry lists of strings.
1368.PP
1369This introduces some
1370conceptual complications.  We need a notation for lists of words.
1371There are two different kinds of concatenation, for strings \(em
1372.CW $a^$b ,
1373and lists \(em
1374.CW "($a $b)" .
1375The difference between
1376.CW ()
1377and
1378.CW ''
1379is confusing to novices,
1380although the distinction is arguably sensible \(em
1381a null argument is not the same as no argument.
1382.PP
1383Bourne also rescans input when doing command substitution.
1384This is because the text enclosed in back-quotes is not
1385a string, but a command.  Properly, it ought to
1386be parsed when the enclosing command is, but this makes
1387it difficult to
1388handle nested command substitutions, like this:
1389.P1
1390size=`wc -l \e`ls -t|sed 1q\e``
1391.P2
1392The inner back-quotes must be escaped
1393to avoid terminating the outer command.
1394This can get much worse than the above example;
1395the number of
1396.CW \e 's
1397required is exponential in the nesting depth.
1398.I Rc
1399fixes this by making the backquote a unary operator
1400whose argument is a command, like this:
1401.P1
1402size=`{wc -l `{ls -t|sed 1q}}
1403.P2
1404No escapes are ever required, and the whole thing
1405is parsed in one pass.
1406.PP
1407For similar reasons
1408.I rc
1409defines signal handlers as though they were functions,
1410instead of associating a string with each signal, as Bourne does,
1411with the attendant possibility of getting a syntax error message
1412in response to typing the interrupt character.  Since
1413.I rc
1414parses input when typed, it reports errors when you make them.
1415.PP
1416For all this trouble, we gain substantial semantic simplifications.
1417There is no need for the distinction between
1418.CW $*
1419and
1420.CW $@ .
1421There is no need for four types of quotation, nor the
1422extremely complicated rules that govern them.  In
1423.I rc
1424you use quotation marks when you want a syntax character
1425to appear in an argument, or an argument that is the empty string,
1426and at no other time.
1427.CW IFS
1428is no longer used, except in the one case where it was indispensable:
1429converting command output into argument lists during command substitution.
1430.PP
1431This also avoids an important UNIX security hole.
1432In UNIX, the
1433.I system
1434and
1435.I popen
1436functions call
1437.CW /bin/sh
1438to execute a command.  It is impossible to use either
1439of these routines with any assurance that the specified command will
1440be executed, even if the caller of
1441.I system
1442or
1443.I popen
1444specifies a full path name for the command.  This can be devastating
1445if it occurs in a set-userid program.
1446The problem is that
1447.CW IFS
1448is used to split the command into words, so an attacker can just
1449set
1450.CW IFS=/
1451in his environment and leave a Trojan horse
1452named
1453.CW usr
1454or
1455.CW bin
1456in the current working directory before running the privileged program.
1457.I Rc
1458fixes this by never rescanning input for any reason.
1459.PP
1460Most of the other differences between
1461.I rc
1462and the Bourne shell are not so serious.  I eliminated Bourne's
1463peculiar forms of variable substitution, like
1464.P1
1465echo ${a=b} ${c-d} ${e?error}
1466.P2
1467because they are little used, redundant and easily
1468expressed in less abstruse terms.
1469I deleted the builtins
1470.CW export ,
1471.CW readonly ,
1472.CW break ,
1473.CW continue ,
1474.CW read ,
1475.CW return ,
1476.CW set ,
1477.CW times
1478and
1479.CW unset
1480because they seem redundant or
1481only marginally useful.
1482.PP
1483Where Bourne's syntax draws from Algol 68,
1484.I rc 's
1485is based on C or Awk.  This is harder to defend.
1486I believe that, for example
1487.P1
1488if(test -f junk) rm junk
1489.P2
1490is better syntax than
1491.P1
1492if test -f junk; then rm junk; fi
1493.P2
1494because it is less cluttered with keywords,
1495it avoids the semicolons that Bourne requires
1496in odd places,
1497and the syntax characters better set off the
1498active parts of the command.
1499.PP
1500The one bit of large-scale syntax that Bourne
1501unquestionably does better than
1502.I rc
1503is the
1504.CW if
1505statement with
1506.CW "else
1507clause.
1508.I Rc 's
1509.CW if
1510has no terminating
1511.CW fi -like
1512bracket.  As a result, the parser cannot
1513tell whether or not to expect an
1514.CW "else
1515clause without looking ahead in its input.
1516The problem is that after reading, for example
1517.P1
1518if(test -f junk) echo junk found
1519.P2
1520in interactive mode,
1521.I rc
1522cannot decide whether to execute it immediately and print
1523.CW $prompt(1) ,
1524or to print
1525.CW $prompt(2)
1526and wait for the
1527.CW "else
1528to be typed.
1529In the Bourne shell, this is not a problem, because the
1530.CW if
1531command must end with
1532.CW fi ,
1533regardless of whether it contains an
1534.CW else
1535or not.
1536.PP
1537.I Rc 's
1538admittedly feeble solution is to declare that the
1539.CW else
1540clause is a separate statement, with the semantic
1541proviso that it must immediately follow an
1542.CW if ,
1543and to call it
1544.CW "if not
1545rather than
1546.CW else ,
1547as a reminder that something odd is going on.
1548The only noticeable consequence of this is that
1549the braces are required in the construction
1550.P1
1551for(i){
1552    if(test -f $i) echo $i found
1553    if not echo $i not found
1554}
1555.P2
1556and that
1557.I rc
1558resolves the ``dangling else'' ambiguity in opposition
1559to most people's expectations.
1560.PP
1561It is remarkable that in the four most recent editions of the UNIX system
1562programmer's manual the Bourne shell grammar described in the manual page
1563does not admit the command
1564.CW who|wc .
1565This is surely an oversight, but it suggests something darker:
1566nobody really knows what the Bourne shell's grammar is.  Even examination
1567of the source code is little help.  The parser is implemented by recursive
1568descent, but the routines corresponding to the syntactic categories all
1569have a flag argument that subtly changes their operation depending on the
1570context.
1571.I Rc 's
1572parser is implemented using
1573.I yacc ,
1574so I can say precisely what the grammar is.
1575.NH
1576Acknowledgements
1577.PP
1578Rob Pike, Howard Trickey and other Plan 9 users have been insistent, incessant
1579sources of good ideas and criticism.  Some examples in this document are plagiarized
1580from [Bourne],
1581as are most of
1582.I rc 's
1583good features.
1584.NH
1585Reference
1586.LP
1587S. R. Bourne,
1588UNIX Time-Sharing System: The UNIX Shell,
1589Bell System Technical Journal, Volume 57 number 6, July-August 1978
1590