Est. 1989 Intermediate

RC Shell

The Plan 9 command interpreter created by Tom Duff at Bell Labs — a Bourne-shell descendant with C-like syntax, cleaner quoting, and list-valued variables

Created by Tom Duff (Bell Labs)

Paradigm Procedural: Command/shell scripting
Typing Dynamic, Untyped (all values are lists of strings)
First Appeared 1989 (approximate)
Latest Version Maintained within Plan 9 / 9front and the Byron Rakitzis Unix port

rc is the command interpreter of Plan 9 from Bell Labs — a Unix shell designed by Tom Duff as a cleaner, more regular replacement for the venerable Bourne shell. It keeps the familiar role of a Unix shell — running commands, wiring up pipes, expanding variables, and driving scripts — but rebuilds the language on simpler and more consistent foundations. Where the Bourne shell accreted quirks over years of evolution, rc was designed in one piece, borrowing control-flow ideas from C and rebuilding the shell’s data model around a single uniform type — the list of strings — and the result is a small shell whose grammar fits comfortably in a person’s head.

History & Origins

rc was written by Tom Duff at Bell Labs — the same Tom Duff remembered for “Duff’s device,” the famous loop-unrolling trick in C. It originated for Research Unix (Version 10) in the late 1980s; Wikipedia dates its first appearance to 1989, though the most firmly documented early milestone is Duff’s own paper, “Rc — A Shell for Plan 9 and UNIX Systems,” presented at the Summer 1990 UKUUG Conference in London. Because the precise year of first use is not strongly corroborated by a primary Bell Labs release, the “1989” date is best treated as approximate.

rc then became the standard shell of Plan 9 from Bell Labs, the operating system that Bell Labs’ Computing Science Research Center built as a successor to Unix. When Plan 9’s First Edition shipped to universities in 1992, rc was its command interpreter, and it has remained the system’s native shell ever since — through the Second Edition (1995), the open-source release of 2000, the Fourth Edition of 2002, and the continuing 9front fork.

The shell also escaped the Plan 9 world early. Around 1991, Byron Rakitzis wrote an independent re-implementation of rc for ordinary Unix systems — a from-scratch rewrite rather than a port — which is how most Unix and Linux users have encountered the language. A separate, faithful port of Duff’s original later arrived through Plan 9 from User Space (plan9port).

Design Philosophy

Duff’s paper framed shell design as a language problem, not merely a feature-collection problem. His goal was a shell with the same expressive power as the Bourne shell but with simpler, more regular syntax and fewer of the surprises that make sh scripts fragile. Two convictions shape the result:

  • Consistency over compatibility. rc deliberately breaks with sh where sh is irregular. Its control structures look like C, its quoting has one rule, and expansion behaves predictably.
  • A real data model. rc treats the central shell datatype — the list of strings — seriously and uniformly, rather than leaning on the Bourne shell’s tangle of word-splitting and special parameters.

The explicit appeal to functional languages such as Scheme and ML belongs less to rc itself than to its direct successor, the es shell, whose authors cited those languages by name; Duff’s own rc paper is more modest, framing the work as regularizing the Bourne shell rather than importing functional-language theory. Even so, rc’s list-valued data model and predictable expansion give it more of a small-programming-language feel than most Unix shells.

Key Features

C-like control flow

Instead of the Bourne shell’s ALGOL-style if/then/fi and case/esac, rc uses brace-delimited blocks:

if (test -f config) {
    echo found it
}

for (i in *.c) {
    echo compiling $i
    cc -c $i
}

switch ($1) {
case start
    echo starting
case stop
    echo stopping
}

It also offers an if not clause as the counterpart to if.

Variables are lists of strings

Every variable in rc is a list of strings, and that single decision removes a whole class of Bourne-shell pain. There is no magic "$@" versus "$*" distinction, and argument lists carry their structure naturally:

path=(/bin /usr/bin /usr/local/bin)
echo $path        # /bin /usr/bin /usr/local/bin
echo $#path       # 3  (number of elements)

Cleaner quoting and no re-splitting

rc uses a single quoting rule — text inside single quotes is literal, with '' denoting a literal quote — so there is no nesting of backslashes to reason about. Critically, variables are not re-split into words when expanded, which eliminates the notorious “unquoted variable splits on spaces” bug that haunts Bourne-shell scripting.

