Bourne Shell
The original Unix shell written by Stephen Bourne at Bell Labs, which introduced structured scripting to Unix and became the ancestor of virtually every modern shell.
Created by Stephen R. Bourne
The Bourne Shell (sh) is the foundational Unix shell, written by Stephen R. Bourne at Bell Laboratories and released as part of Unix Version 7 in 1979. It replaced the earlier Thompson shell with a dramatically more capable scripting language—introducing structured control flow, named variables, here-documents, signal trapping, and the ability to use scripts as pipeline filters. Every major shell in widespread use today—Bash, Korn shell, Zsh, Dash—descends directly from or was designed as a compatible replacement for the Bourne shell. The POSIX shell standard, which governs portable scripting across all Unix-like systems, is itself based on the System V Bourne shell. Few pieces of software have had a more lasting influence on the daily practice of computing.
History & Origins
The Thompson Shell Problem
The original Unix shell, written by Ken Thompson and shipping with Unix versions 1 through 6, was a minimal command interpreter. It lacked named variables (only positional parameters were available), had no built-in control flow (even if was an external command), and suffered a critical design flaw: a script file consumed standard input, making it impossible to use a shell script as a filter in a pipeline. For interactive use the Thompson shell was serviceable, but for scripting it was severely limited.
An intermediate step came with the PWB/UNIX shell (also called the Mashey shell), written by John Mashey at Bell Labs around 1977 for the Programmer’s Workbench variant of Unix. It added built-in control structures—if, while, and switch—which pointed the direction Bourne would take further.
Stephen Bourne at Bell Labs
Stephen R. Bourne studied mathematics at King’s College London and later at Trinity College, Cambridge, where he earned advanced degrees and worked on the ALGOL 68C compiler project, serving on the ALGOL 68 revision committee. He then joined Bell Laboratories and, as part of the Seventh Edition Unix team, wrote the shell that bears his name.
Development work on the Bourne shell began around 1976–1977. An internal version-controlled snapshot dated October 12, 1978 survives (version string sys137), showing the shell was in internal use at AT&T before its public release. In 1979, Unix Version 7 shipped the Bourne shell as /bin/sh, making it publicly available to the universities and research institutions that licensed AT&T Unix.
The ALGOL 68 Connection
Bourne’s academic background left a distinctive mark on the shell in two ways. First, the control structure syntax uses paired keywords derived from ALGOL: if closes with fi, case closes with esac, and loop bodies end with done—a pattern carried by every Bourne-compatible shell to this day.
Second, and more unusually, the shell’s C source code was written using C preprocessor macros that made C resemble ALGOL 68:
| |
This gave the source code a distinctive appearance that later helped inspire the International Obfuscated C Code Contest. Russ Cox has documented this implementation technique in detail. It is a reminder that the Bourne shell was not just a tool but a creative work shaped by its author’s intellectual history.
Design Philosophy
The Bourne shell was designed to solve the scripting inadequacies of the Thompson shell while remaining consistent with Unix’s core philosophy of composable, text-based tools. Key design decisions include:
Structured programming as a first-class concern. Control structures (if, case, for, while, until) are built into the shell itself, not external programs. A Bourne shell script can express the same logical structures as a conventional program without relying on any external binaries.
Variables and environment propagation. Named variables with assignment and expansion, positional parameters, and the export built-in for passing variables to child processes solved the Thompson shell’s variable limitations.
Scripts as filters. The shell separates command input (the script file) from standard input (the data being processed), fixing the Thompson shell’s fatal constraint. A Bourne shell script can participate as a stage in a pipeline.
Signal handling. The trap built-in allows scripts to catch Unix signals and execute cleanup code, enabling reliable resource management in long-running scripts.
Composability. The shell orchestrates other programs; it does not try to replace them. The pipeline (|) and I/O redirection model, inherited from the Thompson shell, remains the fundamental mechanism.
Key Features
Variables and Parameter Expansion
| |
Control Structures
The Bourne shell introduced these structures as built-in syntax, not external commands:
| |
I/O Redirection and Pipelines
| |
Command Substitution
| |
Signal Trapping
| |
Shell Functions (Added in SVR2, 1984)
Shell functions were not part of the original 1979 Bourne shell but were added in System V Release 2:
| |
Filename Globbing
| |
Feature Evolution Across Releases
The Bourne shell was never versioned in the way modern software is. Its capabilities evolved through the System V Unix release series:
| Release | Year | Key Additions |
|---|---|---|
| Unix V7 | 1979 | Variables, control structures (if, case, for, while, until), here-documents, command substitution (backticks), trap, eval, export, I/O redirection, pipelines, filename globbing |
| System III | 1981 | Comment character (#), set -- option delimiter |
| SVR1 | 1983 | shift n, ulimit, CDPATH |
| SVR2 | 1984 | Shell functions, type, unset, built-in echo and pwd, I/O redirection for built-ins |
| SVR3 | 1986 | getopts for portable option parsing, modern "$@" semantics, 8-bit clean text handling |
| SVR4 | 1989 | Job control, symbolic signal names for trap |
| SVR4.2 | 1992 | read -r flag for literal backslash handling |
| OpenSolaris | 2005 | AT&T source code released under CDDL license |
Standardization
The Bourne shell’s greatest long-term impact may be that it became the basis for the POSIX shell standard. IEEE P1003.2, focused on shell language and utilities, worked through the mid-to-late 1980s and was ratified in September 1992 as IEEE Std 1003.2-1992. The standard was explicitly based on the System V Bourne shell as its primary reference implementation, with the committee reconciling behavior from V7, System V, BSD, and Korn shell variants.
In 2001, IEEE Std 1003.1-2001 (also known as the Single UNIX Specification version 3, or SUSv3) merged the shell standard into a unified POSIX specification. The current revision is IEEE Std 1003.1-2024.
A consequence of this history is that POSIX sh is not identical to the original 1979 Bourne shell. Several features programmers associate with the Bourne shell—shell functions, getopts—were added in the System V era, years after Unix V7. The original V7 shell is a historical artifact; POSIX sh is the living standard.
The ALGOL 68 Keyword Pairing Legacy
One of the most visible and lasting contributions of Bourne’s design is the keyword-pairing pattern for block termination. In ALGOL 68, structured constructs end with distinct closing markers. Bourne adapted this for shell syntax:
| Opening | Closing | Construction |
|---|---|---|
if | fi | Reverse of if |
case | esac | Reverse of case |
do | done | Completion form |
then | (implicit) | Embedded in control flow |
This pattern made shell scripts visually scannable—a closing fi is unambiguous, unlike a bare } that could close any block. Every POSIX-compatible shell in use today—Bash, Zsh, ksh, Dash—inherits these exact keywords.
Current Status
The original AT&T Bourne shell binary no longer ships as /bin/sh on mainstream modern operating systems:
- Debian and Ubuntu Linux:
/bin/shpoints to Dash (Debian Almquist Shell), chosen for its strict POSIX compliance and fast startup - macOS:
/bin/shis Bash 3.2 (retained for compatibility; Apple uses GPLv2, not GPLv3) - Alpine Linux:
/bin/shis BusyBox ash, a compact POSIX sh implementation for container environments - FreeBSD:
/bin/shis the FreeBSD shell, derived from ash - Commercial Unix (HP-UX, AIX): These historically ran Bourne-derived shells; AIX uses ksh93 as its default
The original AT&T source code became publicly available in 2005 when Sun open-sourced it as part of OpenSolaris under the CDDL license. Two maintained forks preserve access to the original codebase: the Heirloom Bourne Shell (Gunnar Ritter’s portable port) and Schily bosh (originally developed by Jörg Schilling, who died in 2021; the fork includes POSIX extensions and is available in NetBSD pkgsrc and FreeBSD ports).
The shell’s true continuation is through the POSIX sh standard and its derivatives. Dash, the shell closest in spirit to the original—minimal, fast, strictly POSIX-compliant—is what most Linux systems use for /bin/sh today, directly serving the same role the Bourne shell served in 1979.
Bourne Shell vs. Bash: Key Differences
Many developers encounter Bourne shell compatibility constraints when writing portable scripts. The differences between original sh and Bash (bash) are significant:
| Feature | Bourne/POSIX sh | Bash |
|---|---|---|
| Command substitution | `cmd` (backtick) | $(cmd) preferred |
| Arithmetic | expr (external command) | $(( )) built-in |
| Arrays | None | Indexed and associative |
[[ ]] conditionals | Not available | Available (extended test) |
=~ regex matching | Not available | Available (Bash 3.0+) |
| String manipulation | Limited ${var#pat} forms | Rich expansion operators |
local in functions | Not in original V7 | Available |
Here strings (<<<) | Not available | Available |
source built-in | Not in original (. only) | Both . and source |
For maximum portability, scripts intended to run on any POSIX system should use only POSIX sh features, use the #!/bin/sh shebang, and be validated with a tool such as ShellCheck in POSIX mode.
Why the Bourne Shell Matters
The Bourne shell’s influence on computing is difficult to overstate. It defined the scripting model that Unix system administrators have used for nearly five decades. It introduced the structured control flow that made shell scripts viable programs rather than just command shortcuts. And by becoming the basis for the POSIX standard, it ensured that a script written to its conventions would be portable across every Unix-like system ever built.
The shell’s family tree traces the history of free and open-source Unix. Bash, GNU’s free Bourne replacement, became the default shell of Linux, which became the default operating system of the internet. Ash and Dash, lightweight reimplementations for resource-constrained environments, power the init systems of billions of embedded devices and containers. Every time a CI/CD pipeline runs a shell script, every time a Docker container starts with /bin/sh, every time a configure script runs before compilation—the Bourne shell’s design decisions from 1979 are at work.
For developers, the Bourne shell is not merely a historical curiosity. Understanding it illuminates why Bash behaves as it does, why some shell constructs are portable and others are not, and why decades of Unix infrastructure is written the way it is. The if/fi pairing, the $? exit status, the pipeline-first philosophy—these are Bourne’s contributions, and they remain as relevant in 2026 as they were when Unix Version 7 shipped.
Timeline
Notable Uses & Legacy
AT&T Unix System V
The Bourne shell was the default /bin/sh on all AT&T System V Unix releases throughout the 1980s and 1990s, serving as the primary administrative scripting environment for commercial Unix deployments worldwide.
GNU Autoconf configure Scripts
Autoconf generates ./configure scripts that target strict Bourne/POSIX sh compatibility as the lowest common denominator, meaning every open-source package using Autoconf ships scripts that must run on a Bourne-compatible shell. The Autoconf manual documents Bourne shell portability requirements explicitly.
Unix System Init Scripts
Every commercial Unix system (HP-UX, AIX, Solaris, IRIX) used Bourne shell scripts as rc (run-control) init scripts for boot-time system initialization. This pattern carried forward into early Linux SysV init and BSD /etc/rc.d/ scripts.
Embedded and Container Systems
BusyBox ash, a Bourne-compatible shell, provides /bin/sh in Alpine Linux, which serves as the base image for a large fraction of Docker containers. Bourne shell syntax therefore remains the scripting standard in container-based infrastructure.
POSIX sh Scripting
Scripts written to the POSIX sh standard—derived directly from the System V Bourne shell—are used across all Unix-like operating systems for portable automation. Continuous integration platforms, cloud-init scripts, and package install scripts commonly target POSIX sh for maximum portability.
Language Influence
Influenced By
Influenced
Running Today
Run examples using the official Docker image:
docker pull bash:5.2Example usage:
docker run --rm -v $(pwd):/app -w /app bash:5.2 sh hello.sh