The Stephen Bourne Shell first appeared in Version 7 Unix (1979) at Bell Labs. It replaced the earlier Thompson shell and became the standard shell for Unix systems in the late 1970s and 1980s. Its design introduced structured programming features (variables, control flow) to improve on the limitations of older shells.
By default, /bin/sh was the login shell on historical Unix systems. Today, “sh” usually refers to a POSIX-compliant shell, widely used for portability. For instance, many distributions link /bin/sh to dash. The Bourne shell (sh) remains crucial for init scripts, install scripts, and other tasks demanding universal compatibility.
sh handles basic control flow (loops, if statements), pipes, redirection, variables, and command substitution. Scripts often leverage other Unix utilities for string manipulation and arithmetic.
#!/bin/sh
echo"Script name: $0"for arg in "$@";doecho"Arg: $arg"done
Brian Fox created Bash in 1989 for the GNU Project, later maintained by Chet Ramey. It was designed to be a free replacement for The Bourne shell with features from C shell and KornShell. It’s the default interactive shell on many Linux distros and was the default on macOS until recent updates.
Used both interactively and for scripting, Bash is ubiquitous in the Linux/Unix world. System boot scripts and user dotfiles (~/.bashrc) rely on it. It’s also the standard shell in many Docker images and widely adopted for CI/CD pipelines.
Bash extends sh with features like arrays, [[...]] tests, arithmetic expansion, and process substitution. Ideal for moderate automation and daily command-line use.
#!/usr/bin/env bash
fruits=(apple banana cherry)for fruit in "${fruits[@]}";doecho"$fruit"done
Paul Falstad developed Zsh around 1990, naming it after a Yale professor’s login ID. Zsh merged ideas from KornShell, C shell, and sh, eventually evolving into a highly customizable, feature-rich shell. Zsh became the default on macOS starting with Catalina and is also default on Kali Linux.
Zsh is praised for interactive use, with many frameworks like Oh My Zsh and Prezto. It also can handle scripting, largely compatible with Bash. Developers often choose Zsh for advanced tab completion, theming, and plugin ecosystems.
Zsh supports advanced glob qualifiers, theming, spelling corrections, and can emulate POSIX or sh if desired. Scripting can employ extended features or remain portable.
Axel Liljencrantz first released Fish in 2005, aiming for a modern, user-friendly shell free from historical POSIX constraints. Fish is open-source (GPL) and developed by a dedicated community, embracing simplicity and discoverability over strict backward compatibility.
Fish is mainly an interactive shell that provides autosuggestions, syntax highlighting, and convenient defaults. It’s not intended for system scripting but can be used if all target environments have Fish installed. Developers enjoy its user-centric features for daily command-line tasks.
Fish excels interactively, providing colored prompts, advanced tab completion, and no subshell forks in pipelines. Configuration typically resides in ~/.config/fish/config.fish. Its scripting uses straightforward commands: set for variables, function ... end for functions.
# Fish example:set greeting "Hello from Fish!"echo$greetingfunction say_hi
echo"This is a fish function"end
say_hi
John Wiegley created Eshell in the late 1990s. Entirely written in Emacs Lisp, it’s bundled with GNU Emacs. Eshell aims to provide a shell-like environment within Emacs, working consistently across Windows, macOS, and Linux.
Eshell is used from inside Emacs, letting developers run commands, manipulate files, and even work with remote directories via Tramp. It’s purely an interactive tool rather than a standalone system shell; you cannot ssh directly into Eshell.
Eshell runs external commands or built-in Lisp versions of commands like ls, grep, etc. It supports pipes, redirection, and mixing Emacs Lisp expressions inline. Output appears in an Emacs buffer, making it straightforward to copy, edit, or search results. Remote directories work seamlessly with Tramp.
;; Example Eshell usage:
echo"Home: $HOME"(message "Hello from Emacs Lisp!")find-file ~/notes.org