rc.ms 34 KB

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