Shell families and lineage
Shell families and lineage
A shell is the interpreter that takes user input and hands it to the operating system. On the same OS we can pick from several shells, each with slightly different syntax and capabilities.
1. About shells
The OS kernel works through system calls. Asking a regular user to invoke system calls directly every time would be cumbersome, so we need a middle layer that takes commands and runs programs. The shell is that middle layer.
Shells are used both interactively (REPL) and as scripts batched from a file. The same interpreter handles both.
2. The Unix lineage
The Unix shell lineage traces back to the Thompson shell of 1971.
| Shell | Released | Traits |
|---|---|---|
| sh (Bourne shell) | 1977 | Stephen Bourne. The Unix V7 standard. The reference for POSIX sh. |
| csh | 1978 | Bill Joy. C-flavored syntax. Has scripting pitfalls. |
| ksh (KornShell) | 1983 | David Korn. Combines csh's interactive features with sh's syntax. |
| bash | 1989 | Brian Fox. The GNU project's sh-compatible shell. The de facto Linux default. |
| zsh | 1990 | Paul Falstad. ksh/bash compatible plus strong autocompletion. macOS 10.15+ default. |
| fish | 2005 | "Friendly Interactive Shell". Intentionally non-POSIX. |
Linux distros usually keep bash as the user shell and wire /bin/sh to a lighter POSIX sh like dash (Debian Almquist Shell).
3. Where the POSIX standard sits
POSIX (Portable Operating System Interface) is the IEEE family of standards for Unix-flavored OS interfaces, started in 1988. Part of it defines the shell command language (POSIX sh).
Modern shells like bash, zsh, and ksh are supersets of POSIX sh. Scripts written within POSIX sh generally run anywhere, but bash-only extensions ([[ ]], arrays) break under stricter shells like dash. Scripts that start with #!/bin/sh are safest staying inside POSIX.
4. The Windows lineage
| Shell | Released | Traits |
|---|---|---|
| COMMAND.COM | 1981 (MS-DOS 1.0) | The 16-bit DOS-era command processor. |
| cmd.exe | 1993 (Windows NT 3.1) | The 32/64-bit successor on NT. Runs .bat/.cmd. |
| Windows PowerShell | 2006 | Built on .NET Framework. An object-oriented shell. Default since Windows 7+. |
| PowerShell 7+ | 2020 | Built on .NET Core (later .NET 5+). Cross-platform. |
PowerShell's command unit is a cmdlet — Verb-Noun naming (Get-Process, Set-Item).
5. Object pipes vs text pipes
A bash-family pipe | flows the bytes of stdout into the next command's stdin.
ps -ef | grep node | awk '{print $2}'
A PowerShell pipe flows .NET objects. The next stage accesses object properties directly:
Get-Process | Where-Object { $_.Name -eq "node" } | Select-Object -ExpandProperty Id
The two models have different expressive grain. Text pipes combine with any tool and are highly portable. Object pipes are safer and more precise on structured data.
6. Defaults by environment
- macOS 10.15+ — zsh.
- macOS 10.14 and earlier — bash 3.2 (Apple stopped upgrading to avoid GPLv3).
- Most Linux — user shell bash,
/bin/shis dash or bash's sh mode. - Windows 10/11 — PowerShell + cmd.exe. Windows Terminal as the host.
- WSL2 — same as a regular Linux inside.
7. Interactive vs script
A shell wears two faces:
- Interactive — humans typing commands. Autocomplete, history, prompt, theme.
- Non-interactive (script) — running a file of commands as a batch. Stability, portability, error handling.
zsh and fish lean into interactive convenience; bash and dash lean into scripting compatibility. A common combination is using zsh day-to-day while writing automation scripts in bash.
8. Switching shells
| Task | macOS/Linux | Windows |
|---|---|---|
| List available shells | cat /etc/shells |
(Windows Terminal profiles) |
| Change default shell | chsh -s /bin/zsh |
Windows Terminal default profile setting |
| Check current shell | echo $SHELL |
$PSVersionTable.PSVersion (PowerShell) |
9. Common pitfalls
bash-only syntax ([[, arrays, <<<) inside a #!/bin/sh script — breaks under dash.
macOS bash is 3.2, so newer bash 4/5 features like associative arrays and mapfile are unavailable — install a fresh bash via Homebrew and switch to #!/usr/bin/env bash.
Differences between PowerShell 5.1 and 7+ — 5.1 has no &&/|| and the object output behaves differently in places.
fish is non-POSIX — other shell scripts will not run unchanged. fish users running a bash script need to specify the interpreter with bash script.sh.
Closing thoughts
The shell choice settles between two corners: interactive comfort (zsh, fish) and scripting compatibility (bash, dash). Keeping both — zsh for everyday and #!/usr/bin/env bash for automation — is the operational shape we see most often.
Next
- bash-and-sh
- powershell-basics
GNU Bash Manual · zsh docs · POSIX Shell (IEEE 1003.1) · Microsoft PowerShell · Wikipedia — Comparison of command shells for reference.