The Shell
The shell starts processes, connects their input and output, and expands command arguments. This page uses Bash; other shells differ.
Expansion order
Bash performs parameter and command expansion before word splitting and filename expansion. Quote variables as "$var" to keep spaces and wildcard characters from changing the arguments.
Use "$@" to forward arguments separately. "$*" joins them into one string. ${var:-default} supplies a fallback; ${var:?message} reports a missing value.
File descriptors
Standard input, output and error use descriptors 0, 1 and 2. Redirections apply from left to right:
cmd >file 2>&1sends output and errors to the file.cmd 2>&1 >filesends errors to the original output destination.
Process substitution, such as diff <(sort a) <(sort b), lets a command read another command's output as a file. Quote a here-document delimiter to keep its contents literal.
Processes, groups and signals
Ctrl-C sends SIGINT to the foreground process group. A background job may receive SIGHUP when its shell exits. Use a terminal multiplexer or a supervised service for work that must survive disconnection.
trap handles selected signals. An EXIT trap can clean up temporary files on shell exit, but it cannot handle SIGKILL.
Job control and background work
& starts a background job. jobs, fg and bg manage jobs in the current shell; wait collects their exit status.
For parallel commands, xargs -P is often enough. Pair find -print0 with xargs -0 to handle unusual filenames.
Writing scripts that fail properly
set -u catches unset variables. set -o pipefail makes a pipeline fail when one of its commands fails. set -e has exceptions, so check failures explicitly where they matter.
Use ShellCheck to catch quoting and portability mistakes. Move to another language when the script needs complex data structures.
Finding your way around
pwd shows the current directory. Relative paths start there; absolute paths start at the filesystem root. cd - returns to the previous directory. Tab completion reduces typing and catches misspelled paths.
Use command -v to find the command your shell will run. Different installations can put different versions earlier in PATH. A command that works in your terminal may fail in a service with a different environment.
Searching and inspecting
Use rg to search file contents and rg --files to list files. less handles long output without losing your place. head and tail show the beginning and end; tail -f follows a growing file.
Text tools work best on text with predictable separators. Use a JSON-aware tool for JSON, rather than depending on its indentation or key order.
Exit status and filenames
An exit status of zero conventionally means success. Some tools use nonzero statuses for ordinary outcomes, such as finding no matches. Read their documentation before treating every nonzero result as an error.
Use -- where supported to end option parsing when a filename starts with a dash. Avoid splitting filenames on spaces or newlines. Inspect the destination before running a destructive command.