POSIX Shell Scripting
The Portable Operating System Interface (POSIX) family of standards are specified by the IEEE to maintain OS interoperability1.
The standardized user command line and scripting interface were based on the UNIX System V shell. But not only these are standardized, also are common utility programs.
POSIX.1-2008 combined most parts of previous POSIX standards into one. Latest revision is POSIX.1-2017
POSIX.1-2017 Specification with search box and frames
POSIX.1-2017 Rationale TOC (e.g. to be strictly POSIX compliant there must be NO #! at the beginning of the file)
The Shell Command Language Documentation
POSIX Utility Conventions: Naming of utilities, specification of options, option-arguments, and operands (The
getopt() function assists in this matter).
Shell Portability Guidelines: If scripts need to be portable, some of the BASH-specific syntax elements should be avoided. Others should be avoided for all scripts, e.g. if there is a corresponding POSIX®-compatible syntax.
Pure sh Bible: a collection of pure POSIX alternatives to external processes.
Evolution of Shells in Linux
Comparison of command shells
Hyperpolyglot: Unix Shells (bash, fish, ksh, tcsh, zsh)
Dash as default /bin/sh shell in Ubuntu: Dash is more efficient than Bash. For system scripts this matters. It was changed in Ubuntu 6.10 (long time ago). Includes a list of "bashisms"2. It was Ubuntu who migrated first to Dash, and then Debian decided to adopt it.
ash, the original Kenneth Almquist shell. It's a clone of the Bourne Shell to avoid licensing issues. It's the default shell in BusyBox.
dash: The Debian Almquist Shell is a modern POSIX-compliant implementation of
/bin/sh. It has a low memory footprint compared to Bash. It's used in Debian as the default non-interactive shell.
mrsh: a minimal POSIX shell.
shellcheck: a static analysis tool for shell scripts. Use
shellcheck -s sh (or if script starts with
#!/bin/sh) to check for POSIX and warn on portability issues.
ts(1) -- test script: ts provides functions for writing tests in shell. The test scripts can be run individually or in a batch format using ts as a command. ts makes a test directory available on a per-test basis so it's easy to sandbox tests that write or manipulate files. ts tries to use POSIX exclusively and so should (hopefully) work with any POSIX-compliant shell.
A shell script to demonstrate various POSIX features related to shell variables
KISS package manager: Tiny and straightforward package manager for KISS (a Linux distribution) written in 600 lines of POSIX sh. Related software. Script related guidestones:
- All shell code must be written in a safe way, pass the shellcheck linter and match the style of any existing code.
- All distribution tooling and shell code must be written in a portable way. Otherwise, the user will be locked into a single coreutils and shell.
- One exception is made for
sed -ias it is too useful to let go of. The
-iflag has rather good support across implementations regardless.
Static site generator (180LoC), written in shell.
RSS feed generator (148LoC), written in shell.
git-issue: Git-based decentralized issue management. Interesting shellchecks to support, e.g. local variables, which are not standard but supported by most modern shells.
asdf-vm: Extendable version manager. Supports many shells.
bashmarks: Save and jump to commonly used directories. Has tab completion embedded in the same script (zsh and bash).
bashism: "a shell feature that is not required to be supported by POSIX". ↩