[The Definitive Guide] 5 Bash Patterns to Learn and How to Avoid Mistakes
In our Bash introduction series so far, you've built up the fundamental skills for wielding the black screen, from basic commands to creating simple scripts. You've probably started to feel how much easier your daily tasks have become by combining commands. Great work!
Now, to conclude our Bash series, this time we'll take it a step further. We'll show you how to level up from a script that "just works" to one that is "safe, readable, and less prone to errors"โa professional script. We'll impart 5 particularly important patterns and teach you how to avoid common "pitfalls" for beginners.
What we're about to introduce aren't new, difficult commands. It's about "how to use" the knowledge you've already learned correctlyโtips for driving, so to speak. Just as a new driver learns techniques to drive safely on rainy days or dark roads, with today's article, you too will master how to write scripts that you can run with confidence in any situation!
Pattern 1: Always Enclose Variables in "Double Quotes"!
This is the absolute golden rule in Bash scripting. Neglecting to enclose variables in double quotes " " is the biggest cause of unexpected errors. The problem becomes especially apparent when a variable contains spaces.
A Common Mistake: Unquoted Variables
For example, let's look at the following script that tries to create a directory with a space in its name.
#!/bin/bash
DIR_NAME="My Project"
mkdir $DIR_NAME
When you run this script, Bash interprets it as the command mkdir My Project, which results in two separate directories named "My" and "Project" being created. This is not the intended outcome.
Best Practice: Enclose Variables in " "
To solve this problem, you just need to enclose the variable in double quotes. This makes Bash correctly recognize the entire string, including the space, as a "single unit."
#!/bin/bash
DIR_NAME="My Project"
mkdir "$DIR_NAME" # Enclose the variable in double quotes!
echo "Directory '$DIR_NAME' created."
This simple habit will make your scripts far more robust. Engrave this in your mind: "Always enclose your variables in double quotes."
Pattern 2: Fail-Safe Design that Stops Immediately on Error
The scary thing about Bash scripts is that they will continue to execute subsequent commands without a second thought, even if a command in the middle fails. For example, what would happen in a script that is supposed to "move to a directory, then delete a file inside it" if the move command fails? You could end up with a disaster where a file is deleted in an unintended location.
To prevent this, write the following magic spell at the beginning of your script.
set -e
set -e is a "safety switch" that immediately stops the execution of the script if any command run within it fails. Let's see its effect in the following script.
#!/bin/bash
set -e # Turn on the safety switch
echo "Starting process..."
# Attempt to move to a non-existent directory, which will cause an error here
cd /non-existent-directory
# Because of set -e, this line will never be executed
echo "This message will not be displayed."
When you run this script, the process will stop the moment the cd command fails, and the final echo will not be executed. Make it a habit to include this line in any script that performs important operations.
Pattern 3: Putting the Result of a Command into a Variable
When you're writing scripts, you'll frequently encounter situations where you want to "use the 'result' of a command in another command or variable." For example, you might want to include today's date in a backup filename.
For this, we use a feature called Command Substitution. The syntax is $(command).
#!/bin/bash
set -e
# Get today's date in YYYY-MM-DD format and store it in a variable
TODAY=$(date "+%Y-%m-%d")
# Incorporate the date into the filename
BACKUP_FILENAME="backup_${TODAY}.tar.gz"
echo "Backup filename: $BACKUP_FILENAME"
# tar -czf "$BACKUP_FILENAME" /path/to/backup/source
The $(date "+%Y-%m-%d") part is replaced by the execution result of the date command (e.g., 2025-07-06). This allows you to easily generate dynamic and descriptive filenames.
Pattern 4: Safely Processing Files Line by Line
Reading a text file (a list of domains, a list of URLs, etc.) and performing some action for each line is a typical use case for a script. However, this process has a "pitfall" that beginners often fall into.
A Common Bad Pattern
A syntax like for line in $(cat file.txt) should be avoided because it cannot correctly handle cases where a file contains spaces.
The Safe Best Practice: The `while read` loop
The standard pattern for safely and efficiently processing a file line by line is the while read loop. It might look a bit complicated, but the best approach is to memorize it in this form.
First, let's prepare a list file to process, `domains.txt`.
example.com
example.net
example.org
Next, here is the script that reads this file and processes it.
#!/bin/bash
set -e
INPUT_FILE="domains.txt"
while IFS= read -r line
do
echo "Processing domain: $line"
# You would perform actions like ping "$line" or curl "http://$line/" here
done < "$INPUT_FILE"
This syntax can be applied to processing any text file because it preserves leading and trailing spaces in a line and correctly handles special characters.
Pattern 5: Securely Creating and Deleting Temporary Files
In the middle of a script's execution, you may need a temporary file for work. In this case, hardcoding a filename like /tmp/my_temp_file is dangerous. If another program is using a file with the same name, or if multiple instances of the script are run at the same time, the file could be overwritten.
To safely create a temporary file, use the mktemp command. This creates an empty file with a unique name that won't conflict with anything else.
#!/bin/bash
set -e
# Create a safe temporary file and store its name in a variable
TEMP_FILE=$(mktemp)
# Always remove the temporary file when the script exits (on success, error, or interrupt)
trap 'rm -f "$TEMP_FILE"' EXIT
echo "Created temporary file: $TEMP_FILE"
echo "Writing data to this file..."
echo "some temporary data" > "$TEMP_FILE"
echo "File contents:"
cat "$TEMP_FILE"
echo "Process complete. The temporary file will be deleted automatically."
Furthermore, by combining it with the trap command, you can reserve a cleanup action to "always delete this temporary file at the end, no matter why the script exits." This prevents unnecessary junk files from being left on the server.
Conclusion
Great work! This concludes our Bash introduction series. In this final installment, you learned 5 important patterns to elevate your scripts from "toys" to "professional tools."
- ๐ก๏ธ Always enclose variables in
" ": The most basic of basics to prevent malfunctions due to spaces. - ๐จ Stop immediately on error with
set -e: A safety switch to prevent unexpected accidents. - ๐ Utilize command results with
$(command): A powerful weapon to achieve dynamic processing. - ๐ Process files line by line with
while read: The standard for safe and reliable file reading. - ๐๏ธ Flawless cleanup with
mktempandtrap: The professional way to handle temporary files safely.
Just by being conscious of these patterns, the scripts you write will become significantly more reliable and maintainable, making them easy for your future self or others to read. Please make use of them in your future script creation. We sincerely hope that your web development life, now armed with the powerful tool of Bash, will become even more creative and efficient!