· 8 years ago · Mar 14, 2018, 11:28 PM
1Archive-name: unix-faq/shell/rc
2Comp-unix-shell-archive-name: rc-FAQ
3Version: 2.19
4Last-modified: 04 Nov 1994
5This document attempts to answer some Frequently Asked Questions about
6rc, a clean, portable, and freely-available shell for UNIX systems (see
71.1 for a very brief overview of rc). It in no way replaces either the
8formal documentation for rc (see 1.2) or the mailing list archives (see
92.2).
10
11This document draws heavily on the collective wisdom of the rc mailing
12list; the quality of the correspondence is such that often all that was
13required was a summary of one or two messages. The rc mailing list
14archive is recommend reading for newcomers to rc (see 2.2).
15Contributors are acknowledged at the end of this document.
16
17Corrections, comments, and suggestions concerning this document are
18welcome (see 3.2).
19
20NOTE: Neither the editor nor any of the contributors to this document
21are responsible for any consequences resulting from the advice in this
22document.
23
24Table of Contents
25
261. Implementations of rc
271.1 What is rc?
281.2 Where is rc documented?
291.3 How do I obtain rc?
301.4 Are there any patches to rc?
311.5 Can I compile rc on a ... machine with ... operating system and
32 ... compiler?
331.6 Should rc be dynamically or statically linked?
341.7 To whom do I report bugs?
351.8 Does anyone have an implementation of /dev/fd for my UNIX?
36
372. The rc mailing list
382.1 How do I subscribe to the rc mailing list?
392.2 How do I obtain the rc mailing list archive?
40
413. The rc FAQ list
423.1 How do I obtain the current version of the rc FAQ list?
433.2 To whom do I make suggestions about the rc FAQ list?
44
454. Does rc have ... ?
464.1 Does rc have job control?
474.2 Does rc have command-line editing?
484.3 Does rc have a history mechanism?
494.4 Does rc have file name completion?
504.5 Does rc have home directory expansion?
514.6 Does rc check for new mail?
524.7 Does rc have hierarchical lists?
534.8 Does rc have cartesian products?
544.9 Does rc cache the location of executables in the path?
554.10 Does rc have C-style \ escapes?
564.11 Does rc have ... built in?
574.12 Does rc have echo built in?
584.13 Does rc have test built in?
594.14 Does rc have true, false, and `:' built in?
60
615. Using rc as a login shell
625.1 How do I make rc my login shell?
635.2 How do I use rc in a heterogeneous cluster?
645.3 What problems occur with rc on Apollos?
655.4 What problems occur with rc on SYSV-derived systems?
665.5 What problems occur with rc on NeXTs?
675.6 How do I keep down the size of my .rcrc file?
685.7 How do I speed up the execution of my .rcrc file?
69
706. Interactions between rc and the rest of UNIX
716.1 How do I get each new interactive rc to do ...?
726.2 How do I get rc to do ... in each new xterm?
736.3 How do I get rc to read .rcrc when I use rsh?
746.4 How do I get at or batch to run an rc script?
75
767. Programming in rc
777.1 What makes rc such a good scripting language?
787.2 What are the trade-offs between functions and scripts?
797.3 What can I do if I have deficient sed, awk, test, ... ?
807.4 Where do I obtain the GNU tools and other software?
817.5 How do I perform arithmetic in rc?
827.6 How do I find the first occurrence of an element in a list?
837.7 How do I use ranges in array subscripts in rc?
847.8 How do I perform the equivalent of read in rc?
85
861. Implementations of rc
87
881.1 What is rc?
89
90 rc is a shell designed by Tom Duff of Bell Labs to replace the
91 venerable Bourne sh in Plan 9. (Plan 9 is an experimental
92 operating and networking system developed at Bell Labs.) In
93 addition to Plan 9, Duff's rc runs on SunOS and v10 UNIX. The
94 design of rc is extremely clean, in that precisely those
95 features of Bourne's sh that have caused problems over the years
96 (the slightly awkward flow control syntax, the Byzantine quoting
97 rules, the failure to export all variables into the environment)
98 were reworked, and the temptation to add superfluous features
99 was strongly resisted.
100
101 Byron Rakitzis has written a version of rc that is portable
102 between many version on UNIX and is largely compatible with
103 Duff's design. Rakitzis' implementation has been successfully
104 used on UNIX platforms ranging from PCs running Linux to Cray
105 Y-MPs running Unicos.
106
107 Most of this document deals with issues that have arisen from
108 use of Rakitzis' rc, and most of the example code will follow
109 his minor modifications to rc. Henceforth, a plain `rc' refers
110 to Rakitzis' rather than Duff's rc.
111
1121.2 Where is rc documented?
113
114 rc is documented in its man page, distributed with the source
115 (see 1.3).
116
117 The Plan 9 manual pages, including those on Duff's rc, are
118 available as research.att.com:/dist/plan9man/manual.ps.Z by
119 anonymous FTP. The full manual is almost 600 pages long, but
120 the manual pages for Duff's rc are physical pages 142 to 147
121 (logical pages 116 to 121).
122
123 An early version of Duff's rc is described in the paper `rc -- a
124 Shell for Plan 9 and UNIX Systems', written for a UKUUG meeting.
125 Duff has kindly allowed the paper to be distributed by anonymous
126 FTP as viz.tamu.edu:/pub/rc/plan9.ps. It provides an excellent
127 introduction and tutorial for Duff's rc, and describes the
128 motivations for the differences between Duff's rc and Bourne's
129 sh.
130
131 When reading Duff's paper and the Plan 9 manual pages, bear in
132 mind that Rakitzis' implementation of rc differs in detail from
133 Duff's (these differences are documented in the rc man page).
134
135 Another valuable source of information on rc is the rc mailing
136 list archive (see 2.2).
137
1381.3 How do I obtain rc?
139
140 The sources are available by anonymous FTP in the directory
141 viz.tamu.edu:/pub/rc. Be sure to get the most recent version.
142 At the time this document was last updated, the most recent
143 version of rc was v1.4 announced on 21 May 1992, available as
144 viz.tamu.edu:/pub/rc/rc-1.4.tar.Z. (A beta release of v1.5 is
145 on the horizon.)
146
147 rc is distributed on very liberal terms, although it has not
148 been placed in the public domain (see the file COPYRIGHT
149 distributed with the sources).
150
151 Duff's rc can be obtained by acquiring either a Plan 9 or a v10
152 UNIX system from Bell Labs. Plan 9 can be licensed by academic
153 institutions, which should contact:
154
155 Neera Kuckreja
156 RM 2C557
157 ATT Bell Laboratories
158 Murray Hill
159 NJ 07974
160 USA
161 +1 908 582-3855
162 ne...@research.att.com
163
1641.4 Are there any patches to rc?
165
166 Although the current version of rc is remarkably mature, a small
167 number of bugs have been found since its release and patches
168 have been posted to the rc mailing list (see 2.2). Other
169 patches posted to the mailing list include work-arounds for
170 broken compilers or libraries and assorted features.
171
172 An up-to-date set of patches extracted from the mailing list
173 archive, together with a script to apply those patches, is
174 available as oldp.astro.wisc.edu:/pub/rc/patches.tar.Z by
175 anonymous FTP.
176
1771.5 Can I compile rc on a ... machine with ... operating system and
178 ... compiler?
179
180 rc is written in portable ANSI C, but it can be compiled by many
181 older C compilers after passing the sources through unproto (get
182 ftp.win.tue.nl:/pub/unix/unproto4.shar.Z by anonymous FTP).
183
184 If you use gcc, use v1.39 or later.
185
186 rc has been successfully compiled on systems with the following
187 combinations of architectures, operating systems, and compilers,
188 although this list is probably not exhaustive:
189
190 DEC VAX Ultrix v3.x gcc v1
191 DEC MIPS Ultrix v4.[23] gcc v2
192 DEC MIPS Ultrix v4.[23] cc [a]
193 DEC AXP OSF/1 v1.2 cc [a][b]
194 DEC AXP OSF/1 v1.2 cc -std1 [b]
195
196 Sun SPARC Solaris v2 gcc v2 [b][c]
197 Sun SPARC acc [b][c]
198 Sun SPARC SunOS v4.1.[123] cc [a][b][c]
199 Sun SPARC SunOS v4.1.[123] gcc v2 [b][c]
200 Sun SPARC BSD [b][c]
201 Sun 68K SunOS v4.1.1 gcc v2 [b][c]
202 Sun 68K SunOS v3.5 gcc v1 [b][c]
203
204 SGI Iris Irix v[45].x gcc v2
205
206 IBM RS/6000 AIX v3.1.5 cc
207 IBM RS/6000 AIX v3.2.[013] cc
208
209 HP PA-RISC HP-UX v8.0 gcc v2 [d][e]
210 HP PA-RISC HP-UX v9.0 gcc v2 [d]
211 HP PA-RISC OSF/1 v1.0.2 cc
212
213 i386/i486 SCO-ODT SVR3 gcc v2 [d][e]
214 i386/i486 SCO-ODT SVR3 cc [d][e]
215 i386 Minix v1.5 [d]
216 i386/i486 NetBSD gcc v[12]
217 i386/i486 Linux gcc v2 [d]
218 i386/i486 386BSD r0.0 gcc [j]
219 i386/i486 SCO Xenix SVR2.3x [f]
220
221 NeXT NeXT OS v2.x gcc v[12] [g]
222 NeXT NeXT OS v3.0 gcc v2 [g]
223
224 Apollo 68K DomainOS v10.4 (BSD) cc [h]
225 Apollo 10000 DomainOS v10.4 (BSD) cc [h]
226
227 Sony MIPS NEWS/OS cc [a]
228 Sony 68K NEWS/OS v4.0.1 cc [a]
229
230 Convex C1 ConvexOS v10.1 cc
231
232 Pyramid 9810 OSx 5.1a (BSD) cc -Xa [i]
233
234 Cray Y-MP Unicos 6.1.7 scc [e][j]
235
236 Sequent Dynix v3.2.0 (BSD) gcc v2
237
238 Apple 68K A/UX v3.0 cc
239
240 Encore MIPS Umax v4.3 gcc v2
241
242 Acorn ARM iX v1.21a cc
243
244 Motorola 88K System V R32V3 gcc v2
245 Motorola 88K System V R32V3 cc [a][k]
246
247 Notes:
248
249 [a] Sources pre-processed with unproto.
250 [b] See 1.6.
251 [c] Sun's yacc has a memory leak -- use another
252 implementation such as GNU bison (see 7.4).
253 [d] Requires intervention by hand to get mksignal to work,
254 because of of the non-standard signal.h file.
255 [e] See 4.13.
256 [f] See 5.4.
257 [g] See 5.5.
258 [h] See 5.3
259 [i] This compiler has no stdarg.h, but vararg.h sufficed.
260 [j] Minor modifications required to prototypes.
261 [k] Greenhills cc, used without any optimization.
262
2631.6 Should rc be dynamically or statically linked?
264
265 As far as one can generalize, statically linked executables fork
266 faster than dynamically linked executables. This suggests that
267 shells, which fork a great deal, should probably be statically
268 linked (i.e., you should not link them with shared libraries).
269 rc makes so little use of libc functions that static linking
270 results in only a small increase in the size of the executable
271 on disc.
272
273 Versions of UNIX which support shared libraries include SVR4,
274 SunOS, Solaris, OSF/1, and Irix.
275
2761.7 To whom do I report bugs?
277
278 Byron Rakitzis (by...@netapp.com) or the rc mailing list
279 (r...@hawkwind.utcs.toronto.edu). Please check the documentation
280 before reporting bugs, and check the mailing list archive in
281 case the bug is already known.
282
2831.8 Does anyone have an implementation of /dev/fd for my UNIX?
284
285 /dev/fd pseudo-devices allow a more reliable implementation of
286 non-linear pipelines (i.e., <{...} and >{...}) than named
287 pipes, but they are not present in all versions of UNIX.
288
289 An implementation of Ultrix v4.2 and later was posted to the
290 mailing list in March 1993 (see 2.2).
291
292 An implementation for SunOS v4.1.1 is also available (although
293 it may well work with v4.1.2 and v4.1.3) by anonymous FTP as
294 ftp.cs.arizona.edu:/devfd.shar.
295
296 An implementation for SunOS v4.1.2 is available by anonymous FTP
297 as emx.cc.utexas.edu:/pub/mnt/source/sun/devfd.shar. (This is
298 packaged as a loadable module, so you do not have to rebuild
299 your kernel.)
300
301 An implementation for NeXT OS 2.1 is available by anonymous FTP
302 as ftp.sys.toronto.edu:/pub/rc/devfd-next.shar.gz.
303
304 You will, of course, need to rebuild your kernel to install
305 these pseudo-devices.
306
3072. The rc mailing list
308
3092.1 How do I subscribe to the rc mailing list?
310
311 Send mail to
312
313 rc-re...@hawkwind.utcs.toronto.edu.
314
315 Chris Siebenmann maintains the mailing list, and can be reached
316 at the above address in the event of problems with the mailing
317 list or to unsubscribe.
318
319 The rc mailing list represents hundreds of user-years of
320 experience with rc. Clearly, it is a courtesy to the list and
321 to your own advantage to check the mailing list archive before
322 posting to the list, to benefit from the experience and mistakes
323 of those before you, and to prevent topics being continually
324 rehashed.
325
3262.2 How do I obtain the rc mailing list archive?
327
328 The archive can be obtained by anonymous FTP. At the moment, it
329 is split chronologically between the original and current
330 maintainers of the mailing list.
331
332 Period File
333 Jun 91 to Dec 91 viz.tamu.edu:/pub/rc/rc-list.1991.Z
334 Jan 92 to May 92 viz.tamu.edu:/pub/rc/rc-list
335 May 92 to present ftp.sys.toronto.edu:/pub/rc/rc-list
336
3373. The rc FAQ list
338
3393.1 How do I obtain the current version of the rc FAQ list?
340
341 The current version of the rc FAQ list is archived automatically
342 and is available by anonymous FTP as
343 rtfm.mit.edu:/pub/usenet/comp.unix.shell/rc-FAQ.
344
3453.2 To whom do I make suggestions about the rc FAQ list?
346
347 To its editor, Alan Watson (al...@lowell.edu), or the rc
348 mailing list if you think your suggestion warrants a wider
349 audience.
350
3514. Does rc have ... ?
352
3534.1 Does rc have job control?
354
355 No. This has been discussed at length in the rc mailing list.
356
357 Now that personal workstations with window systems are common
358 place, the case for job control is less compelling. However, if
359 you have to use rc on a traditional terminal, you may wish to
360 obtain the screens program from a GNU archive (see 7.4), the sm
361 program that was posted to alt.sources in mid-1992 (see 7.4), or
362 investigate shell escape mechanisms in vi and shell mode in
363 emacs.
364
3654.2 Does rc have command-line editing?
366
367 If you wish. Hooks are provided for the readline or editline
368 libraries which provide command-line editing. The default is no
369 command-line editing.
370
371 The readline library can be obtained from a GNU archive (see
372 7.4).
373
374 The editline library is similar to the readline library, but is
375 a fraction of the size and offers fewer features. The sources
376 are available as ftp.sys.toronto.edu:/pub/rc/editline.shar by
377 anonymous FTP).
378
379 Alternatively, you can use fep, ile, atty, or Rk to implement
380 editing on a per-terminal basis. These have been discussed in
381 on the mailing list at one time or another, and modifications to
382 ile have been posted there.
383
3844.3 Does rc have a history mechanism?
385
386 Yes. While, rc does not have a built-in csh-like history
387 mechanism, rather it is able to write interactive commands to a
388 file (see the history special variable in the man page),
389 allowing a history mechanism similar to the v8 `=' command to be
390 implemented as an external program (one such implementation is
391 supplied with the source of rc).
392
393 In Plan 9, `:' was the history program (the name was probably
394 changed from the `=' used in v8 because `=' is a special
395 character in rc, and needs quoting if it refers to a command).
396 However, this form of history was apparently used so little that
397 the ability to write commands to a file was removed from Duff's
398 rc. The history program distributed with the rc source is
399 invoked with `-'.
400
401 Both editline and readline have command recall.
402
4034.4 Does rc have file name completion?
404
405 If you wish. Plain rc does not have file name completion (as it
406 obtains its command input with read), but the readline library
407 does.
408
4094.5 Does rc have home directory expansion?
410
411 No. This has been hotly debated on the rc mailing list, and a
412 patch to implement this was posted to the rc mailing list in
413 November 1992 (see 2.2 and 1.4).
414
4154.6 Does rc check for new mail?
416
417 No. However, you can make it do so with the following prompt
418 function:
419
420 fn prompt { mail -e && echo You have mail. }
421
422 Alternatively, consider using biff or xbiff.
423
4244.7 Does rc have hierarchical lists?
425
426 No. Each element of an rc list must be a string, and cannot be
427 another list. Whenever a list appears inside another list, it
428 is expanded so that the outer list contains its elements.
429 Similarly, whenever two lists are adjacent, they are
430 concatenated to form a single list (with one exception).
431
432 In rc terms, the arguments to a command form a list, even though
433 they may not have explicit `(' and `)' delimiters around them.
434 Hierarchical lists do not correspond well to the `char **argv'
435 model for arguments to UNIX commands, although simple lists do.
436
437 The single exception to these rules are the arguments to the `~'
438 built-in command, which rc interprets as two lists -- a subject
439 list and a pattern list. Normal expansion and concatenation is
440 performed on the two lists separately. A consequence of this is
441 that the following command:
442
443 if ( ~ $1 () '' ) ...
444
445 does not check if $1 is either the null list or the null string,
446 as normal list concatenation occurs on the pattern list leading
447 to a pattern list with one element -- the null string.
448
4494.8 Does rc have cartesian products?
450
451 No. If you really need them, they can be obtained in the
452 following manner:
453
454 ; x = (a b c)
455 ; y = (1 2 3)
456 ; product = ()
457 ; for ( elem in $x ) product = ( $product $elem^$y )
458 ; echo $product
459 a1 a2 a3 b1 b2 b3 c1 c2 c3
460
461 rc's concatenation operator works in a distributive manner if
462 one of the lists has only a single element and in a pairwise
463 manner if both lists have the same number of elements:
464
465 ; echo a^( x y z )
466 ax ay az
467 ; echo ( a b c )^( x y z )
468 ax by cz
469
4704.9 Does rc cache the location of executables in the path?
471
472 No. This has been discussed on the mailing list. As far as one
473 can generalize, searching the path is not a performance
474 bottleneck on most modern UNIX systems.
475
4764.10 Does rc have C-style \ escapes?
477
478 No. One of the most attractive features of rc is its single
479 quoting rule.
480
481 If you need to embed control characters in your strings,
482 investigate tr and printf (see 7.3 if your system lacks the
483 latter).
484
4854.11 Does rc have ... built in?
486
487 It is not by accident that rc has fewer built-in commands than
488 most shells other than the original Bourne shell. The
489 underlying philosophy, eloquently summarized by Boyd Roberts, is
490 that a shell is there to run other programs, not to have other
491 programs built into it. By having a well-defined role, rc has
492 remained small and simple, properties that lead to better
493 performance, fewer bugs, and a more thorough understanding of
494 the shell by its users.
495
496 Most of the rc built-in commands perform functions that are
497 essential for a shell and cannot be performed by external
498 programs (e.g., cd, eval, limit, umask, wait).
499
500 rc does include hooks for users to add new built-in commands,
501 and these have been used to add test, access, kill, read, and
502 even sync and haltsys commands (see the mailing list and the
503 examples file for more details). Such additions are unsupported
504 and potentially unportable.
505
5064.12 Does rc have echo built in?
507
508 If you wish. While most of rc's built-in commands could not
509 easily be replaced by external commands, echo is the one
510 exception. The justification is that echo is used so much that
511 providing it as a built-in command results in a significant gain
512 in performance, although this opinion is by no means universally
513 held. By default, echo is built in.
514
515 It has also been noted that rc's echo is more portable that
516 /bin/echo, as the v7 and SYSV implementations of echo differ in
517 the method that must be used to suppress the final newline.
518 (However, rc's echo differs from both, as it uses `--' to
519 indicate that all other arguments are to be echoed literally.)
520
521 People who dislike the notion of a built-in echo command have
522 the option of excluding it from the compilation. Alternatively,
523 the built-in echo can be subverted with the following function,
524 although this will not defeat an explicit call to `builtin
525 echo'.
526
527 fn echo { /bin/echo $* }
528
529 See also 7.3.
530
5314.13 Does rc have test built in?
532
533 No. You can use the built-in `~' command to match strings, and
534 fall back on /bin/expr or /bin/test for numeric comparisons and
535 /bin/test for querying the file system.
536
537 If you are using rc on a system that lacks a stand-alone
538 /bin/test and /bin/[ and has test built into sh, the following
539 serves as an interim replacement:
540
541 #! /bin/sh
542 `basename $0` ${1+"$@"}
543 # end-of-file
544
545 This applies to Unicos and HP-UX v8. Note that trip.rc, the
546 script provided with the rc sources to check basic functionality
547 after compilation, will fail unless a suitable test command
548 exists in the path.
549
550 SCO UNIX implements /bin/test in precisely this way. You can
551 almost certainly get better performance by using the GNU
552 implementation of /bin/test (see 7.4), although this is
553 obviously more important on an i386 machine than on a Cray.
554
555 It is possible to get at the file system obliquely through the
556 globbing mechanism and the builtin cd command, and in some
557 circumstances these can be of use (see, for example, 5.7). Such
558 speed hacks need to be carefully justified.
559
560 See also 7.3.
561
5624.14 Does rc have true, false, and `:' built in?
563
564 No. The following functions are just as fast:
565
566 fn true { return 0 }
567 fn false { return 1 }
568 fn : { return 0 }
569
570 Note that an indefinite loop in rc does not require the use of
571 an explicit `true' command:
572
573 while () {
574 ...
575 }
576
5775. Using rc as a login shell
578
5795.1 How do I make rc my login shell?
580
581 On most systems, you or the system administrator will have to
582 add a line to /etc/shells containing the full path to rc. This
583 will need to be done on each machine on which you wish to use
584 rc.
585
586 Next, use the chsh command to specify your new preference. If
587 your machine is running Yellow Pages (YP), you will have to do
588 this on the YP server, otherwise you will have to do this on
589 each machine individually. (To determine if your machine is
590 using YP, type `ypwhich -m passwd' that will either print the
591 name of your YP server or give an error if your machine is not
592 running YP.) Often, you will also need to change your password
593 (using the yppasswd command) on the YP server to propagate the
594 new /etc/passwd entry contain your selected shell; changing your
595 password to itself will normally suffice.
596
597 An alternative method is to invoke rc from your .profile file or
598 its equivalent, but this has so many drawbacks that I cannot
599 recommend it.
600
6015.2 How do I use rc in a heterogeneous cluster?
602
603 There are two issues: finding the correct executable when you
604 login, and getting the correct path in scripts run using the #!
605 kernel hack.
606
607 If you have root privileges on every machine on the cluster, by
608 far the simplest solution is to place a copy of rc in /bin and
609 add /bin/rc to /etc/shells on each machine. Use `#! /bin/rc' in
610 shell scripts.
611
612 Otherwise, use a sh wrapper around rc. Create a shell script
613 called, say, rc-login, and make this your login shell. The
614 purpose of this script is to set SHELL and PATH to point
615 appropriately according to the machine, and then to exec rc.
616
617 The following script is suitable for adaptation:
618
619 #! /bin/sh
620
621 # determine OS
622 TMP=/tmp/$$
623 ( exec >$TMP ; echo OS=`uname -m` )
624 . $TMP
625 rm -f $TMP
626
627 # determine location of rc executable
628 case $OS in
629 RISC)
630 PATH=$HOME/bin/mips:$PATH
631 SHELL=$HOME/bin/mips/rc
632 ;;
633 sun4c)
634 PATH=$HOME/bin/sparc:$PATH
635 SHELL=$HOME/bin/sparc/rc
636 ;;
637 alpha)
638 PATH=$HOME/bin/alpha:$PATH
639 SHELL=$HOME/bin/alpha/rc
640 ;;
641 *)
642 echo 1>&2 "WARNING: unknown architecture"
643 SHELL=/bin/sh
644 ;;
645 esac
646
647 # determine if this is a login shell
648 case $SHELL in
649 */rc)
650 case $0 in
651 -*)
652 FLAG=-l
653 ;;
654 esac
655 ;;
656 esac
657
658 export PATH
659 export SHELL
660
661 exec $SHELL $FLAG ${1+"$@"}
662
663 # end-of-file
664
665 The dance to capture the output of uname is necessary because of
666 a bug whereby redirection does not work in the original v7 sh if
667 stdout is closed. (This bug lives on in the Ultrix /bin/sh.)
668
669 The easiest way to manage shell scripts is to keep a master copy
670 in a central directory, say $home/bin/share, and have slave
671 scripts in machine-specific directories which source the master
672 script. For example, for a command called `foo' create the
673 following in each machine-specific directory:
674
675 #! /full/path/to/machine/specific/rc
676 . $home/bin/share/foo $*
677 # end-of-file
678
679 See 5.3 if your cluster contains Apollos.
680
6815.3 What problems occur with rc on Apollos?
682
683 Apollos require the login shell to be a binary, so you cannot
684 use a sh script wrapper around rc.
685
6865.4 What problems occur with rc on SYSV-derived systems?
687
688 Many SYSV-derived sh and ksh are `restricted' if the final
689 component of SHELL contains the letter `r'. A restricted shell
690 will not allow you to cd, perform output redirection, set PATH,
691 or specify absolute paths to executables, meaning that many
692 shell scripts written in sh or ksh will fail. This is also
693 applies to BSD-derived systems that also ship with a SYSV-
694 derived shell (for example, /bin/sh5 on Ultrix).
695
696 One solution is to link rc to a file that does not contain the
697 letter `r', and use that file as your SHELL. You can achieve
698 this automatically by placing the following commands in your
699 .rcrc:
700
701 rcdir = `{ dirname $SHELL } {
702 test -f $rcdir/RC || ln $rcdir/rc $rcdir/RC
703 SHELL = $rcdir/RC
704 }
705
706 Make sure when you install a new version of rc that you remove
707 the previous RC.
708
709 This behaviour is also a potential problem if you use a sh
710 wrapper around rc as your login shell (see 5.2 and 6.3). Make
711 sure that the name of the wrapper does not contain the letter
712 `r'.
713
7145.5 What problems occur with rc on NeXTs?
715
716 The NeXT window system assumes that all shells are `job control'
717 shells and will place themselves in a new process group.
718 Contrary to this assumption, rc is not a job control shell and
719 so does not do this. The result is that a signal to one (such
720 as an interrupt) will be sent to all.
721
722 The `newpgrp' built-in command was provided to deal with this
723 problem. You can use it to ensure that each new interactive rc
724 belongs to a new process group by using a prompt function to run
725 code in each new interactive instance of rc (see 6.1 and 6.2).
726 Other more elegant solutions (such as a wrapper around rc) are
727 precluded by the uncooperative and inflexible nature of the NeXT
728 window system.
729
730 See also 6.1 and 6.2.
731
7325.6 How do I keep down the size of my .rcrc file?
733
734 Given the nature of rc, the natural place to define functions is
735 in the .rcrc file. However, as the number of functions grows,
736 it becomes more awkward to maintain them all in a single file.
737 One solution is to break out the functions into separate files
738 and automatically load them within .rcrc:
739
740 fnlib = $home/fnlib
741 fn load { ~ $#* 1 && builtin . $fnlib/$1 }
742 builtin cd $fnlib
743 name = () for ( name in * ) load $name
744 builtin cd
745
746 See also 5.7.
747
7485.7 How do I speed up the execution of my .rcrc file?
749
750 If you have lots of functions, you may wish to use lazy function
751 loading:
752
753 fnlib = $home/fnlib
754 fn load { ~ $#* 1 && builtin . $fnlib/$1 }
755 builtin cd $fnlib
756 name = () for ( name in * ) fn $name { load $0 && $0 $* }
757 builtin cd
758
759 Often, though, a more substantial amount of time is spent
760 testing directories before they are added to a path: rc does not
761 have a built-in test command, so each test implies a fork and an
762 exec. In some circumstances, you can replace the test with code
763 similar to the following:
764
765 path = ()
766 dir = () for ( dir in ... )
767 builtin cd $dir >[1=] >[2=] && path = ( $path $dir )
768 builtin cd
769
770 See also 5.6 and 4.13.
771
7726. Interactions between rc and the rest of UNIX
773
7746.1 How do I get each new interactive rc to do ...?
775
776 Rather than set the `-l' flag and place the code in .rcrc, you
777 can use a prompt function like the following:
778
779 fn prompt {
780 if ( ! ~ $ipid $pid ) {
781 ipid=$pid
782 ...
783 }
784 }
785
786 This will run ... at the start of each new interactive instance
787 of rc, but not in non-interactive instances of rc.
788
789 See also 6.2 and 5.5.
790
7916.2 How do I get rc to do ... in each new xterm?
792
793 Since xterm puts WINDOWID into the environment, you can use a
794 prompt function like the following:
795
796 fn prompt {
797 if ( ! ~ $wid $WINDOWID && ~ $TERM xterm* ) {
798 wid=$WINDOWID
799 ...
800 }
801 }
802
803 See also 6.1.
804
8056.3 How do I get rc to read .rcrc when I use rsh?
806
807 rshd does not place a `-' in the first character of argv[0] when
808 it execs a shell, so .rcrc is not run and this can cause
809 problems.
810
811 One solution is to have a false login shell called login-shell
812 that explicitly supplies a -l flag to rc, i.e., login-shell
813 contains:
814
815 #! /path/to/rc
816 exec /path/to/rc -l $*
817 # end-of-file
818
819 See also 5.2.
820
8216.4 How do I get at or batch to run an rc script?
822
823 at and batch only accept sh or csh scripts, so you need to
824 package your rc script in a sh wrapper. The following two
825 functions accomplish this. Note that they do not completely
826 emulate the standard commands, as they will not accept a file
827 name on the command line, but rather only read commands from
828 stdin. A simple further enhancement might be to mail the stdout
829 and stderr of the job back to the user.
830
831 fn at {
832 if ( ~ $#* 0 ) {
833 echo >[2=1] \
834 'usage: at [ time [day] | -r job ... | -l [job ...] ]'
835 return 1
836 }
837 switch ( $1 ) {
838 case -r
839 builtin at $*
840 case -l
841 builtin at $* >[2=1]
842 case *
843 {
844 echo 'SHELL='^$SHELL
845 echo 'export SHELL'
846 echo 'sed ''s/^-//'' <<''+'' | '^$SHELL
847 sed 's/^/-/'
848 echo '+'
849 } | SHELL = /bin/sh builtin at $*
850 }
851 }
852
853 fn batch {
854 if ( ! ~ $#* 0 ) {
855 echo >[1=2] 'usage: batch'
856 return 1
857 }
858 {
859 echo 'SHELL='^$SHELL
860 echo 'export SHELL'
861 echo 'sed ''s/^-//'' <<''+'' | '^$SHELL
862 sed 's/^/-/'
863 echo '+'
864 } | SHELL = /bin/sh builtin batch
865 }
866
8677. Programming in rc
868
8697.1 What makes rc such a good scripting language?
870
871 Brian Kernighan and Rob Pike wrote of the original v7 Bourne
872 shell:
873
874 The UNIX shell isn't typical of command interpreters:
875 although it lets you run commands in the usual way, because
876 it is a programming language it can accomplish much more.
877
878 Their comments apply equally to rc, perhaps more so.
879
880 The two aspects of rc that contribute most to its utility as a
881 scripting language are its simple quoting rule coupled with the
882 absence of rescanning and the fact that the language is small,
883 simple, and well defined.
884
885 The former allows one to write scripts with complete control
886 over the lexical aspects of the process: when and if globbing,
887 pattern matching, and list formation take place. Tom Duff wrote
888 that rc is `not a macro processor'. The lack or rescanning,
889 together with improvements to backquote substitutions, allowed
890 him to collapse Bourne's four types of quoting down to one,
891 eliminating all of their complex interactions.
892
893 The latter means that the whole language can be readily
894 understood by the user. Its grammar is well defined, in sharp
895 contrast to sh. (Indeed, a skeleton yacc grammar is included as
896 an appendix to rc's manual page.) The language is small and
897 well defined; there are, to quote John Mackin, no `dark
898 corners'. Although the language is smaller and simpler, it
899 retains all the power and flexibility of sh, and improves and
900 extends on it in several areas.
901
9027.2 What are the trade-offs between functions and scripts?
903
904 Functions are run in the process that invokes them, so they can
905 make persistent changes to the environment of the interpreter.
906 They are essential for some actions (reading a variable, for
907 example).
908
909 Functions make excellent wrappers around standard commands, as
910 one can use the `builtin' command to invoke the standard command
911 from within the function. Invoking a standard command from
912 within a script of the same name involves either hard-wiring the
913 name into the script or using a more elaborate method, such as
914 the `pathos' script posted to the mailing list in June 1992.
915
916 There is less overhead in invoking a function, as the kernel
917 need not exec rc once again.
918
919 However, functions take up space in the environment. There is
920 often a hard limit on the size of the environment. Although on
921 some systems this limit is very large, on others it is not. In
922 addition, very large environments can degrade the performance of
923 fork.
924
925 Functions cannot be exec-ed directly by a C program, but must be
926 invoked through rc, although it is probably a good idea to do
927 this anyway, as responsibility for globbing and variable
928 substitution properly resides with the shell.
929
9307.3 What can I do if I have deficient sed, awk, test, ... ?
931
932 Shell programming on UNIX rests on two foundations: the shell
933 itself and the toolkit of programs provided in /bin and
934 /usr/bin. Unfortunately, many vendors provide out-of-date tools
935 and there are many incompatibilities between BSD- and SYSV-
936 derived systems, so writing portable scripts is a problem. This
937 problem can be especially acute in heterogeneous clusters.
938
939 There are two approaches to this problem: one is to use only
940 those tools and options that were present in v7, and the other
941 is to use only those tools and options that are present in
942 POSIX.2, and to replace the vendor-supplied tools with those
943 from GNU if the former do not conform (see 7.4).
944
9457.4 Where do I obtain the GNU tools and other software?
946
947 Get prep.ai.mit.edu:/pub/gnu/GNUinfo/FTP by anonymous FTP for a
948 list of sites that archive GNU software.
949
950 The article `How to find sources' lists sites that archive
951 software posted to Usenet source newgroups. This article is
952 regularly cross-posted to comp.sources.wanted, comp.answers, and
953 news.answers, and is also available via anonymous FTP as
954 rtfm.mit.edu:/pub/usenet/comp.answers/finding-sources.
955
9567.5 How do I perform arithmetic in rc?
957
958 You can use /bin/expr, /bin/awk, or unary arithmetic with lists
959 (see 7.6 for an example).
960
9617.6 How do I find the first occurrence of an element in a list?
962
963 Use an `index' function, as in:
964
965 ; x = ( a b a b )
966 ; index b $x
967 2
968
969 This implementation of index uses a list to count up to the
970 index of the element:
971
972 fn index {
973 switch ( $#* ) {
974 case 0 1
975 echo >[1=2] 'usage: index pattern list ...'
976 return 1
977 case *
978 elem = $1 prefix = () {
979 shift
980 if ( ! ~ $elem $* ) {
981 echo 0
982 return 1
983 }
984 while ( prefix = ( $prefix $1 ) && ! ~ $elem $1 )
985 shift
986 echo $#prefix
987 return 0
988 }
989 }
990 }
991
9927.7 How do I use ranges in array subscripts in rc?
993
994 Use a `seq' function, as in:
995
996 ; x = ( a b c d e f g h )
997 ; echo $x( `{seq 2 5} )
998 b c d e
999
1000 There are many implementations of seq, most of which use awk,
1001 like this one:
1002
1003 fn seq {
1004 switch ( $#* ) {
1005 case 1
1006 * = ( 1 $1 )
1007 case 2
1008 case *
1009 echo >[1=2] usage: seq [start] stop
1010 return 1
1011 }
1012 echo $1 $2 | awk '{
1013 if ( $1 <= $2 )
1014 for ( i = $1; i <= $2; i++ ) print i;
1015 else
1016 for ( i = $1; i >= $2; i-- ) print i;
1017 }'
1018 }
1019
10207.8 How do I perform the equivalent of read in rc?
1021
1022 Use a `read' function, to read a single line from stdin, remove
1023 the trailing newline, and assign it to a variable:
1024
1025 ; read foo
1026 Do the funky gibbon!
1027 ; echo $foo
1028 Do the funky gibbon!
1029 ; echo $#foo
1030 1
1031
1032 The following implementation of read returns 1 if EOF is seen,
1033 like the read in the v7 sh:
1034
1035 fn read {
1036 if ( ! ~ $#* 1 ) {
1037 echo >[1=2] 'usage: read variable'
1038 return 1
1039 }
1040 if ( ~ $1 '*' () *'='* ) {
1041 echo >[1=2] 'read: bad variable name'
1042 return 1
1043 }
1044 lines = () nl = () {
1045 ifs = () { nl = `{ echo } }
1046 ifs = $nl { lines = `{ line ; echo $status } }
1047 if ( ~ $#lines 2 ) {
1048 $1 = $lines(1)
1049 return 0
1050 } else {
1051 $1 = ''
1052 return $lines(1)
1053 }
1054 }
1055 }
1056
1057 If your UNIX does not have a line command, the following is an
1058 straightforward substitute.
1059
1060 #include <unistd.h>
1061 int main ()
1062 {
1063 unsigned char c;
1064
1065 while (read (0, &c, 1) == 1 && c != '\n')
1066 write (1, &c, 1);
1067 write (1, "\n", 1);
1068 return c != '\n';
1069 }
1070
1071 Attempts to use standard UNIX utilities (e.g., "sed 1q", "head
1072 -1", and "awk '{ print; exit; }'") to replace the line command
1073 fail because line does not buffer its input. This was discussed
1074 extensively in the mailing list in September 1991 (see 2.2).
1075
1076 Alternatively, a patch to add a built-in read was posted to the
1077 mailing list in September 1993 (see 1.4).
1078
1079Acknowledgements
1080
1081Many people have contributed ideas, code, and information to this
1082document, either directly or indirectly, through the rc mailing list and
1083its influence on my understanding of rc.
1084
1085People who have directly contributed to this document include Vincent
1086Broman, Raymond Chen, Tom Culliton, Stefan Dalibor, Jim Davis, Matt Day,
1087Matthew Farwell, David Fiander, Tim Goodwin, Paul Haahr, Charles Hannum,
1088David Hogan, Noel Hunt, John LoVerso, Hamish Macdonald, John Mackin,
1089Byron Rakitzis, Boyd Roberts, Rich Salz, Chris Siebenmann, Emin Gun
1090Sirer, Icarus Sparry, Gerry Tomlinson, Malte Uhl, Christopher Vance, and
1091Victor Zandy. My apologies to anyone I have missed.
1092
1093As a user of rc, I am indebted to Tom Duff for its design, to Steve
1094Bourne for its foundation, and to Byron Rakitzis for its implementation.
1095
1096Alan Watson (al...@lowell.edu)