Est. 1983 Intermediate

Korn Shell

A powerful Unix shell developed by David Korn at Bell Labs that combined Bourne shell compatibility with C shell interactive features and added associative arrays, floating-point arithmetic, and rich programming constructs.

Created by David G. Korn

Paradigm Procedural, Scripting
Typing Dynamic, Weak
First Appeared 1983
Latest Version ksh93u+m/1.0.10 (community fork, 2024)

The Korn Shell (ksh) is a Unix shell developed by David G. Korn at AT&T Bell Laboratories and first presented publicly in 1983. It was designed to combine the scripting strength of the Bourne shell with the interactive convenience of the C shell, and then to push well beyond both with features borrowed from programming languages: associative arrays, floating-point arithmetic, name references, compound variables, and a rich expression language. For decades it served as the default shell on commercial Unix systems such as AIX and Solaris, and its design directly shaped the POSIX shell standard, Bash, and Zsh. Although it is no longer the dominant Unix shell on Linux, ksh remains in active maintenance through the ksh93u+m community fork and is still widely encountered in enterprise environments.

History & Origins

Bell Labs in the Early 1980s

By the early 1980s, Unix users at Bell Labs faced a recurring tension between two shells. The Bourne shell (sh), shipped with Unix V7 in 1979, was a capable scripting language but offered little in the way of interactive convenience: no command history, no line editing, no job control, no aliases. The C shell (csh), written by Bill Joy at Berkeley, provided those interactive features but had a different and often awkward scripting syntax that diverged from Bourne in subtle, error-prone ways.

David Korn, a member of the Bell Labs computer science research staff, set out to build a shell that did both well: a strict superset of the Bourne shell’s scripting language together with the interactive features users had come to expect from csh. The initial implementation grew out of internal AT&T work on shell improvements during 1982 and was first presented to the wider Unix community at the USENIX summer conference in Toronto in July 1983.

Distribution Within and Beyond AT&T

Through the mid-1980s, the Korn shell circulated within AT&T and select licensees, evolving rapidly as Korn responded to user feedback. The first version distributed broadly outside Bell Labs—ksh88, released in 1988—became the reference Korn shell for nearly a decade. Most commercial Unix vendors began bundling ksh88, and it shipped as a standard component of System V Release 4.

In 1993, Korn released ksh93, a substantial rewrite that added many programming-language features new to shells. For most of the 1990s and early 2000s, ksh88 and ksh93 coexisted: ksh88 was conservative and widely deployed, while ksh93 was more powerful but slower to propagate to legacy systems.

Open Sourcing

For most of its early life ksh was AT&T proprietary software, available only to AT&T Unix licensees. This restriction motivated several independent reimplementations, most notably the Public Domain Korn Shell (pdksh), a clean-room rewrite that became the default /bin/sh on OpenBSD and the basis for mksh (MirBSD Korn Shell).

In 2000, AT&T released the ksh93 source code under an open-source license, and in 2005 the license was changed to the Eclipse Public License (EPL) as part of the broader AST (Advanced Software Technology) toolkit. After the final AT&T release, ksh93u+ in 2012, upstream activity at AT&T effectively wound down. A community-led release branded ksh2020 appeared but was withdrawn after regressions were discovered. Since 2021, Martijn Dekker has maintained the ksh93u+m fork, which is now the active upstream for Korn shell development.

Design Philosophy

The Korn shell rests on a few clear design principles that distinguish it from both its Bourne ancestor and the contemporaneous C shell.

Strict Bourne compatibility. A POSIX-compatible Bourne script runs unmodified under ksh. Korn explicitly preserved the Bourne scripting model—if/fi, case/esac, for/done, here-documents, command substitution—so existing scripts and the habits surrounding them continued to work.

Interactive features without syntactic divergence. Rather than create a separate scripting dialect (the path C shell took), Korn added command history, vi and emacs line editing, aliases, and job control as orthogonal extensions to a single, consistent language.

Programming-language ambitions. ksh93 in particular treats the shell less as a glue layer and more as a real programming environment. Associative arrays, name references, floating-point arithmetic, compound variables that act like records, and discipline functions (which are roughly analogous to property accessors) move the language closer in spirit to Awk or Perl than to V7 sh.

