Skip to content

Shell scripting: the reading list

Level: reference · for anyone whose text pipeline is a script

One line: The shell is the language most of this library's examples are written in and the only one here with no string type at all, so the material that teaches it well is the material that teaches it as glue between byte-processing programs — and the two resources that matter most are a wiki and a linter, not books.

Every link on this page was fetched on 2026-09-13 (GET, following redirects). Two publishers refuse an automated request with 403 — O'Reilly, as RESOURCES.md already notes, and gnu.org's manual pages — so their books link to Open Library and their manuals are named rather than linked; both open normally in a browser.

Start with these three, in this order

What it gives you
BashGuide ↗ — Maarten Billemont, on Greg Wooledge's wiki The one tutorial that teaches quoting first and everything else after it, which is the right order for a language where an unquoted $var is re-parsed into words and globs before any command sees it. Read it before any book below.
BashPitfalls ↗ Sixty-odd numbered mistakes, each with the wrong line, the right line, and why. Number 1 is for f in $(ls *.mp3), and most of the list is the same mistake — treating a stream of bytes as a list of words — in different clothes.
ShellCheck ↗ — Vidar Holen The linter. brew install shellcheck or apt install shellcheck, then run it on every script you own; every warning links to a wiki page ↗ that explains the failure it prevents. It catches the pitfalls above mechanically, and it knows which constructs are bash-only in a #!/bin/sh file.

Then the BashFAQ ↗, which is the same wiki's answers to the questions people actually ask — how do I read a file line by line, how do I handle filenames with spaces — and its entry 105 ↗, on why set -e does not do what you expect, which is the one to read before putting that line at the top of a script.

Books

The shell as a language for text

bash specifically

The command line around the script

sed and awk, which are half of every script

The references you will actually open

What it is
POSIX.1-2024, Shell Command Language ↗ The specification. Section 2.2 is quoting and 2.6 is word expansion, in the order the shell performs them — the two pages that settle every "why did it split there" argument. What it promises is what runs under both shs this library measures.
GNU Bash Reference Manualinfo bash, or the copy on gnu.org Everything bash adds to the specification above, and help <builtin> at the prompt for the same text one command at a time.
explainshell ↗ Paste a command line; it splits it into the flags of each program and quotes the man page for each. The fastest way to read a one-liner somebody else wrote.
Rich Felker, Rich's sh (POSIX shell) tricks One page by the author of musl on doing things portably in sh that people believe need bash — reading a line, handling arbitrary filenames, printf as the only safe echo. The portable spellings this library's printf page reaches the same way.
Google Shell Style Guide ↗ A house style with reasons, and one opinion worth taking even if you take no other: a script that grows past a hundred lines should be rewritten in a language with a string type.
Bash Hackers Wiki ↗ The other wiki: parameter expansion, the parser, and the printf builtin in more detail than the manual. This is a mirror; the original domain lapsed in 2023.
The Bash Guide ↗ Billemont's newer, unfinished rewrite of BashGuide. The finished chapters are the best introduction to how bash parses a line, which is the thing the pitfalls are made of.
The Art of Command Line ↗ One long page of idioms, from basics to one-liners, with a section on macOS-only and Windows-only differences.

Courses, for somebody starting from nothing

Tools that read your script

Tool What it finds
ShellCheck ↗ Above. The one to install first.
shfmt ↗ — Daniel Martí A formatter and a parser for POSIX shell and bash; shfmt -d diffs your script against a canonical layout, and the parser behind it is what several editors use for shell syntax.
checkbashisms ↗ — Debian devscripts Reports bash-only constructs in a script that claims #!/bin/sh. That claim is not idle: /bin/sh is bash 3.2 on a Mac and dash on Ubuntu, and The shell has no string type measures three things the two answer differently for the same script.
bash -n script Parses without running. Catches an unclosed quote; catches nothing about what the quotes mean.

Read with care

  • Mendel Cooper, Advanced Bash-Scripting Guide. The most-linked bash document on the web, and the one BashGuide was written in reaction to: it is encyclopaedic, and its examples teach the exact habits BashPitfalls lists — unquoted expansions, parsing ls, echo where printf was needed. Use it as an index of what exists, never as a model of how to write it.
  • Any list of "useful one-liners". They assume GNU tools almost without exception, and the forty-three platform differences CONTRIBUTING.md has collected are the ways those one-liners fail on a Mac — sed -i without a suffix, xargs -a, base64 -w, split -C. Run each through the tool's page in 11_Tools before trusting it on both platforms.

Where this library already covers it

The shell's own behaviour with text is a lesson here rather than a resource, and the tools a script is made of have a page each:

See also

  • RESOURCES.md — the main reading list, of which this page is the shell shelf
  • 11_Tools — the toolbox those scripts call, and the three questions to ask of any tool in it
  • 06_Terminal — the tools whose job is bytes