Expressive pipes and redirection

rc generalizes redirection to arbitrary file descriptors and supports piping a specific descriptor between commands:

cmd >[2] errors.log      # redirect fd 2 (stderr)
producer |[2] consumer   # pipe producer's stderr into consumer

It also provides process substitution, so a command’s output can be presented to another command as a file.

Evolution

rc’s history is unusual in that the language has stayed remarkably stable while its implementations multiplied. The canonical line runs through Plan 9 itself, where rc has been the shell since 1992 and continues today in the actively developed 9front fork. Alongside it run two Unix-facing implementations: Byron Rakitzis’s independent rewrite — which added conveniences such as GNU Readline line editing and a few deliberate incompatibilities — and the plan9port port of Duff’s original code.

rc’s ideas also propagated forward. In 1993, Paul Haahr and Byron Rakitzis built es, the “extensible shell,” directly on top of the rc implementation. es kept rc’s syntax but added functional-language ideas its authors drew from Scheme and ML — first-class functions, lexical scoping, and exception handling — an experiment in just how programmable a Unix shell could become.

Current Relevance

rc is not a mainstream shell — it will never displace bash or zsh on the typical Linux desktop — but it is far from dead. It remains the default shell of a living operating system in the form of 9front and the broader Plan 9 community, and it is readily installable on conventional systems through the Rakitzis port (packaged in BSD ports and many Linux distributions) and through plan9port on Unix and macOS. For people working in the Plan 9 ecosystem, rc is simply the shell; for people elsewhere, it is a deliberate, minimalist alternative chosen for its clean syntax.

Why It Matters

rc matters because it is a careful redesign of a tool everyone takes for granted. By starting from the Bourne shell and asking what it would look like rebuilt cleanly — C-style control flow, one quoting rule, list-valued variables, no surprise word-splitting — Tom Duff produced a shell that is both smaller and more predictable than its ancestor. It demonstrated that a Unix shell could be treated as a coherent little language rather than an accretion of special cases, and that lesson echoes through later work, most directly in the es shell. For anyone studying language design, Plan 9, or the history of Unix tooling, rc is a compact and instructive example of doing a familiar thing right.

Timeline

1989
Tom Duff develops rc at Bell Labs as the shell for Research Unix (Version 10); Wikipedia dates its first appearance to this year
1990
Duff presents 'Rc — A Shell for Plan 9 and UNIX Systems' at the Summer 1990 UKUUG Conference in London, describing the shell's design
1991
Byron Rakitzis releases an independent Unix re-implementation of rc, bringing the shell to Unix systems outside Bell Labs
1992
Plan 9 from Bell Labs First Edition is released to universities, with rc as its standard command interpreter
1993
Paul Haahr and Byron Rakitzis release es ('extensible shell'), derived from the rc implementation and adding functional-programming features
1995
Plan 9 Second Edition is distributed (book and CD), continuing rc as the default shell
2000
Plan 9's third release is distributed freely over the internet under an open-source license, making the original rc source widely available
2002
Plan 9 Fourth Edition is released, with rolling updates thereafter
2011
The 9front fork of Plan 9 begins active community development, continuing rc as its default shell

Notable Uses & Legacy

Plan 9 from Bell Labs

rc is the standard command interpreter of Plan 9, the research operating system from Bell Labs designed as a successor to Unix; nearly all system scripting is written in rc.

9front

The actively maintained community fork of Plan 9 continues to ship rc as its default shell, keeping the language in everyday use on a living operating system.

Plan 9 from User Space (plan9port)

Russ Cox's port of Plan 9 tools to Unix and macOS includes a port of the original Duff rc, letting developers run Plan 9-style scripts on mainstream systems.

Byron Rakitzis's Unix rc

An independent re-implementation packaged for BSD ports and many Linux distributions, used by enthusiasts who prefer rc's syntax to the Bourne shell on conventional Unix.

es (extensible shell)

Derived directly from the rc implementation, es extended the design with first-class functions, lexical scope, and exceptions, carrying rc's ideas into a more programmable shell.

Language Influence

Influenced By

Influenced

es

Running Today

Run examples using the official Docker image:

docker pull
Last updated: