rc.ms 34 KB

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