Rc — The Plan 9 Shell
Rc is a command interpreter for Plan 9 that provides similar facilities to UNIX’s Bourne shell, with some small additions and less idiosyncratic syntax. This paper uses numerous examples to describe rc’s features, and contrasts rc with the Bourne shell, a model that many readers will be familiar with.
Rc is similar in spirit but different in detail from UNIX’s Bourne shell. This paper describes rc’s principal features with many small examples and a few larger ones. It assumes familiarity with the Bourne shell.
2. Simple commands
For the simplest uses rc has syntax familiar to Bourne-shell users. All of the following behave as expected:
who | wc
vc *.c &
mk && v.out /*/bin/fb/*
rm -r junk || echo rm failed!
An argument that contains a space or one of rc’s other syntax characters must be enclosed in apostrophes (’):
rm ’odd file name’
An apostrophe in a quoted argument must be doubled:
echo ’How’’s your father?’
An unquoted argument that contains any of the characters * ? [ is a pattern to be matched against file names. A * character matches any sequence of characters, ? matches any single character, and [class] matches any character in the class, unless the first character of class is ~, in which case the class is complemented. The class may also contain pairs of characters separated by -, standing for all characters lexically between the two. The character / must appear explicitly in a pattern, as must the path name components . and ... A pattern is replaced by a list of arguments, one for each path name matched, except that a pattern matching no names is not replaced by the empty list; rather it stands for itself.
UNIX’s Bourne shell offers string-valued variables. Rc provides variables whose values are lists of arguments — that is, arrays of strings. This is the principal difference between rc and traditional UNIX command interpreters. Variables may be given values by typing, for example:
The parentheses indicate that the value assigned to path is a list of two strings. The variables user and font are assigned lists containing a single string.
The value of a variable can be substituted into a command by preceding its name with a $, like this:
If path had been set as above, this would be equivalent to
echo . /bin
Variables may be subscripted by numbers or lists of numbers, like this:
echo $path(2 1 2)
These are equivalent to
echo /bin . /bin
There can be no space separating the variable’s name from the left parenthesis; otherwise, the subscript would be considered a separate parenthesized list.
The number of strings in a variable can be determined by the $# operator. For example,
would print 2 for this example.
The following two assignments are subtly different:
The first sets empty to a list containing no strings. The second sets null to a list containing a single string, but the string contains no characters.
Although these may seem like more or less the same thing (in Bourne’s shell, they are indistinguishable), they behave differently in almost all circumstances. Among other things
prints 0, whereas
All variables that have never been set have the value ().
Occasionally, it is convenient to treat a variable’s value as a single string. The elements of a string are concatenated into a single string, with spaces between the elements, by the $" operator. Thus, if we set
list=(How now brown cow)
cause the same output, viz:
How now brown cow
echo $#list $#string
because $list has four members, but $string has a single member, with three spaces separating its words.
When rc is reading its input from a file, the file has access to the arguments supplied on rc’s command line. The variable $* initially has the list of arguments assigned to it. The names $1, $2, etc. are synonyms for $*(1), $*(2), etc. In addition, $0 is the name of the file from which rc’s input is being read.
Rc has a string concatenation operator, the caret ^, to build arguments out of pieces.
is exactly equivalent to
Suppose variable i contains the name of a command. Then
vl -o $1 $i^.v
might compile the command’s source code, leaving the result in the appropriate file.
Concatenation distributes over lists. The fo