Bash (Bourne Again SHell) is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell. It is widely used as the default login shell for most Linux distributions and Apples macOS.
Bash Anti-Patterns Overview
Not Quoting Variables
Using ls in Scripts
ls
in scripts. It can break when filenames contain spaces, newlines, or other special characters. Use shell globbing, find
, or other more robust methods instead.Not Checking Command Exit Status
set -e
option to exit on any error, or combine both approaches for more robust error handling.Using eval
eval
whenever possible, especially with user input. It can lead to code injection vulnerabilities. If you must use it, validate input strictly and consider alternatives like case statements or function dispatching.Command Injection Vulnerabilities
--
to indicate the end of options when available, and consider using printf %q
to properly quote arguments for commands that don’t support --
.Using Backticks Instead of $()
$()
for command substitution instead of backticks. It’s more readable, especially when nested, and more consistent with other shell constructs.Not Setting IFS When Reading Lines
IFS=
(empty) and use the -r
flag with read
to prevent backslash interpretation. This preserves leading and trailing whitespace and handles backslashes correctly.Using /bin/sh for Bash Scripts
#!/bin/bash
as the shebang, not #!/bin/sh
. On many systems, /bin/sh
might be a different shell (like dash) that doesn’t support Bash features.Not Using set -u
set -u
(or set -o nounset
) to make your script exit when it tries to use an undefined variable. This helps catch typos and missing variables early.Not Using set -e
set -e
(or set -o errexit
) to make your script exit immediately if any command fails. This prevents the script from continuing in an unexpected state after an error.Not Using Shellcheck
Using [ ] Instead of [[ ]]
[[ ]]
instead of [ ]
for conditional tests in Bash. It’s more powerful, safer with empty variables, supports logical operators directly, and provides pattern matching.Hardcoding Paths
Not Using Functions
Using echo for Printing to stderr
printf
instead of echo
for more consistent behavior across different systems, especially when printing to stderr or when dealing with strings that start with options like -n
or -e
.Using Uppercase Variable Names
Not Using Local Variables in Functions
local
to declare function-specific variables. This prevents unintended side effects and makes functions more self-contained and reusable.Using Temporary Files Insecurely
mktemp
to create secure temporary files with unique names. Add a trap to clean up temporary files when the script exits, even if it exits due to an error.Not Using Double Brackets for Regex
[[ ]]
with the =~
operator for regular expression matching. Single brackets [ ]
only support glob patterns, not regular expressions.Not Using Proper Shebang
#!/usr/bin/env bash
is more portable than #!/bin/bash
because it will find the Bash interpreter in the user’s PATH.Using Deprecated Syntax
$[...]
for arithmetic expansion. Use the modern equivalents like $((...))
instead.Not Using Parameter Expansion