X(matches any single character, whereas)4 1525 1 970 4094 t
X9 CW f
X(\304 $1 '?')2 432 1 1258 4264 t
X10 R f
X(only matches a literal question mark.)5 1476 1 970 4444 t
X10 B f
X( I/O Redirection)2 694(19. Advanced)1 603 2 720 4684 t
X10 I f
X(Rc)720 4840 w
X10 R f
X( 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
X(descriptor in square brackets)3 1144 1 720 4960 t
X10 CW f
X([ ])1 180 1 1889 4960 t
X10 R f
X(after the)1 329 1 2094 4960 t
X10 CW f
X(<)2448 4960 w
X10 R f
X(or)2533 4960 w
X10 CW f
X(>)2641 4960 w
X10 R f
X( example,)1 388(. For)1 214 2 2701 4960 t
X9 CW f
X(cc junk.c >[2]junk.diag)2 1242 1 1008 5130 t
X10 R f
X(saves the compiler's diagnostics in)4 1393 1 720 5310 t
X10 CW f
X(junk.diag)2138 5310 w
X10 R f
X(.)2678 5310 w
X( replaced by a copy, in the sense of)8 1471(File descriptors may be)3 959 2 720 5466 t
X10 I f
X(dup)3184 5466 w
X10 R f
X(\(2\), of an already-open file by typing, for)7 1706 1 3334 5466 t
X(example)720 5586 w
X9 CW f
X(cc junk.c >[2=1])2 864 1 1008 5756 t
X10 R f
X( 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
X(redirections, like this)2 841 1 720 6056 t
X9 CW f
X(cc junk.c >junk.out >[2=1])3 1404 1 1008 6226 t
X10 R f
X( descriptor 1 to)3 629(Redirections are evaluated from left to right, so this redirects file)10 2667 2 720 6406 t
X10 CW f
X(junk.out)4050 6406 w
X10 R f
X(, then points)2 510 1 4530 6406 t
X( contrast,)1 366( By)1 167(file descriptor 2 at the same file.)6 1289 3 720 6526 t
X9 CW f
X(cc junk.c >[2=1] >junk.out)3 1404 1 1008 6696 t
X10 R f
X( \(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
X( 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
X10 CW f
X(junk.out)4400 6996 w
X10 R f
X(. In)1 160 1 4880 6996 t
X(the second, diagnostic output will appear on the terminal, and standard output will be sent to the file.)17 4024 1 720 7116 t
X( 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
Xcleartomark
Xshowpage
Xsaveobj restore
X%%EndPage: 7 7
X%%Page: 8 8
X/saveobj save def
Xmark
X8 pagesetup
X10 R f
X(- 8 -)2 166 1 2797 480 t
X(example,)720 840 w
X9 CW f
X(cc junk.c >[2=])2 810 1 1008 1010 t
X10 R f
X(will discard diagnostics from the compilation.)5 1838 1 720 1190 t
X(Arbitrary file descriptors may be sent through a pipe by typing, for example)12 3031 1 720 1346 t
X( 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
X10 CW f
X(grep)720 1816 w
X10 R f
X(still appears on file descriptor 1.)5 1287 1 985 1816 t
X( 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
X(The notation)1 508 1 720 2092 t
X9 CW f
X(cmd1 |[5=19] cmd2)2 918 1 1008 2262 t
X10 R f
X(creates a pipeline with)3 895 1 720 2442 t
X10 CW f
X(cmd1)1640 2442 w
X10 R f
X('s file descriptor 5 connected through a pipe to)8 1863 1 1880 2442 t
X10 CW f
X(cmd2)3768 2442 w
X10 R f
X('s file descriptor 19.)3 804 1 4008 2442 t
X10 B f
X( documents)1 486(20. Here)1 385 2 720 2682 t
X10 I f
X(Rc)720 2838 w
X10 R f
X( 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
X(version of the)2 549 1 720 2958 t
X10 I f
X(tel)1294 2958 w
X10 R f
X(command)1419 2958 w
X9 CW f
X(for\(i\) grep $i <<!)3 972 1 1008 3128 t
X(...)1008 3238 w
X(nls 2T-402 2912)2 810 1 1008 3348 t
X(norman 2C-514 2842)2 972 1 1008 3458 t
X(pjw 2T-502 7214)2 810 1 1008 3568 t
X(...)1008 3678 w
X(!)1008 3788 w
X10 R f
X(A here document is introduced by the redirection symbol)8 2288 1 720 3968 t
X10 CW f
X(<<)3034 3968 w
X10 R f
X( by an arbitrary eof marker \()6 1141(, followed)1 406 2 3154 3968 t
X10 CW f
X(!)4701 3968 w
X10 R f
X(in the)1 227 1 4813 3968 t
X( to a line containing only the eof marker are saved in a tempo-)13 2507( following the command, up)4 1142(example\). Lines)1 671 3 720 4088 t
X(rary file that it connected to the command's standard input when it is run.)13 2935 1 720 4208 t
X10 I f
X(Rc)720 4364 w
X10 R f
X( following)1 414( The)1 205(does variable substitution in here documents.)5 1804 3 850 4364 t
X10 I f
X(subst)3298 4364 w
X10 R f
X(command:)3529 4364 w
X9 CW f
X(ed $3 <<EOF)2 594 1 1008 4534 t
X(g/$1/s//$2/g)1008 4644 w
X(w)1008 4754 w
X(EOF)1008 4864 w
X10 R f
X( of)1 113(changes all occurrences)2 954 2 720 5044 t
X10 CW f
X($1)1817 5044 w
X10 R f
X(to)1967 5044 w
X10 CW f
X($2)2075 5044 w
X10 R f
X(in file)1 241 1 2225 5044 t
X10 CW f
X($3)2496 5044 w
X10 R f
X( include a literal)3 661(. To)1 191 2 2616 5044 t
X10 CW f
X($)3498 5044 w
X10 R f
X(in a here document, type)4 1004 1 3588 5044 t
X10 CW f
X($$)4622 5044 w
X10 R f
X( the)1 152(. If)1 146 2 4742 5044 t
X(name of a variable is followed immediately by)7 1861 1 720 5164 t
X10 CW f
X(\303)2606 5164 w
X10 R f
X(, the caret is deleted.)4 820 1 2666 5164 t
X( by enclosing the eof marker following)6 1643(Variable substitution can be entirely suppressed)5 1981 2 720 5320 t
X10 CW f
X(<<)4384 5320 w
X10 R f
X(in quotation)1 496 1 4544 5320 t
X(marks.)720 5440 w
X(Here documents may be provided on file descriptors other than 0 by typing, for example)14 3530 1 720 5596 t
X9 CW f
X(cmd <<[4]End)1 648 1 1008 5766 t
X(...)1008 5876 w
X(End)1008 5986 w
X10 B f
X(21. Signals)1 482 1 720 6286 t
X10 I f
X(Rc)720 6442 w
X10 R f
X( function with the name of)5 1067( A)1 124( an interrupt is received from the terminal.)7 1705(scripts normally terminate when)3 1293 4 851 6442 t
X( the usual way, but called when)6 1268(a signal, in lower case, is defined in)7 1449 2 720 6562 t
X10 I f
X(rc)3464 6562 w
X10 R f
X( of inter-)2 353( Signals)1 347(receives the signal.)2 766 3 3574 6562 t
X(est are:)1 285 1 720 6682 t
X10 CW f
X(sighup)720 6838 w
X10 R f
X( controlling teletype has disconnected from)5 1728(Hangup. The)1 546 2 970 6958 t
X10 I f
X(rc)3269 6958 w
X10 R f
X(.)3352 6958 w
X10 CW f
X(sigint)720 7114 w
X10 R f
X(The interrupt character \(usually ASCII del\) was typed on the controlling terminal.)11 3272 1 970 7234 t
Xcleartomark
Xshowpage
Xsaveobj restore
X%%EndPage: 8 8
X%%Page: 9 9
X/saveobj save def
Xmark
X9 pagesetup
X10 R f
X(- 9 -)2 166 1 2797 480 t
X10 CW f
X(sigquit)720 840 w
X10 R f
X(The quit character \(usually ASCII fs, ctrl-\\\) was typed on the controlling terminal.)12 3278 1 970 960 t
X10 CW f
X(sigterm)720 1116 w
X10 R f
X(This signal is normally sent by)5 1231 1 970 1236 t
X10 I f
X(kill)2226 1236 w
X10 R f
X(\(1\).)2354 1236 w
X10 CW f
X(sigexit)720 1392 w
X10 R f
X(An artificial signal sent when)4 1176 1 970 1512 t
X10 I f
X(rc)2171 1512 w
X10 R f
X(is about to exit.)3 617 1 2279 1512 t
X(As an example,)2 618 1 720 1668 t
X9 CW f
X(fn sigint{)1 540 1 1008 1838 t
X(rm /tmp/junk)1 648 1 1224 1948 t
X(exit)1224 2058 w
X(})1008 2168 w
X10 R f
X(sets a trap for the keyboard interrupt that removes a temporary file before exiting.)13 3259 1 720 2348 t
X( routine is set to)4 651(Signals will be ignored if the signal)6 1434 2 720 2504 t
X10 CW f
X({})2833 2504 w
X10 R f
X( revert to their default behavior when their)7 1714(. Signals)1 373 2 2953 2504 t
X(handlers' definitions are deleted.)3 1308 1 720 2624 t
X10 B f
X(22. Environment)1 742 1 720 2864 t
X10 R f
X( Plan 9, the environ-)4 817( On)1 173( is a list of name-value pairs made available to executing binaries.)11 2645(The environment)1 685 4 720 3020 t
X( in a file system named)5 929(ment is stored)2 565 2 720 3140 t
X10 CW f
X(#e)2240 3140 w
X10 R f
X(, normally mounted on)3 914 1 2360 3140 t
X10 CW f
X(/env)3300 3140 w
X10 R f
X( value of each variable is stored)6 1269(. The)1 231 2 3540 3140 t
X( is not quite as horrendous as it sounds,)8 1577( \(This)1 262(in a separate file, with components terminated by ASCII nuls.)9 2481 3 720 3260 t
X( contents of)2 482( The)1 213( access is involved.\))3 828(the file system is maintained entirely in core, so no disk or network)12 2797 4 720 3380 t
X10 CW f
X(/env)720 3500 w
X10 R f
X(are shared on a per-process group basis)6 1579 1 987 3500 t
X10 S f
X(-)2593 3500 w
X10 R f
X( process group is created it effectively attaches)7 1885(when a new)2 480 2 2675 3500 t
X10 CW f
X(/env)720 3620 w
X10 R f
X( consequence of this organization is that)6 1603( A)1 122(to a new file system initialized with a copy of the old one.)12 2329 3 986 3620 t
X(commands can change environment entries and see the changes reflected in)10 3014 1 720 3740 t
X10 I f
X(rc)3759 3740 w
X10 R f
X(.)3842 3740 w
X( in the environment, although this could easily)7 1939(There is not currently a way on Plan 9 to place functions)11 2381 2 720 3896 t
X(done by mounting another instance of)5 1537 1 720 4016 t
X10 CW f
X(#e)2287 4016 w
X10 R f
X( can be)2 290( problem is that currently there)5 1259( The)1 210(on another directory.)2 844 4 2437 4016 t
X(only one instance of)3 807 1 720 4136 t
X10 CW f
X(#e)1552 4136 w
X10 R f
X(per process group.)2 734 1 1697 4136 t
X10 B f
X( Variables)1 436(23. Local)1 414 2 720 4376 t
X10 R f
X( assignment followed by a com-)5 1289( An)1 174( the duration of a single command.)6 1402(It is often useful to set a variable for)8 1455 4 720 4532 t
X( example)1 363( For)1 189(mand has this effect.)3 826 3 720 4652 t
X9 CW f
X(a=global)1008 4822 w
X(a=local echo $a)2 810 1 1008 4932 t
X(echo $a)1 378 1 1008 5042 t
X10 R f
X(will print)1 370 1 720 5222 t
X9 CW f
X(local)1008 5392 w
X(global)1008 5502 w
X10 R f
X(This works even for compound commands, like)6 1906 1 720 5682 t
X(echo $0: $i not found >[1=2])5 1512 1 1332 3250 t
X(})1116 3360 w
X(})1008 3470 w
X10 R f
X(Note the use of)3 619 1 720 3650 t
X10 CW f
X(eval)1368 3650 w
X10 R f
X( Without)1 382(to make a list of candidate manual pages.)7 1675 2 1637 3650 t
X10 CW f
X(eval)3723 3650 w
X10 R f
X(, the)1 176 1 3963 3650 t
X10 CW f
X(*)4168 3650 w
X10 R f
X(stored in)1 352 1 4258 3650 t
X10 CW f
X($s)4640 3650 w
X10 R f
X(would)4790 3650 w
X( 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
X(expanded when assigned to)3 1098 1 720 3890 t
X10 CW f
X($s)1844 3890 w
X10 R f
X( causes its arguments to be re-processed by)7 1728(. Eval)1 259 2 1964 3890 t
X10 I f
X(rc)3977 3890 w
X10 R f
X('s parser and interpreter,)3 980 1 4060 3890 t
X(effectively delaying evaluation of the)4 1491 1 720 4010 t
X10 CW f
X(*)2236 4010 w
X10 R f
X(until the assignment to)3 909 1 2321 4010 t
X10 CW f
X($pages)3255 4010 w
X10 R f
X(.)3615 4010 w
X10 B f
X( \320)1 125(26. Examples)1 592 2 720 4250 t
X10 I f
X(holmdel)1462 4250 w
X10 R f
X(The following)1 575 1 720 4406 t
X10 I f
X(rc)1327 4406 w
X10 R f
X(script plays the deceptively simple game)5 1658 1 1442 4406 t
X10 I f
X(holmdel)3132 4406 w
X10 R f
X(, in which the players alternately name)6 1586 1 3454 4406 t
X(Bell Labs locations, the winner being the first to mention Holmdel.)10 2682 1 720 4526 t
X(This script is worth describing in detail \(rather, it would be if it weren't so silly.\))15 3222 1 720 4682 t
X(Variable)720 4838 w
X10 CW f
X($t)1097 4838 w
X10 R f
X( Including)1 443(is an abbreviation for the name of a temporary file.)9 2115 2 1251 4838 t
X10 CW f
X($pid)3844 4838 w
X10 R f
X(, initialized by)2 595 1 4084 4838 t
X10 I f
X(rc)4714 4838 w
X10 R f
X(to its)1 208 1 4832 4838 t
X( 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
X(instance of the script is running at a time.)8 1651 1 720 5078 t
X(Function)720 5234 w
X10 CW f
X(read)1102 5234 w
X10 R f
X( 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
X10 CW f
X($ifs)720 5354 w
X10 R f
X( Thus)1 252(is set to just a newline.)5 921 2 987 5354 t
X10 CW f
X(read)2187 5354 w
X10 R f
X( at spaces, but the terminating newline is)7 1633('s input is not split apart)5 980 2 2427 5354 t
X(deleted.)720 5474 w
X(A handler is set to catch)5 1012 1 720 5630 t
X10 CW f
X(sigint)1767 5630 w
X10 R f
X(,)2127 5630 w
X10 CW f
X(sigquit)2188 5630 w
X10 R f
X(, and)1 205 1 2608 5630 t
X10 CW f
X(sighup,)2849 5630 w
X10 R f
X(and the artificial)2 676 1 3305 5630 t
X10 CW f
X(sigexit)4017 5630 w
X10 R f
X( just)1 181(signal. It)1 386 2 4473 5630 t
X(removes the temporary file and exits.)5 1486 1 720 5750 t
X( 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
X(loop starts.)1 439 1 720 6026 t
X( \(in)1 144(First, the program guesses a location)5 1500 2 720 6182 t
X10 CW f
X($lab)2397 6182 w
X10 R f
X(\) using the)2 438 1 2637 6182 t
X10 CW f
X(fortune)3108 6182 w
X10 R f
X(program to pick a random line from)6 1479 1 3561 6182 t
X( prints the location, and if it guessed Holmdel, prints a message and exits.)13 2942( It)1 111(the location list.)2 642 3 720 6302 t
X( the)1 149(Then it uses)2 485 2 720 6458 t
X10 CW f
X(read)1381 6458 w
X10 R f
X(function to get lines from standard input and validity-check them until it gets a legal)14 3392 1 1648 6458 t
X( that the condition part of a)6 1118(name. Note)1 491 2 720 6578 t
X10 CW f
X(while)2360 6578 w
X10 R f
X( the exit status of the)5 855( Only)1 255( compound command.)2 901(can be a)2 338 4 2691 6578 t
X(last command in the sequence is checked.)6 1666 1 720 6698 t
X( it goes back to the top of the loop.)9 1388( Otherwise)1 460(Again, if the result is Holmdel, it prints a message and exits.)11 2415 3 720 6854 t
Xcleartomark
Xshowpage
Xsaveobj restore
X%%EndPage: 11 11
X%%Page: 12 12
X/saveobj save def
Xmark
X12 pagesetup
X10 R f
X(- 12 -)2 216 1 2772 480 t
X9 CW f
X(t=/tmp/holmdel$pid)1008 890 w
X(fn read{)1 432 1 1008 1000 t
X($1=`{awk '{print;exit}'})1 1296 1 1440 1110 t
X(})1008 1220 w
X(ifs=')1008 1330 w
X( just a newline)3 810(' #)1 486 2 1008 1440 t
X(fn sigexit sigint sigquit sighup{)4 1782 1 1008 1550 t
X(rm -f $t)2 432 1 1440 1660 t
X(exit)1440 1770 w
X(})1008 1880 w
X(cat <<'!' >$t)2 702 1 1008 1990 t
X(Allentown)1008 2100 w
X(Atlanta)1008 2210 w
X(Cedar Crest)1 594 1 1008 2320 t
X(Chester)1008 2430 w
X(Columbus)1008 2540 w
X(Elmhurst)1008 2650 w
X(Fullerton)1008 2760 w
X(Holmdel)1008 2870 w
X(Indian Hill)1 594 1 1008 2980 t
X(Merrimack Valley)1 864 1 1008 3090 t
X(Morristown)1008 3200 w
X(Piscataway)1008 3310 w
X(Reading)1008 3420 w
X(Short Hills)1 594 1 1008 3530 t
X(South Plainfield)1 864 1 1008 3640 t
X(Summit)1008 3750 w
X(Whippany)1008 3860 w
X(West Long Branch)2 864 1 1008 3970 t
X(!)1008 4080 w
X(while\(true\){)1008 4190 w
X(lab=`{/usr/games/fortune $t})1 1512 1 1170 4300 t
X(echo $lab)1 486 1 1170 4410 t
X(if\(\304 $lab Holmdel\){)2 1026 1 1170 4520 t
X(echo You lose.)2 756 1 1332 4630 t
X(exit)1332 4740 w
X(})1170 4850 w
X(while\(read lab; ! grep -i -s $lab $t\) echo No such location.)11 3240 1 1170 4960 t
X(if\(\304 $lab [hH]olmdel\){)2 1188 1 1170 5070 t
X(echo You win.)2 702 1 1332 5180 t
X(exit)1332 5290 w
X(})1170 5400 w
X(})1008 5510 w
X10 B f
X(27. Discussion)1 626 1 720 5690 t
X10 R f
X(Steve Bourne's)1 622 1 720 5846 t
X10 CW f
X(/bin/sh)1376 5846 w
X10 R f
X( I)1 93( comparison.)1 526(is extremely well-designed; any successor is bound to suffer in)9 2591 3 1830 5846 t
X( things wherever possible, usually by)5 1512(have tried to fix its best-acknowledged shortcomings and to simplify)9 2808 2 720 5966 t
X( I)1 67( Obviously)1 475( when irresistibly tempted have I introduced novel ideas.)8 2330( Only)1 258(omitting unessential features.)2 1190 5 720 6086 t
X(have tinkered extensively with Bourne's syntax, that being where his work was most open to criticism.)15 4109 1 720 6206 t
X(The most important principle in)4 1284 1 720 6362 t
X10 I f
X(rc)2032 6362 w
X10 R f
X( is never scanned more)4 930( Input)1 265('s design is that it's not a macro processor.)8 1730 3 2115 6362 t
X( by the lexical and syntactic analysis code \(except, of course, by the)12 2885(than once)1 401 2 720 6482 t
X10 CW f
X(eval)4046 6482 w
X10 R f
X(command, whose)1 714 1 4326 6482 t
X10 I f
X(raison d'etre)1 519 1 720 6602 t
X10 R f
X(is to break the rule\).)4 801 1 1264 6602 t
X( These)1 298( arguments containing spaces.)3 1228(Bourne shell scripts can often be made to run wild by passing them)12 2794 3 720 6758 t
X(will be split into multiple arguments using)6 1780 1 720 6878 t
X10 CW f
X(IFS)2539 6878 w
X10 R f
X( In)1 146( inopportune times.)2 801(, often as)2 391 3 2719 6878 t
X10 I f
X(rc)4095 6878 w
X10 R f
X(, values of variables,)3 862 1 4178 6878 t
X( have)1 227( Arguments)1 508( when substituted into a command.)5 1464(including command line arguments, are not re-read)6 2121 4 720 6998 t
X(presumably been scanned in the parent process, and ought not to be re-read.)12 3026 1 720 7118 t
X( store lists of)3 571( needs to be able to)5 858( He)1 184(Why does Bourne re-scan commands after variable substitution?)7 2707 4 720 7274 t
Xcleartomark
Xshowpage
Xsaveobj restore
X%%EndPage: 12 12
X%%Page: 13 13
X/saveobj save def
Xmark
X13 pagesetup
X10 R f
X(- 13 -)2 216 1 2772 480 t
X( we eliminate re-scanning, we must change the)7 1875( If)1 117( character strings.)2 708(arguments in variables whose values are)5 1620 4 720 840 t
X(type of variables, so that they can explicitly carry lists of strings.)11 2583 1 720 960 t
X( are two dif-)3 505( There)1 287( for lists of words.)4 750( need a notation)3 647( We)1 192(This introduces some conceptual complications.)4 1939 6 720 1116 t
X(ferent kinds of concatenation, for strings \320)6 1798 1 720 1236 t
X10 CW f
X($a\303$b)2552 1236 w
X10 R f
X(, and lists \320)3 533 1 2852 1236 t
X10 CW f
X(\($a $b\))1 429 1 3419 1236 t
X10 R f
X( difference between)2 801(. The)1 238 2 3848 1236 t
X10 CW f
X(\(\))4920 1236 w
X10 R f
X(and)720 1356 w
X10 CW f
X('')895 1356 w
X10 R f
X( not the)2 314(is confusing to novices, although the distinction is arguably sensible \320 a null argument is)14 3680 2 1046 1356 t
X(same as no argument.)3 865 1 720 1476 t
X( the text enclosed in back-)5 1100( is because)2 452( This)1 238(Bourne also rescans input when doing command substitution.)7 2530 4 720 1632 t
X( it ought to be parsed when the enclosing com-)9 1939( Properly,)1 427(quotes is not properly a string, but a command.)8 1954 3 720 1752 t
X(mand is, but this makes it difficult to handle nested command substitutions, like this:)13 3393 1 720 1872 t
X9 CW f
X(size=`wc -l \\`ls -t|sed 1q\\``)4 1566 1 1008 2042 t
X10 R f
X( can get much worse)4 832( This)1 231( escaped to avoid terminating the outer command.)7 2018(The inner back-quotes must be)4 1239 4 720 2222 t
X(than the above example; the number of)6 1612 1 720 2342 t
X10 CW f
X(\\)2366 2342 w
X10 R f
X('s required is exponential in the nesting depth.)7 1911 1 2426 2342 t
X10 I f
X(Rc)4396 2342 w
X10 R f
X(fixes this by)2 505 1 4535 2342 t
X(making the backquote a unary operator whose argument is a command, like this:)12 3220 1 720 2462 t
X9 CW f
X(size=`{wc -l `{ls -t|sed 1q}})4 1566 1 1008 2632 t
X10 R f
X(No escapes are ever required, and the whole thing is parsed in one pass.)13 2862 1 720 2812 t
X(For similar reasons)2 772 1 720 2968 t
X10 I f
X(rc)1520 2968 w
X10 R f
X( associating a string)3 803(defines signal handlers as though they were functions, instead of)9 2606 2 1631 2968 t
X(with each signal, as Bourne does, with the attendant possibility of getting a syntax error message in)16 4320 1 720 3088 t
X( Since)1 285(response to typing the interrupt character.)5 1723 2 720 3208 t
X10 I f
X(rc)2766 3208 w
X10 R f
X(parses input when typed, it reports errors when you)8 2153 1 2887 3208 t
X(make them.)1 466 1 720 3328 t
X( need for the distinction)4 1029( is no)2 255( There)1 301(For all this trouble, we gain substantial semantic simplifications.)8 2735 4 720 3484 t
X(between)720 3604 w
X10 CW f
X($*)1080 3604 w
X10 R f
X(and)1228 3604 w
X10 CW f
X($@)1400 3604 w
X10 R f
X( rules that)2 398( is no need for four types of quotation, nor the extremely complicated)12 2812(. There)1 310 3 1520 3604 t
X( In)1 133(govern them.)1 527 2 720 3724 t
X10 I f
X(rc)1405 3724 w
X10 R f
X( to appear in an argu-)5 855(you use quotation marks exactly when you want a syntax character)10 2672 2 1513 3724 t
X(ment.)720 3844 w
X10 CW f
X(IFS)999 3844 w
X10 R f
X(is no longer used, except in the one case where it was indispensable: converting command out-)15 3833 1 1207 3844 t
X(put into argument lists during command substitution.)6 2121 1 720 3964 t
X( security hole [Ree88].)3 933(This also avoids an important)4 1211 2 720 4120 t
X10 I f
X(System)2922 4120 w
X10 R f
X(\(3\) and)1 293 1 3199 4120 t
X10 I f
X(popen)3525 4120 w
X10 R f
X(\(3\) call)1 293 1 3769 4120 t
X10 CW f
X(/bin/sh)4095 4120 w
X10 R f
X(to execute a)2 492 1 4548 4120 t
X( to use either of these routines with any assurance that the specified command)13 3212( is impossible)2 569(command. It)1 539 3 720 4240 t
X(will be executed, even if the caller of)7 1479 1 720 4360 t
X10 I f
X(system)2224 4360 w
X10 R f
X(or)2515 4360 w
X10 I f
X(popen)2623 4360 w
X10 R f
X( can)1 164( This)1 229( for the command.)3 735(specifies a full path name)4 1020 4 2892 4360 t
X( problem is that)3 643( The)1 211( a set-userid program.)3 888(be devastating if it occurs in)5 1164 4 720 4480 t
X10 CW f
X(IFS)3657 4480 w
X10 R f
X(is used to split the command)5 1172 1 3868 4480 t
X(into words, so an attacker can just set)7 1534 1 720 4600 t
X10 CW f
X(IFS=/)2285 4600 w
X10 R f
X( Trojan horse named)3 844(in his environment and leave a)5 1253 2 2616 4600 t
X10 CW f
X(usr)4745 4600 w
X10 R f
X(or)4957 4600 w
X10 CW f
X(bin)720 4720 w
X10 R f
X(in the current working directory before running the privileged program.)9 2891 1 929 4720 t
X10 I f
X(Rc)3874 4720 w
X10 R f
X(fixes this by not ever res-)5 1032 1 4008 4720 t
X(canning input for any reason.)4 1167 1 720 4840 t
X(Most of the other differences between)5 1565 1 720 4996 t
X10 I f
X(rc)2320 4996 w
X10 R f
X( eliminated Bourne's)2 860( I)1 94(and the Bourne shell are not so serious.)7 1647 3 2439 4996 t
X(peculiar forms of variable substitution, like)5 1726 1 720 5116 t
X9 CW f
X(echo ${a=b} ${c-d} ${e?error})3 1566 1 1008 5286 t
X10 R f
X( deleted the builtins)3 822( I)1 95(because they are little used, redundant and easily expressed in less abstruse terms.)12 3403 3 720 5466 t
X10 CW f
X(export)720 5586 w
X10 R f
X(,)1080 5586 w
X10 CW f
X(readonly)1131 5586 w
X10 R f
X(,)1611 5586 w
X10 CW f
X(break)1662 5586 w
X10 R f
X(,)1962 5586 w
X10 CW f
X(continue)2013 5586 w
X10 R f
X(,)2493 5586 w
X10 CW f
X(read)2544 5586 w
X10 R f
X(,)2784 5586 w
X10 CW f
X(return)2835 5586 w
X10 R f
X(,)3195 5586 w
X10 CW f
X(set)3246 5586 w
X10 R f
X(,)3426 5586 w
X10 CW f
X(times)3477 5586 w
X10 R f
X(and)3803 5586 w
X10 CW f
X(unset)3973 5586 w
X10 R f
X(because they seem)2 742 1 4298 5586 t
X(redundant or only marginally useful.)4 1462 1 720 5706 t
X(Where Bourne's syntax draws from Algol 68,)6 1917 1 720 5862 t
X10 I f
X(rc)2677 5862 w
X10 R f
X( I)1 99( is harder to defend.)4 859( This)1 244( C or Awk.)3 492('s is based on)3 586 5 2760 5862 t
X(believe that, for example)3 992 1 720 5982 t
X9 CW f
X(if\(test -f junk\) rm junk)4 1296 1 1008 6152 t
X10 R f
X(is better syntax than)3 802 1 720 6332 t
X9 CW f
X(if test -f junk; then rm junk; fi)7 1782 1 1008 6502 t
X10 R f
X( is less cluttered with keywords, it avoids the semicolons that Bourne requires in odd places, and)16 3921(because it)1 399 2 720 6682 t
X(the syntax characters better set off the active parts of the command.)11 2693 1 720 6802 t
X(The one bit of large-scale syntax that Bourne unquestionably does better than)11 3169 1 720 6958 t
X10 I f
X(rc)3922 6958 w
X10 R f
X(is the)1 222 1 4038 6958 t
X10 CW f
X(if)4293 6958 w
X10 R f
X(statement with)1 594 1 4446 6958 t
X10 CW f
X(else)720 7078 w
X10 R f
X(clause.)986 7078 w
X10 I f
X(Rc)1310 7078 w
X10 R f
X('s)1415 7078 w
X10 CW f
X(if)1512 7078 w
X10 R f
X(has no terminating)2 744 1 1657 7078 t
X10 CW f
X(fi)2426 7078 w
X10 R f
X( a result, the parser cannot tell whether or not)9 1807( As)1 161(-like bracket.)1 526 3 2546 7078 t
X(to expect an)2 482 1 720 7198 t
X10 CW f
X(else)1227 7198 w
X10 R f
X( problem is that after reading, for example)7 1685( The)1 205(clause without looking ahead in its input.)6 1647 3 1492 7198 t
X(resolves the ``dangling else'' ambiguity in opposition to most people's expectations.)10 3378 1 1172 2446 t
X( the UNIX system programmer's manual the Bourne)7 2120(It is remarkable that in the four most recent editions of)10 2200 2 720 2602 t
X( not admit the command)4 976(shell grammar described in the manual page does)7 1985 2 720 2722 t
X10 CW f
X(who|wc)3707 2722 w
X10 R f
X( is surely an over-)4 719(. This)1 254 2 4067 2722 t
X( Even)1 266( something darker: nobody really knows what the Bourne shell's grammar is.)11 3206(sight, but it suggests)3 848 3 720 2842 t
X( the rou-)2 346( parser is implemented by recursive descent, but)7 1959( The)1 210(examination of the source code is little help.)7 1805 4 720 2962 t
X( categories all have a flag argument that subtly changes their operation)11 2885(tines corresponding to the syntactic)4 1435 2 720 3082 t
X(depending on the context.)3 1041 1 720 3202 t
X10 I f
X(Rc)1814 3202 w
X10 R f
X('s parser is implemented using)4 1233 1 1919 3202 t
X10 I f
X(yacc)3180 3202 w
X10 R f
X(, so I can say precisely what the grammar)8 1678 1 3362 3202 t
X(is.)720 3322 w
X( is a)2 165( There)1 284( it considerably except for two things.)6 1524( would simplify)2 636( I)1 84(Its lexical structure is harder to describe.)6 1627 6 720 3478 t
X( distinguish between parentheses that immediately follow a word with no intervening)11 3614(lexical kludge to)2 706 2 720 3598 t
X( use for)2 319(spaces and those that don't that I would eliminate if there were a reasonable pair of characters to)17 4001 2 720 3718 t
X( could also eliminate the insertion of free carets if users were not adamant about it.)15 3299( I)1 83(subscript brackets.)1 743 3 720 3838 t
X10 B f
X(28. Acknowledgements)1 1002 1 720 4078 t
X10 R f
X( Plan 9 users have been insistent, incessant sources of good ideas and)12 2825(Rob Pike, Howard Trickey and other)5 1495 2 720 4234 t
X( examples in this document are plagiarized from [Bou78], as are most of)12 2892(criticism. Some)1 653 2 720 4354 t
X10 I f
X(rc)4290 4354 w
X10 R f
X('s good features.)2 662 1 4373 4354 t
X10 B f
X(29. References)1 639 1 720 4594 t
X10 R f
X( R. Bourne, ``U)3 678(Bou78. S.)1 423 2 720 4822 t
X8 R f
X(NIX)1821 4822 w
X10 R f
X(Time-Sharing System: The U)3 1234 1 2006 4822 t
X8 R f
X(NIX)3240 4822 w
X10 R f
X(Shell,'')3425 4822 w
X10 I f
X(Bell System Technical Journal)3 1275 1 3765 4822 t
X10 B f
X(57)970 4942 w
X10 R f
X(\(6\), pp. 1971-1990 \(July-August 1978\).)4 1579 1 1070 4942 t
X( Reeds, ``)2 409(Ree88. J.)1 394 2 720 5098 t
X10 CW f
X(/bin/sh)1523 5098 w
X10 R f
X( Bell)1 205( AT&T)1 334(: the biggest UNIX security loophole,'' 11217-840302-04TM,)6 2558 3 1943 5098 t
X(Laboratories \(1988\).)1 820 1 970 5218 t
Xcleartomark
Xshowpage
Xsaveobj restore
X%%EndPage: 14 14
X%%Trailer
Xdone
X%%Pages: 14
X%%DocumentFonts: Courier Times-Bold Times-Italic Times-Roman Symbol
END_OF_FILE
if test 40176 -ne `wc -c <'plan9.ps.b'`; then
echo shar: \"'plan9.ps.b'\" unpacked with wrong size!