david alfonso

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

Resources

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.

Shells

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.

Tooling

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.

checkbashisms

Examples

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:

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).


  1. https://en.wikipedia.org/wiki/POSIX 

  2. bashism: "a shell feature that is not required to be supported by POSIX".