Newsgroups: comp.sources.misc From: byron@archone.tamu.edu (Byron Rakitzis) Subject: v23i064: rc - A Plan 9 shell reimplementation, v1.2, Part04/06 Message-ID: <1991Oct18.034413.2362@sparky.imd.sterling.com> X-Md4-Signature: b20aaa006ae36b5a6e1aeb17a64f5b33 Date: Fri, 18 Oct 1991 03:44:13 GMT Approved: kent@sparky.imd.sterling.com Submitted-by: byron@archone.tamu.edu (Byron Rakitzis) Posting-number: Volume 23, Issue 64 Archive-name: rc/part04 Environment: UNIX Supersedes: rc: Volume 20, Issue 10-13 #!/bin/sh # do not concatenate these parts, unpack them in order with /bin/sh # file parse.y continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 4; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping parse.y' else echo 'x - continuing file parse.y' sed 's/^X//' << 'SHAR_EOF' >> 'parse.y' && redir : DUP { $$ = newnode(rDUP,$1.type,$1.left,$1.right); } X | REDIR word { $$ = newnode(rREDIR,$1.type,$1.fd,$2); X if ($1.type == HEREDOC && !qdoc($2, $$)) YYABORT; /* queue heredocs up */ X } X case : CASE words ';' { $$ = newnode(rCASE, $2); } X | CASE words '\n' { $$ = newnode(rCASE, $2); } X cbody : cmd { $$ = newnode(CBODY, $1, NULL); } X | case cbody { $$ = newnode(CBODY, $1, $2); } X | cmdsan cbody { $$ = newnode(CBODY, $1, $2); } X iftail : cmd %prec ELSE X | brace ELSE optnl cmd { $$ = newnode(rELSE,$1,$4); } X cmd : /* empty */ %prec WHILE { $$ = NULL; } X | simple X | brace epilog { $$ = newnode(BRACE,$1,$2); } X | IF paren optnl iftail { $$ = newnode(rIF,$2,$4); } X | FOR '(' word IN words ')' optnl cmd { $$ = newnode(FORIN,$3,$5,$8); } X | FOR '(' word ')' optnl cmd { $$ = newnode(FORIN,$3,star,$6); } X | WHILE paren optnl cmd { $$ = newnode(rWHILE,$2,$4); } X | SWITCH '(' word ')' optnl '{' cbody '}' { $$ = newnode(rSWITCH,$3,$7); } X | TWIDDLE optcaret word words { $$ = newnode(MATCH,$3,$4); } X | cmd ANDAND optnl cmd { $$ = newnode(rANDAND,$1,$4); } X | cmd OROR optnl cmd { $$ = newnode(rOROR,$1,$4); } X | cmd PIPE optnl cmd { $$ = newnode(rPIPE,$2.left,$2.right,$1,$4); } X | redir cmd %prec BANG { $$ = ($2 != NULL ? newnode(PRE,$1,$2) : $1); } X | assign cmd %prec BANG { $$ = ($2 != NULL ? newnode(PRE,$1,$2) : $1); } X | BANG optcaret cmd { $$ = newnode(rBANG,$3); } X | SUBSHELL optcaret cmd { $$ = newnode(rSUBSHELL,$3); } X | FN words brace { $$ = newnode(NEWFN,$2,$3); } X | FN words { $$ = newnode(RMFN,$2); } X optcaret : /* empty */ X | '^' X simple : first X | simple word { $$ = ($2 != NULL ? newnode(ARGS,$1,$2) : $1); } X | simple redir { $$ = newnode(ARGS,$1,$2); } X first : comword X | first '^' sword { $$ = newnode(CONCAT,$1,$3); } X sword : comword X | keyword { $$ = newnode(rWORD,$1, NULL); } X word : sword X | word '^' sword { $$ = newnode(CONCAT,$1,$3); } X comword : '$' sword { $$ = newnode(VAR,$2); } X | '$' sword SUB words ')' { $$ = newnode(VARSUB,$2,$4); } X | COUNT sword { $$ = newnode(rCOUNT,$2); } X | FLAT sword { $$ = newnode(rFLAT, $2); } X | '`' sword { $$ = newnode(BACKQ,nolist,$2); } X | '`' brace { $$ = newnode(BACKQ,nolist,$2); } X | BACKBACK word brace { $$ = newnode(BACKQ,$2,$3); } X | BACKBACK word sword { $$ = newnode(BACKQ,$2,$3); } X | '(' words ')' { $$ = $2; } X | REDIR brace { $$ = newnode(NMPIPE,$1.type,$1.fd,$2); } X | WORD { $$ = ($1.w[0] == '\'') ? newnode(QWORD, $1.w+1, NULL) : newnode(rWORD,$1.w, $1.m); } X keyword : FOR { $$ = "for"; } X | IN { $$ = "in"; } X | WHILE { $$ = "while"; } X | IF { $$ = "if"; } X | SWITCH { $$ = "switch"; } X | FN { $$ = "fn"; } X | ELSE { $$ = "else"; } X | CASE { $$ = "case"; } X | TWIDDLE { $$ = "~"; } X | BANG { $$ = "!"; } X | SUBSHELL { $$ = "@"; } X words : { $$ = NULL; } X | words word { $$ = ($1 != NULL ? ($2 != NULL ? newnode(LAPPEND,$1,$2) : $1) : $2); } X optnl : /* empty */ X | optnl '\n' X %% X void initparse() { X star = treecpy(newnode(VAR,newnode(rWORD,"*",NULL)), ealloc); X nolist = treecpy(newnode(VAR,newnode(rWORD,"ifs",NULL)), ealloc); } X SHAR_EOF echo 'File parse.y is complete' && chmod 0644 parse.y || echo 'restore of parse.y failed' Wc_c="`wc -c < 'parse.y'`" test 5406 -eq "$Wc_c" || echo 'parse.y: original size 5406, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= plan9.ps ============== if test -f 'plan9.ps' -a X"$1" != X"-c"; then echo 'x - skipping plan9.ps (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting plan9.ps (Text)' sed 's/^X//' << 'SHAR_EOF' > 'plan9.ps' && %!PS %%Version: 3.3 %%DocumentFonts: (atend) %%Pages: (atend) %%EndComments % % Version 3.3 prologue for troff files. % X /#copies 1 store /aspectratio 1 def /formsperpage 1 def /landscape false def /linewidth .3 def /magnification 1 def /margin 0 def /orientation 0 def /resolution 720 def /rotation 1 def /xoffset 0 def /yoffset 0 def X /roundpage true def /useclippath true def /pagebbox [0 0 612 792] def X /R /Times-Roman def /I /Times-Italic def /B /Times-Bold def /BI /Times-BoldItalic def /H /Helvetica def /HI /Helvetica-Oblique def /HB /Helvetica-Bold def /HX /Helvetica-BoldOblique def /CW /Courier def /CO /Courier def /CI /Courier-Oblique def /CB /Courier-Bold def /CX /Courier-BoldOblique def /PA /Palatino-Roman def /PI /Palatino-Italic def /PB /Palatino-Bold def /PX /Palatino-BoldItalic def /Hr /Helvetica-Narrow def /Hi /Helvetica-Narrow-Oblique def /Hb /Helvetica-Narrow-Bold def /Hx /Helvetica-Narrow-BoldOblique def /KR /Bookman-Light def /KI /Bookman-LightItalic def /KB /Bookman-Demi def /KX /Bookman-DemiItalic def /AR /AvantGarde-Book def /AI /AvantGarde-BookOblique def /AB /AvantGarde-Demi def /AX /AvantGarde-DemiOblique def /NR /NewCenturySchlbk-Roman def /NI /NewCenturySchlbk-Italic def /NB /NewCenturySchlbk-Bold def /NX /NewCenturySchlbk-BoldItalic def /ZD /ZapfDingbats def /ZI /ZapfChancery-MediumItalic def /S /S def /S1 /S1 def /GR /Symbol def X /inch {72 mul} bind def /min {2 copy gt {exch} if pop} bind def X /setup { X counttomark 2 idiv {def} repeat pop X X landscape {/orientation 90 orientation add def} if X /scaling 72 resolution div def X linewidth setlinewidth X 1 setlinecap X X pagedimensions X xcenter ycenter translate X orientation rotation mul rotate X width 2 div neg height 2 div translate X xoffset inch yoffset inch neg translate X margin 2 div dup neg translate X magnification dup aspectratio mul scale X scaling scaling scale X X /Symbol /S Sdefs cf X /Times-Roman /S1 S1defs cf X 0 0 moveto } def X /pagedimensions { X useclippath userdict /gotpagebbox known not and { X /pagebbox [clippath pathbbox newpath] def X roundpage currentdict /roundpagebbox known and {roundpagebbox} if X } if X pagebbox aload pop X 4 -1 roll exch 4 1 roll 4 copy X landscape {4 2 roll} if X sub /width exch def X sub /height exch def X add 2 div /xcenter exch def X add 2 div /ycenter exch def X userdict /gotpagebbox true put } def X /pagesetup { X /page exch def X currentdict /pagedict known currentdict page known and { X page load pagedict exch get cvx exec X } if } def X /decodingdefs [ X {counttomark 2 idiv {y moveto show} repeat} X {neg /y exch def counttomark 2 idiv {y moveto show} repeat} X {neg moveto {2 index stringwidth pop sub exch div 0 32 4 -1 roll widthshow} repeat} X {neg moveto {spacewidth sub 0.0 32 4 -1 roll widthshow} repeat} X {counttomark 2 idiv {y moveto show} repeat} X {neg setfunnytext} ] def X /setdecoding {/t decodingdefs 3 -1 roll get bind def} bind def X /w {neg moveto show} bind def /m {neg dup /y exch def moveto} bind def /done {/lastpage where {pop lastpage} if} def X /f { X dup /font exch def findfont exch X dup /ptsize exch def scaling div dup /size exch def scalefont setfont X linewidth ptsize mul scaling 10 mul div setlinewidth X /spacewidth ( ) stringwidth pop def } bind def X /changefont { X /fontheight exch def X /fontslant exch def X currentfont [ X 1 0 X fontheight ptsize div fontslant sin mul fontslant cos div X fontheight ptsize div X 0 0 X ] makefont setfont } bind def X /sf {f} bind def X /cf { X dup length 2 idiv X /entries exch def X /chtab exch def X /newfont exch def X X findfont dup length 1 add dict X /newdict exch def X {1 index /FID ne {newdict 3 1 roll put} {pop pop} ifelse} forall X X newdict /Metrics entries dict put X newdict /Metrics get X begin X chtab aload pop X 1 1 entries {pop def} for X newfont newdict definefont pop X end } bind def X % % A few arrays used to adjust reference points and character widths in some % of the printer resident fonts. If square roots are too high try changing % the lines describing /radical and /radicalex to, % % /radical [0 -75 550 0] % /radicalex [-50 -75 500 0] % % Move braceleftbt a bit - default PostScript character is off a bit. % X /Sdefs [ X /bracketlefttp [201 500] X /bracketleftbt [201 500] X /bracketrighttp [-81 380] X /bracketrightbt [-83 380] X /braceleftbt [203 490] X /bracketrightex [220 -125 500 0] X /radical [0 0 550 0] X /radicalex [-50 0 500 0] X /parenleftex [-20 -170 0 0] X /integral [100 -50 500 0] X /infinity [10 -75 730 0] ] def X /S1defs [ X /underscore [0 80 500 0] X /endash [7 90 650 0] ] def % % Tries to round clipping path dimensions, as stored in array pagebbox, so they % match one of the known sizes in the papersizes array. Lower left coordinates % are always set to 0. % X /roundpagebbox { X 7 dict begin X /papersizes [8.5 inch 11 inch 14 inch 17 inch] def X X /mappapersize { X /val exch def X /slop .5 inch def X /diff slop def X /j 0 def X 0 1 papersizes length 1 sub { X /i exch def X papersizes i get val sub abs X dup diff le {/diff exch def /j i def} {pop} ifelse X } for X diff slop lt {papersizes j get} {val} ifelse X } def X X pagebbox 0 0 put X pagebbox 1 0 put X pagebbox dup 2 get mappapersize 2 exch put X pagebbox dup 3 get mappapersize 3 exch put X end } bind def X %%EndProlog %%BeginSetup mark /linewidth 0.5 def /xoffset 0 def /yoffset 0 def /#copies 1 store /magnification 1 def %%FormsPerPage: 1 /formsperpage 1 def X /landscape false def /resolution 720 def setup 2 setdecoding %%EndSetup %%Page: 1 1 /saveobj save def mark 1 pagesetup 12 B f (Rc \320 A Shell for Plan 9 and UNIX Systems)9 2230 1 1765 1230 t 10 I f (Tom Duff)1 381 1 2689 1470 t 10 R f (AT&T Bell Laboratories)2 993 1 2383 1650 t (Murray Hill, New Jersey 07974)4 1267 1 2246 1770 t 10 I f (ABSTRACT)2643 2150 w (Rc)1330 2410 w 10 R f ( also runs on a variety of traditional sys-)8 1641( It)1 115( interpreter for Plan 9.)4 900(is a command)2 561 4 1463 2410 t ( provides similar facilities to Bourne's)5 1580( It)1 120( SunOS and the Tenth Edition.)5 1273(tems, including)1 627 4 1080 2530 t 10 I f (/bin/sh)1080 2650 w 10 R f ( paper intro-)2 497( This)1 229(, with some small additions and mostly less idiosyncratic syntax.)9 2601 3 1353 2650 t (duces)1080 2770 w 10 I f (rc)1335 2770 w 10 R f ( why it varies)3 547('s highlights with numerous examples, and discusses its design and)9 2715 2 1418 2770 t (from Bourne's.)1 610 1 1080 2890 t 10 B f (1. Introduction)1 670 1 720 3250 t 10 R f ( new)1 208( porting the Bourne shell to an incompatible)7 1875( As)1 177(Plan 9 needs a command-programming language.)5 2060 4 720 3406 t ( new command interpreter, called)4 1350(environment seemed a daunting task, I chose to write a)9 2232 2 720 3526 t 10 I f (rc)4330 3526 w 10 R f (because it runs)2 599 1 4441 3526 t ( could hardly resist trying to)5 1220( tinkering with perfection is a dangerous business, I)8 2197(commands. Although)1 903 3 720 3646 t ( Thus)1 250(`improve' on Bourne's design.)3 1226 2 720 3766 t 10 I f (rc)2221 3766 w 10 R f (is similar in spirit but different in detail from Bourne's shell.)10 2424 1 2329 3766 t (The bulk of this paper describes)5 1318 1 720 3922 t 10 I f (rc)2071 3922 w 10 R f ( features with many small examples and a few larger ones.)10 2426('s principal)1 460 2 2154 3922 t (We close with a discussion of the principles guiding)8 2143 1 720 4042 t 10 I f (rc)2895 4042 w 10 R f ( it differs from Bourne's design.)5 1317('s design and why)3 745 2 2978 4042 t ( features, as individual details)4 1198(The descriptive sections include little discussion of the rationale for particular)10 3122 2 720 4162 t ( skip to the discussion at the end before)8 1632( impatient reader may wish to)5 1230( The)1 213(are hard to justify in isolation.)5 1245 4 720 4282 t (skimming the expository parts of the paper.)6 1740 1 720 4402 t 10 B f ( commands)1 486(2. Simple)1 420 2 720 4642 t 10 R f (For the simplest uses)3 881 1 720 4798 t 10 I f (rc)1639 4798 w 10 R f ( all of the following behave as)6 1293( Thus)1 263(has syntax familiar to Bourne-shell users.)5 1724 3 1760 4798 t (expected:)720 4918 w 9 CW f (date)1008 5088 w (con alice)1 486 1 1008 5198 t (who >user.names)1 810 1 1008 5308 t (who >>user.names)1 864 1 1008 5418 t (wc )2929 840 w 10 R f ( in braces causes the com-)5 1054(followed by a command)3 971 2 3015 840 t ( parent command \()3 751( The)1 205( be run with its standard output or input attached to a pipe.)12 2334(mand to)1 326 4 720 960 t 10 CW f (cmp)4336 960 w 10 R f (in the exam-)2 499 1 4541 960 t ( descriptor or other, and with an argument)7 1701(ple\) is started with the other end of the pipe attached to some file)13 2619 2 720 1080 t ( connect to the pipe when opened \(e.g.)7 1601(that will)1 341 2 720 1200 t 10 CW f (/dev/fd/6)2721 1200 w 10 R f ( systems without)2 691(.\) On)1 239 2 3261 1200 t 10 CW f (/dev/fd)4225 1200 w 10 R f (or some-)1 361 1 4679 1200 t (thing similar \(SunOS for example\) this feature does not work.)9 2475 1 720 1320 t 10 B f ( status)1 275(10. Exit)1 353 2 720 1560 t 10 R f ( Plan 9 status is a character)6 1153( On)1 184( executed it.)2 509(When a command exits it returns status to the program that)10 2474 4 720 1716 t ( normal termination it is empty.)5 1267( On)1 172(string describing an error condition.)4 1434 3 720 1836 t 10 I f (Rc)720 1992 w 10 R f ( the variable)2 537(captures commands' exit statuses in)4 1521 2 871 1992 t 10 CW f ($status)2976 1992 w 10 R f ( a simple command the value of)6 1408(. For)1 236 2 3396 1992 t 10 CW f ($status)720 2112 w 10 R f ( a pipeline)2 420( For)1 191(is just as described above.)4 1048 3 1167 2112 t 10 CW f ($status)2853 2112 w 10 R f ( to the concatenation of the statuses of)7 1535(is set)1 205 2 3300 2112 t (the pipeline components with)3 1180 1 720 2232 t 10 CW f (|)1925 2232 w 10 R f (characters for separators.)2 998 1 2010 2232 t 10 I f (Rc)720 2388 w 10 R f ( control flow, many of them conditioned by the status returned from previously)12 3286(has a several kinds of)4 895 2 859 2388 t ( Any)1 224(executed commands.)1 839 2 720 2508 t 10 CW f ($status)1810 2508 w 10 R f (containing only)1 627 1 2257 2508 t 10 CW f (0)2911 2508 w 10 R f ('s and)1 243 1 2971 2508 t 10 CW f (|)3241 2508 w 10 R f ('s has boolean value)3 818 1 3301 2508 t 10 I f (true)4146 2508 w 10 R f ( other status)2 485(. Any)1 248 2 4307 2508 t (is)720 2628 w 10 I f (false)812 2628 w 10 R f (.)1001 2628 w 10 B f ( grouping)1 415(11. Command)1 625 2 720 2868 t 10 R f (A sequence of commands enclosed in)5 1505 1 720 3024 t 10 CW f ({})2250 3024 w 10 R f ( example:)1 391( For)1 189(may be used anywhere a command is required.)7 1873 3 2395 3024 t 9 CW f ({sleep 3600;echo 'Time''s up!'}&)3 1728 1 1008 3194 t 10 R f ( the braces:)2 454( Without)1 378(will wait an hour in the background, then print a message.)10 2319 3 720 3374 t 9 CW f (sleep 3600;echo 'Time''s up!'&)3 1620 1 1008 3544 t 10 R f (this would lock up the terminal for an hour, then print the message in the background!)15 3440 1 720 3724 t 10 B f ( flow \320)2 333(12. Control)1 508 2 720 3964 t 10 CW f (for)1586 3964 w 10 R f (A command may be executed once for each member of a list by typing, for example:)15 3387 1 720 4120 t 9 CW f (for\(i in printf scanf putchar\) look $i /usr/td/lib/dw.dat)7 3078 1 1008 4290 t 10 R f (This looks for each of the words)6 1292 1 720 4470 t 10 CW f (printf)2037 4470 w 10 R f (,)2397 4470 w 10 CW f (scanf)2447 4470 w 10 R f (and)2772 4470 w 10 CW f (putchar)2941 4470 w 10 R f ( general form is)3 629( The)1 205(in the given file.)3 655 3 3386 4470 t 9 CW f (for\()1008 4640 w 9 I f (name)1224 4640 w 9 CW f (in)1473 4640 w 9 I f (list)1635 4640 w 9 CW f (\))1745 4640 w 9 I f (command)1853 4640 w 10 R f (or)720 4820 w 9 CW f (for\()1008 4990 w 9 I f (name)1224 4990 w 9 CW f (\))1419 4990 w 9 I f (command)1527 4990 w 10 R f ( first case)2 394(In the)1 235 2 720 5170 t 10 I f (command)1380 5170 w 10 R f (is executed once for each member of)6 1503 1 1799 5170 t 10 I f (list)3333 5170 w 10 R f (with that member assigned to variable)5 1553 1 3487 5170 t 10 I f (name)720 5290 w 10 R f (. If)1 141 1 936 5290 t 10 CW f (in)1102 5290 w 10 I f (list)1247 5290 w 10 R f (is not given,)2 492 1 1395 5290 t 10 I f ($*)1912 5290 w 10 R f (is used.)1 300 1 2037 5290 t 10 B f ( execution \320)2 555(13. Conditional)1 682 2 720 5530 t 10 CW f (if)1982 5530 w 10 I f (Rc)720 5686 w 10 R f ( example:)1 391( For)1 189(also provides a general if-statement.)4 1444 3 850 5686 t 9 CW f (if\(cyntax *.c\) cc -g -o cmd *.c)6 1674 1 1008 5856 t 10 R f (runs the C compiler whenever)4 1259 1 720 6036 t 10 CW f (cyntax)2018 6036 w 10 R f (finds no problems with)3 967 1 2417 6036 t 10 CW f (*.c)3423 6036 w 10 R f ( `if not' statement provides a)5 1226(. An)1 211 2 3603 6036 t ( example:)1 391( For)1 189(two-tailed conditional.)1 905 3 720 6156 t 9 CW f (for\(i\){)1008 6326 w (if\(test -f /tmp/$i\) echo $i already in /tmp)7 2322 1 1224 6436 t (if not cp $i /tmp)4 918 1 1224 6546 t (})1008 6656 w 10 R f (This loops over each file in)5 1090 1 720 6836 t 10 CW f ($*)1835 6836 w 10 R f (, copying to)2 475 1 1955 6836 t 10 CW f (/tmp)2455 6836 w 10 R f (those that do not already appear there, and printing a mes-)10 2320 1 2720 6836 t (sage for those that do.)4 879 1 720 6956 t cleartomark showpage saveobj restore %%EndPage: 4 4 %%Page: 5 5 /saveobj save def mark 5 pagesetup 10 R f (- 5 -)2 166 1 2797 480 t 10 B f ( flow \320)2 333(14. Control)1 508 2 720 840 t 10 CW f (while)1586 840 w 10 I f (Rc)720 996 w 10 R f ('s while statement looks like this:)5 1342 1 825 996 t 9 CW f (while\(newer subr.c subr.o\) sleep 5)4 1836 1 1008 1166 t 10 R f (This waits until)2 623 1 720 1346 t 10 CW f (subr.o)1368 1346 w 10 R f (is newer than)2 532 1 1753 1346 t 10 CW f (subr.c)2310 1346 w 10 R f (\(presumably because the C compiler finished with it.\))7 2147 1 2695 1346 t 10 B f ( flow \320)2 333(15. Control)1 508 2 720 1586 t 10 CW f (switch)1586 1586 w 10 I f (Rc)720 1742 w 10 R f ( general form is)3 629( Its)1 150(provides a switch statement to do pattern-matching on arbitrary strings.)9 2852 3 850 1742 t 9 CW f (switch\()1008 1912 w 9 I f (word)1386 1912 w 9 CW f (\){)1571 1912 w (case)1008 2022 w 9 I f (pattern ...)1 352 1 1278 2022 t (commands)1224 2132 w 9 CW f (case)1008 2242 w 9 I f (pattern ...)1 352 1 1278 2242 t (commands)1224 2352 w 9 CW f (...)1008 2462 w (})1008 2572 w 10 I f (Rc)720 2752 w 10 R f ( are the same as)4 647( Patterns)1 376(attempts to match the word against the patterns in each case statement in turn.)13 3164 3 853 2752 t (for filename matching, except that)4 1372 1 720 2872 t 10 CW f (/)2117 2872 w 10 R f (and the first characters of)4 1013 1 2202 2872 t 10 CW f (.)3240 2872 w 10 R f (and)3350 2872 w 10 CW f (..)3519 2872 w 10 R f (need not be matched explicitly.)4 1251 1 3689 2872 t ( to the next case \(or the end of the switch\) are)11 1864(If any pattern matches, the commands following that case up)9 2456 2 720 3028 t ( example,)1 388( For)1 189(executed, and execution of the switch is complete.)7 2010 3 720 3148 t 9 CW f (switch\($#*\){)1008 3318 w (case 1)1 324 1 1008 3428 t (cat >>$1)1 432 1 1224 3538 t (case 2)1 324 1 1008 3648 t (cat >>$2 <$1)2 648 1 1224 3758 t (case *)1 324 1 1008 3868 t (echo 'Usage: append [from] to')4 1620 1 1224 3978 t (})1008 4088 w 10 R f ( two, the first)3 536( With)1 251( with one file argument, it tacks standard input to its end.)11 2279( Called)1 311(is an append command.)3 943 5 720 4268 t ( other number elicits a usage message.)6 1533( Any)1 222(is appended to the second.)4 1051 3 720 4388 t (The built-in)1 475 1 720 4544 t 10 CW f (\304)1220 4544 w 10 R f ( arguments are a)3 659( Its)1 151( more concise than a switch.)5 1136(command also matches patterns, and is often)6 1789 4 1305 4544 t ( sets)1 181( It)1 118(string and a list of patterns.)5 1123 3 720 4664 t 10 CW f ($status)2173 4664 w 10 R f (to true if and only if any of the patterns matches the string.)12 2416 1 2624 4664 t (The following example processes option arguments for the)7 2349 1 720 4784 t 10 I f (man)3094 4784 w 10 R f (\(1\) command:)1 563 1 3266 4784 t 9 CW f (opt=\(\))1008 4954 w (while\(\304 $1 -* [1-9] 10\){)4 1296 1 1008 5064 t (switch\($1\){)1224 5174 w (case [1-9] 10)2 702 1 1224 5284 t (sec=$1 secn=$1)1 756 1 1440 5394 t (case -f)1 378 1 1224 5504 t (c=f s=f)1 378 1 1440 5614 t (case -[qwnt])1 648 1 1224 5724 t (cmd=$1)1440 5834 w (case -T*)1 432 1 1224 5944 t (T=$1)1440 6054 w (case -*)1 378 1 1224 6164 t (opt=\($opt $1\))1 702 1 1440 6274 t (})1224 6384 w (shift)1224 6494 w (})1008 6604 w cleartomark showpage saveobj restore %%EndPage: 5 5 %%Page: 6 6 /saveobj save def mark 6 pagesetup 10 R f (- 6 -)2 166 1 2797 480 t 10 B f (16. Functions)1 598 1 720 840 t 10 R f (Functions may be defined by typing)5 1441 1 720 996 t 9 CW f (fn)1008 1166 w 9 I f (name)1170 1166 w 9 CW f ({)1419 1166 w 9 I f (commands)1527 1166 w 9 CW f (})1966 1166 w 10 R f (Subsequently, whenever a command named)4 1795 1 720 1346 t 10 I f (name)2550 1346 w 10 R f (is encountered, the remainder of the command's argu-)7 2238 1 2802 1346 t ( to)1 106(ment list will assigned)3 910 2 720 1466 t 10 CW f ($*)1764 1466 w 10 R f (and)1912 1466 w 10 I f (rc)2084 1466 w 10 R f (will execute the)2 638 1 2195 1466 t 10 I f (commands)2861 1466 w 10 R f ( value of)2 355(. The)1 233 2 3288 1466 t 10 CW f ($*)3904 1466 w 10 R f (will be restored on com-)4 988 1 4052 1466 t ( example:)1 391(pletion. For)1 492 2 720 1586 t 9 CW f (fn g {)2 324 1 1008 1756 t (gre -e $1 *.[hcyl])3 972 1 1224 1866 t (})1008 1976 w 10 R f (defines)720 2156 w 10 CW f (g)1033 2156 w 10 I f (pattern)1118 2156 w 10 R f (to look for occurrences of)4 1030 1 1432 2156 t 10 I f (pattern)2487 2156 w 10 R f (in all program source files in the current directory.)8 2015 1 2801 2156 t (Function definitions are deleted by writing)5 1707 1 720 2312 t 9 CW f (fn)1008 2482 w 9 I f (name)1170 2482 w 10 R f (with no function body.)3 911 1 720 2662 t 10 B f ( execution)1 430(17. Command)1 625 2 720 2902 t 10 R f ( very little about what)4 897(Up to now we've said)4 892 2 720 3058 t 10 I f (rc)2539 3058 w 10 R f ( the command name)3 822( If)1 121(does to execute a simple command.)5 1445 3 2652 3058 t (is the name of a function defined using)7 1570 1 720 3178 t 10 CW f (fn)2317 3178 w 10 R f ( if it is the name of a built-)8 1082( Otherwise,)1 487(, the function is executed.)4 1034 3 2437 3178 t (in command, the built-in is executed directly by)7 1964 1 720 3298 t 10 I f (rc)2716 3298 w 10 R f ( if the name contains a)5 936(. Otherwise,)1 517 2 2799 3298 t 10 CW f (/)4284 3298 w 10 R f (, it is taken to be)5 696 1 4344 3298 t (the name of a binary program and is executed using)9 2155 1 720 3418 t 10 I f (exec)2910 3418 w 10 R f ( the name contains no)4 907(\(2\). If)1 267 2 3086 3418 t 10 CW f (/)4294 3418 w 10 R f (, then directories)2 686 1 4354 3418 t (mentioned in the variable)3 1018 1 720 3538 t 10 CW f ($path)1763 3538 w 10 R f (are searched until an executable file is found.)7 1806 1 2088 3538 t 10 B f ( commands)1 486(18. Built-in)1 504 2 720 3778 t 10 R f ( executed internally by)3 924(Several commands are)2 909 2 720 3934 t 10 I f (rc)2582 3934 w 10 R f (because they are difficult or impossible to implement oth-)8 2346 1 2694 3934 t (erwise.)720 4054 w 10 CW f (. [-i])1 360 1 720 4210 t 10 I f (file ...)1 228 1 1140 4210 t 10 R f (Execute commands from)2 1008 1 970 4330 t 10 I f (file)2008 4330 w 10 R f (.)2136 4330 w 10 CW f ($*)2216 4330 w 10 R f ( reminder of the argument list follow-)6 1545(is set for the duration to the)6 1129 2 2366 4330 t (ing)970 4450 w 10 I f (file)1125 4450 w 10 R f (.)1253 4450 w 10 CW f ($path)1330 4450 w 10 R f (is used to search for)4 806 1 1657 4450 t 10 I f (file)2490 4450 w 10 R f (. Option)1 354 1 2618 4450 t 10 CW f (-i)2998 4450 w 10 R f (indicates interactive input)2 1034 1 3144 4450 t 10 S f (-)4204 4450 w 10 R f (a prompt \(found in)3 755 1 4285 4450 t 10 CW f ($prompt)970 4570 w 10 R f (\) is printed before each command is read.)7 1651 1 1390 4570 t 10 CW f (builtin)720 4726 w 10 I f (command ...)1 488 1 1200 4726 t 10 R f (Execute)970 4846 w 10 I f (command)1316 4846 w 10 R f (as usual except that any function named)6 1597 1 1729 4846 t 10 I f (command)3351 4846 w 10 R f ( example,)1 388( For)1 189(is ignored.)1 422 3 3764 4846 t 9 CW f (fn cd{)1 324 1 1258 5016 t (builtin cd $* && pwd)4 1080 1 1474 5126 t (})1258 5236 w 10 R f (defines a replacement for the)4 1177 1 970 5416 t 10 CW f (cd)2177 5416 w 10 R f (built-in \(see below\) that announces the full name of the new direc-)11 2713 1 2327 5416 t (tory.)970 5536 w 10 CW f (cd [)1 240 1 720 5692 t 10 I f (dir)960 5692 w 10 CW f (])1077 5692 w 10 R f (Change the current directory to)4 1255 1 970 5812 t 10 I f (dir)2252 5812 w 10 R f ( default argument is)3 802(. The)1 232 2 2369 5812 t 10 CW f ($home)3430 5812 w 10 R f (.)3730 5812 w 10 CW f ($cdpath)3808 5812 w 10 R f (is a list of places in)5 784 1 4256 5812 t (which to search for)3 767 1 970 5932 t 10 I f (dir)1762 5932 w 10 R f (.)1879 5932 w 10 CW f (eval [)1 360 1 720 6088 t 10 I f (arg ...)1 239 1 1080 6088 t 10 CW f (])1319 6088 w 10 R f (The arguments are catenated separated by spaces into a string, read as input to)13 3159 1 970 6208 t 10 I f (rc)4158 6208 w 10 R f ( For)1 193(, and executed.)2 606 2 4241 6208 t (example,)970 6328 w 9 CW f (x='$y')1258 6498 w (y=Doody)1258 6608 w (eval echo Howdy, $x)3 1026 1 1258 6718 t 10 R f (would echo)1 463 1 970 6898 t 9 CW f (Howdy, Doody)1 648 1 1258 7068 t 10 R f (since the arguments of)3 901 1 970 7248 t 10 CW f (eval)1896 7248 w 10 R f (would be)1 369 1 2161 7248 t cleartomark showpage saveobj restore %%EndPage: 6 6 %%Page: 7 7 /saveobj save def mark 7 pagesetup 10 R f (- 7 -)2 166 1 2797 480 t 9 CW f (echo Howdy, $y)2 756 1 1258 830 t 10 R f (after substituting for)2 816 1 970 1010 t 10 CW f ($x)1811 1010 w 10 R f (.)1931 1010 w 10 CW f (shift [)1 420 1 720 1166 t 10 I f (n)1140 1166 w 10 CW f (])1190 1166 w 10 R f (Delete the first)2 593 1 970 1286 t 10 I f (n)1588 1286 w 10 R f (\(default 1\) elements of)3 906 1 1663 1286 t 10 CW f ($*)2594 1286 w 10 R f (.)2714 1286 w 10 CW f (wait [)1 360 1 720 1442 t 10 I f (pid)1080 1442 w 10 CW f (])1208 1442 w 10 R f ( given)1 263(Wait for the process with the)5 1231 2 970 1562 t 10 I f (pid)2505 1562 w 10 R f ( no)1 141( If)1 132(to exit.)1 294 3 2674 1562 t 10 I f (pid)3282 1562 w 10 R f (is given, all outstanding processes are)5 1589 1 3451 1562 t (waited for.)1 432 1 970 1682 t 10 CW f (whatis)720 1838 w 10 I f (name ...)1 316 1 1140 1838 t 10 R f ( each)1 209(Print the value of)3 694 2 970 1958 t 10 I f (name)1900 1958 w 10 R f (in a form suitable for input to)6 1189 1 2143 1958 t 10 I f (rc)3359 1958 w 10 R f ( output is an assignment to a vari-)7 1366(. The)1 232 2 3442 1958 t (able, the definition of a function, a call to)8 1709 1 970 2078 t 10 CW f (builtin)2711 2078 w 10 R f ( the path name of a)5 792(for a built-in command, or)4 1085 2 3163 2078 t ( example,)1 388( For)1 189(binary program.)1 643 3 970 2198 t 9 CW f (whatis path g cd who)4 1080 1 1258 2368 t 10 R f (might print)1 448 1 970 2548 t 9 CW f (path=\(. /bin /usr/bin\))2 1188 1 1258 2718 t (fn g {gre -e $1 *.[hycl]})5 1350 1 1258 2828 t (builtin cd)1 540 1 1258 2938 t (/bin/who)1258 3048 w 10 CW f (\304)720 3264 w 10 I f (subject pattern ...)2 697 1 840 3264 t 10 R f (The)970 3384 w 10 I f (subject)1150 3384 w 10 R f (is matched against each)3 945 1 1458 3384 t 10 I f (pattern)2428 3384 w 10 R f ( a match,)2 365( On)1 172(in turn.)1 289 3 2742 3384 t 10 CW f ($status)3594 3384 w 10 R f ( Otherwise,)1 486(is set to true.)3 514 2 4040 3384 t (it is set to)3 396 1 970 3504 t 10 CW f ('no match')1 602 1 1393 3504 t 10 R f ( The)1 207( are the same as for filename matching.)7 1582(. Patterns)1 399 3 1995 3504 t 10 I f (patterns)4210 3504 w 10 R f (are not sub-)2 475 1 4565 3504 t (jected to filename replacement before the)5 1698 1 970 3624 t 10 CW f (\304)2702 3624 w 10 R f (command is executed, so they need not be enclosed in)9 2244 1 2796 3624 t (quotation marks, unless of course, a literal match for)8 2102 1 970 3744 t 10 CW f (* [)1 145 1 3097 3744 t 10 R f (or)3267 3744 w 10 CW f (?)3375 3744 w 10 R f ( example)1 363( For)1 189(is required.)1 449 3 3485 3744 t 9 CW f (\304 $1 ?)2 324 1 1258 3914 t 10 R f (matches any single character, whereas)4 1525 1 970 4094 t 9 CW f (\304 $1 '?')2 432 1 1258 4264 t 10 R f (only matches a literal question mark.)5 1476 1 970 4444 t 10 B f ( I/O Redirection)2 694(19. Advanced)1 603 2 720 4684 t 10 I f (Rc)720 4840 w 10 R f ( of file descriptors other than 0 and 1 \(standard input and output\) by specifying the file)16 3472(allows redirection)1 718 2 850 4840 t (descriptor in square brackets)3 1144 1 720 4960 t 10 CW f ([ ])1 180 1 1889 4960 t 10 R f (after the)1 329 1 2094 4960 t 10 CW f (<)2448 4960 w 10 R f (or)2533 4960 w 10 CW f (>)2641 4960 w 10 R f ( example,)1 388(. For)1 214 2 2701 4960 t 9 CW f (cc junk.c >[2]junk.diag)2 1242 1 1008 5130 t 10 R f (saves the compiler's diagnostics in)4 1393 1 720 5310 t 10 CW f (junk.diag)2138 5310 w 10 R f (.)2678 5310 w ( replaced by a copy, in the sense of)8 1471(File descriptors may be)3 959 2 720 5466 t 10 I f (dup)3184 5466 w 10 R f (\(2\), of an already-open file by typing, for)7 1706 1 3334 5466 t (example)720 5586 w 9 CW f (cc junk.c >[2=1])2 864 1 1008 5756 t 10 R f ( in conjunction with other)4 1061( is more useful)3 609( It)1 117(This replaces file descriptor 2 with a copy of file descriptor 1.)11 2533 4 720 5936 t (redirections, like this)2 841 1 720 6056 t 9 CW f (cc junk.c >junk.out >[2=1])3 1404 1 1008 6226 t 10 R f ( descriptor 1 to)3 629(Redirections are evaluated from left to right, so this redirects file)10 2667 2 720 6406 t 10 CW f (junk.out)4050 6406 w 10 R f (, then points)2 510 1 4530 6406 t ( contrast,)1 366( By)1 167(file descriptor 2 at the same file.)6 1289 3 720 6526 t 9 CW f (cc junk.c >[2=1] >junk.out)3 1404 1 1008 6696 t 10 R f ( \(presumably the terminal\), and then directs file)7 2000(Redirects file descriptor 2 to a copy of file descriptor 1)10 2320 2 720 6876 t ( the first case, standard and diagnostic output will be intermixed in)11 2686( In)1 135( at a file.)3 355(descriptor 1)1 477 4 720 6996 t 10 CW f (junk.out)4400 6996 w 10 R f (. In)1 160 1 4880 6996 t (the second, diagnostic output will appear on the terminal, and standard output will be sent to the file.)17 4024 1 720 7116 t ( For)1 211( using the duplication notation with an empty right-hand side.)9 2664(File descriptors may be closed by)5 1445 3 720 7272 t cleartomark showpage saveobj restore %%EndPage: 7 7 %%Page: 8 8 /saveobj save def mark 8 pagesetup 10 R f (- 8 -)2 166 1 2797 480 t (example,)720 840 w 9 CW f (cc junk.c >[2=])2 810 1 1008 1010 t 10 R f (will discard diagnostics from the compilation.)5 1838 1 720 1190 t (Arbitrary file descriptors may be sent through a pipe by typing, for example)12 3031 1 720 1346 t 9 CW f (cc junk.c |[2] grep -v '\303$')5 1458 1 1008 1516 t 10 R f ( that the output of)4 779( Note)1 261( the C compiler's output.)4 1065(This deletes those ever-so-annoying blank lines from)6 2215 4 720 1696 t 10 CW f (grep)720 1816 w 10 R f (still appears on file descriptor 1.)5 1287 1 985 1816 t ( a pipe to some file descriptor other than zero.)9 1871(Very occasionally you may wish to connect the input side of)10 2449 2 720 1972 t (The notation)1 508 1 720 2092 t 9 CW f (cmd1 |[5=19] cmd2)2 918 1 1008 2262 t 10 R f (creates a pipeline with)3 895 1 720 2442 t 10 CW f (cmd1)1640 2442 w 10 R f ('s file descriptor 5 connected through a pipe to)8 1863 1 1880 2442 t 10 CW f (cmd2)3768 2442 w 10 R f ('s file descriptor 19.)3 804 1 4008 2442 t 10 B f ( documents)1 486(20. Here)1 385 2 720 2682 t 10 I f (Rc)720 2838 w 10 R f ( to commands, as in this)5 982(procedures may include data, called ``here documents'', to be provided as input)11 3206 2 852 2838 t (version of the)2 549 1 720 2958 t 10 I f (tel)1294 2958 w 10 R f (command)1419 2958 w 9 CW f (for\(i\) grep $i <[1=2])6 1890 1 1116 940 t (exit 1)1 324 1 1116 1050 t (})1008 1160 w ( default nroff)2 756(NT=n #)1 378 2 1008 1270 t (s='*' # section, default try all)5 1728 1 1008 1380 t (for\(i\) switch\($i\){)1 972 1 1008 1490 t (case -t)1 378 1 1008 1600 t (NT=t)1116 1710 w (case -n)1 378 1 1008 1820 t (NT=n)1116 1930 w (case -*)1 378 1 1008 2040 t (echo Usage: $0 '[-nt] [section] page ...' >[1=2])7 2592 1 1116 2150 t (exit 1)1 324 1 1116 2260 t (case [1-9] 10)2 702 1 1008 2370 t (s=$i)1116 2480 w (case *)1 324 1 1008 2590 t (eval 'pages=man'$s/$i'.*')1 1350 1 1116 2700 t (for\(page in $pages\){)2 1080 1 1116 2810 t (if\(test -f $page\))2 918 1 1224 2920 t ($NT\303roff -man $page)2 1026 1 1332 3030 t (if not)1 324 1 1224 3140 t (echo $0: $i not found >[1=2])5 1512 1 1332 3250 t (})1116 3360 w (})1008 3470 w 10 R f (Note the use of)3 619 1 720 3650 t 10 CW f (eval)1368 3650 w 10 R f ( Without)1 382(to make a list of candidate manual pages.)7 1675 2 1637 3650 t 10 CW f (eval)3723 3650 w 10 R f (, the)1 176 1 3963 3650 t 10 CW f (*)4168 3650 w 10 R f (stored in)1 352 1 4258 3650 t 10 CW f ($s)4640 3650 w 10 R f (would)4790 3650 w ( if it weren't, it would be)6 1098(not trigger filename matching \320 it's enclosed in quotation marks, and even)11 3222 2 720 3770 t (expanded when assigned to)3 1098 1 720 3890 t 10 CW f ($s)1844 3890 w 10 R f ( causes its arguments to be re-processed by)7 1728(. Eval)1 259 2 1964 3890 t 10 I f (rc)3977 3890 w 10 R f ('s parser and interpreter,)3 980 1 4060 3890 t (effectively delaying evaluation of the)4 1491 1 720 4010 t 10 CW f (*)2236 4010 w 10 R f (until the assignment to)3 909 1 2321 4010 t 10 CW f ($pages)3255 4010 w 10 R f (.)3615 4010 w 10 B f ( \320)1 125(26. Examples)1 592 2 720 4250 t 10 I f (holmdel)1462 4250 w 10 R f (The following)1 575 1 720 4406 t 10 I f (rc)1327 4406 w 10 R f (script plays the deceptively simple game)5 1658 1 1442 4406 t 10 I f (holmdel)3132 4406 w 10 R f (, in which the players alternately name)6 1586 1 3454 4406 t (Bell Labs locations, the winner being the first to mention Holmdel.)10 2682 1 720 4526 t (This script is worth describing in detail \(rather, it would be if it weren't so silly.\))15 3222 1 720 4682 t (Variable)720 4838 w 10 CW f ($t)1097 4838 w 10 R f ( Including)1 443(is an abbreviation for the name of a temporary file.)9 2115 2 1251 4838 t 10 CW f ($pid)3844 4838 w 10 R f (, initialized by)2 595 1 4084 4838 t 10 I f (rc)4714 4838 w 10 R f (to its)1 208 1 4832 4838 t ( one)1 178(process-id, in the names of temporary files insures that their names won't collide, in case more than)16 4142 2 720 4958 t (instance of the script is running at a time.)8 1651 1 720 5078 t (Function)720 5234 w 10 CW f (read)1102 5234 w 10 R f ( is the name of a variable into which a line gathered from standard input is read.)16 3223('s argument)1 475 2 1342 5234 t 10 CW f ($ifs)720 5354 w 10 R f ( Thus)1 252(is set to just a newline.)5 921 2 987 5354 t 10 CW f (read)2187 5354 w 10 R f ( at spaces, but the terminating newline is)7 1633('s input is not split apart)5 980 2 2427 5354 t (deleted.)720 5474 w (A handler is set to catch)5 1012 1 720 5630 t 10 CW f (sigint)1767 5630 w 10 R f (,)2127 5630 w 10 CW f (sigquit)2188 5630 w 10 R f (, and)1 205 1 2608 5630 t 10 CW f (sighup,)2849 5630 w 10 R f (and the artificial)2 676 1 3305 5630 t 10 CW f (sigexit)4017 5630 w 10 R f ( just)1 181(signal. It)1 386 2 4473 5630 t (removes the temporary file and exits.)5 1486 1 720 5750 t ( file is initialized from a here document containing a list of Bell Labs locations, and the main)17 3730(The temporary)1 590 2 720 5906 t (loop starts.)1 439 1 720 6026 t ( \(in)1 144(First, the program guesses a location)5 1500 2 720 6182 t 10 CW f ($lab)2397 6182 w 10 R f (\) using the)2 438 1 2637 6182 t 10 CW f (fortune)3108 6182 w 10 R f SHAR_EOF true || echo 'restore of plan9.ps failed' fi echo 'End of part 4' echo 'File plan9.ps is continued in part 5' echo 5 > _shar_seq_.tmp exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.