Performance as a goal. Many built-ins that other shells leave to external commands—printf, [[, integer arithmetic, even an optional built-in cat—are integrated into ksh to avoid fork/exec overhead. The shell is designed to make typical administrative scripts measurably faster than equivalent Bourne shell scripts, though specific speedups depend heavily on workload.

Key Features

Compatibility with Bourne Shell

Korn shell scripts use the same control structures, redirection syntax, and quoting rules as the Bourne shell:

1
2
3
4
5
6
7
8
#!/bin/ksh
if [ "$#" -gt 0 ]; then
    for arg in "$@"; do
        echo "arg: $arg"
    done
else
    echo "no arguments"
fi

Command-Line Editing

ksh88 introduced built-in command-line editing modes, selectable with set -o:

1
2
set -o vi        # vi-style editing (Esc to enter command mode)
set -o emacs     # emacs-style editing (Ctrl key bindings)

Both modes provide history recall, character and word movement, and incremental search—features that were entirely absent from the Bourne shell.

Aliases and History

1
2
3
4
5
6
7
alias ll='ls -alF'
alias h='history'

# History recall
fc -l            # list recent commands
fc -e -          # re-execute last command
r grep           # re-execute last command starting with 'grep'

Extended Test Command [[ ]]

ksh introduced the [[ ... ]] conditional expression, which avoids the word-splitting and quoting hazards of the legacy [ command and adds pattern-matching operators:

1
2
3
4
5
6
7
if [[ -f "$file" && "$file" == *.txt ]]; then
    echo "Text file exists"
fi

if [[ "$version" == @(1.*|2.*) ]]; then
    echo "Old version"
fi

Integer and Floating-Point Arithmetic

1
2
3
4
5
6
7
8
9
# Integer arithmetic (ksh88 and later)
(( count = 10 ))
(( count += 5 ))
echo $count                       # 15

# Floating-point arithmetic (ksh93 and later)
typeset -F2 price
(( price = 9.99 * 1.0825 ))
echo $price                       # 10.81

Arrays

Indexed arrays were available in ksh88; associative arrays were introduced in ksh93:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Indexed array
typeset -a colors
colors=(red green blue)
echo "${colors[1]}"               # green
echo "${#colors[@]}"              # 3

# Associative array (ksh93+)
typeset -A capitals
capitals[france]=Paris
capitals[japan]=Tokyo
echo "${capitals[japan]}"         # Tokyo

Compound Variables (ksh93)

ksh93 supports structured variables that behave like records:

1
2
3
4
5
6
7
typeset -A employee
employee=(
    name="Alice"
    title="Engineer"
    salary=75000
)
echo "${employee.name}"

Name References (ksh93)

A nameref is a variable that aliases another variable—useful for passing variables by reference into functions:

1
2
3
4
5
6
7
8
function increment {
    typeset -n var=$1
    (( var += 1 ))
}

counter=10
increment counter
echo $counter                     # 11

Functions with Local Variables

1
2
3
4
5
6
function greet {
    typeset name="${1:-World}"
    echo "Hello, $name!"
}

greet Alice

ksh distinguishes between two function definition styles:

1
2
3
4
5
# POSIX-style (no local scope by default)
name() { commands; }

# Korn-style (variables declared with typeset are local)
function name { commands; }

Co-processes

A long-standing distinctive feature is the |& co-process operator, which runs a command asynchronously with its stdin and stdout connected to the parent shell:

1
2
3
4
bc |&                              # start bc as a co-process
print -p "2 + 2"                   # send to co-process stdin
read -p answer                     # read from co-process stdout
echo "bc says: $answer"

Korn Shell Versus Other Shells

FeatureBourne shksh88ksh93Bash
Command-line editingNoYes (vi/emacs)YesYes
[[ ]] testNoYesYesYes
Indexed arraysNoYesYesYes
Associative arraysNoNoYesYes (4.0+)
Floating-point mathNoNoYesNo
Compound variablesNoNoYesNo
Name referencesNoNoYesYes (declare -n)
$(...) substitutionNoYesYesYes
Co-processes (|&)NoYesYesYes (different syntax)
Default on LinuxSometimesRareRareCommon

Many features that programmers think of as “Bash-isms” actually originated in ksh and were later adopted into Bash—including $(...), arithmetic expansion, [[ ]], and indexed arrays. The reverse is also true: Bash’s associative array syntax was modeled on the ksh93 design.

Influence on POSIX and Other Shells

When the IEEE P1003.2 working group standardized the shell in the late 1980s and early 1990s, ksh88 was a major source. Several features that had been Korn-specific—$(command) for nested command substitution, $((expression)) for arithmetic, tilde expansion (~user)—became part of the POSIX shell standard, ratified as IEEE Std 1003.2-1992. Through POSIX, these features then spread to every modern shell.

Bash, originally a GNU Project replacement for the Bourne shell, progressively absorbed Korn shell features through the 1990s and 2000s: [[ ]], indexed arrays, associative arrays (Bash 4.0, 2009), and many parameter-expansion forms. Zsh similarly borrowed from ksh in its early years before evolving its own large feature set.

Current Status

The Korn shell remains in active use, though its role has shifted. On Linux, Bash is dominant for both interactive and scripting use, with Dash and Ash filling the role of a minimal POSIX shell. On AIX, ksh is still the default login shell, and on enterprise Solaris-derived systems ksh93 has long been the default /bin/sh. OpenBSD continues to ship a pdksh-derived shell as /bin/ksh, and Android reportedly ships mksh as a system shell.

The most active modern development is the ksh93u+m community fork maintained by Martijn Dekker, which has produced multiple stable releases since 2022 and is packaged by many Linux distributions in place of the older AT&T binaries. This fork preserves backward compatibility with ksh93u+ while fixing long-standing bugs and modernizing the build system.

For practitioners, ksh remains worth knowing for three reasons: it is still the de facto scripting language for substantial bodies of enterprise infrastructure; it is the most expressive Bourne-family shell, with language features no other mainstream shell matches; and its design choices are visible throughout the modern shell landscape, from POSIX sh to Bash to Zsh.

Why the Korn Shell Matters

The Korn shell occupies a unique place in Unix history. It was the first shell to take seriously the idea that a Unix shell could be both a comfortable interactive environment and a real programming language without sacrificing compatibility with the Bourne tradition. By demonstrating that arrays, structured variables, and floating-point math belonged in a shell, it raised the ceiling on what shell scripts could reasonably accomplish—and by feeding so many of its innovations into the POSIX standard, it shaped what every subsequent shell would inherit.

For decades, “knowing ksh” was a prerequisite for serious Unix system administration. That status has eroded as Bash and Zsh have absorbed most of ksh’s syntactic contributions and as Linux has displaced commercial Unix in most contexts. But the lineage runs deep: every time a script uses $(...) instead of backticks, every time a [[ ]] test avoids a quoting bug, every time Bash declares an associative array, the Korn shell’s design decisions are at work.

Timeline

1983
David Korn presents the Korn shell at the USENIX conference in Toronto, July 1983. The shell originated at AT&T Bell Laboratories as an internal tool combining Bourne shell scripting with C shell interactive features.
1986
Korn shell becomes more widely available within AT&T and is reportedly distributed via the AT&T Toolchest program, gaining traction outside Bell Labs.
1988
ksh88 is released, becoming the first version distributed broadly with commercial Unix systems. It introduces command-line editing modes (vi and emacs), aliases, and many features that POSIX would later standardize.
1992
IEEE Std 1003.2-1992 (POSIX shell standard) is ratified, drawing extensively from ksh88 features such as command substitution with $(...), arithmetic expansion $((...)), and tilde expansion.
1993
ksh93 is released as a major rewrite, adding associative arrays, floating-point arithmetic, compound variables, name references (nameref), discipline functions, and a built-in printf.
2000
AT&T open-sources the Korn shell source code, reportedly under the Common Public License, making ksh93 freely available outside commercial Unix distributions.
2005
AT&T relicenses ksh93 under the Eclipse Public License (EPL) as part of the AST (Advanced Software Technology) project, improving compatibility with open-source distribution.
2012
ksh93u+ is released by AT&T Research as the final stable release of the original codebase before active development at AT&T effectively ceased.
2020
A community-led 'ksh2020' release is published but is later withdrawn after numerous regressions are discovered, prompting renewed community maintenance efforts based on ksh93u+.
2021
Martijn Dekker begins maintaining the ksh93u+m community fork, taking over as the de facto upstream for active Korn shell development and producing the first stable 1.0.0 release in 2022.

Notable Uses & Legacy

IBM AIX

Korn shell (ksh88, with ksh93 also available) has been the default login shell on IBM's AIX Unix operating system for decades, making it the standard scripting environment for enterprise AIX administration in banking, insurance, and telecom deployments.

Solaris and Illumos

Sun Solaris shipped ksh as a standard shell, and Solaris 11 (released 2011) reportedly made ksh93 the default /bin/sh. Illumos-based distributions such as OmniOS continue to include ksh93 in their core install.

OpenBSD pdksh and mksh

OpenBSD ships a pdksh-derived shell (Public Domain Korn Shell) as /bin/ksh, a clean-room reimplementation of ksh88. MirBSD's mksh is a derivative reportedly used as a system shell in Android.

Enterprise Unix Administration

Many long-running enterprise and HPC scripts—particularly in financial services, where AIX and Solaris were dominant—are written specifically against ksh88 or ksh93. These scripts often rely on Korn-specific features such as associative arrays and compound variables that are not portable to POSIX sh.

POSIX Shell Standard Foundation

Korn shell directly influenced the IEEE POSIX shell specification. Many features added by ksh88—including $(...) command substitution, $((...)) arithmetic, and tilde expansion—were codified into POSIX 1003.2 and are now found in every POSIX-compliant shell.

Language Influence

Influenced By

Influenced

Bash Z Shell POSIX sh Public Domain Korn Shell (pdksh) MirBSD Korn Shell (mksh)

Running Today

Run examples using the official Docker image:

docker pull
Last updated: