Published at
Updated at
Reading time

If you ever tried to write a good-looking but also well functioning and safe shell script, you know that this is not a trivial task. Unfortunately, most of the shells out there (and bash is no exception) make it hard to do things the right way. Or rephrased in plain English – most shells make it easy to do the wrong things.

People coming from languages like JavaScript have to worry about the unfamiliar syntax and the fact that things like conditions, loops, and other straightforward principles become a journey of copying snippets from Stack Overflow.

Suppose you're like me and want to get into shell scripting, do yourself one favor first. Please have a look at ShellCheck. Someone recommended me this tool last year at a hackathon, and it's golden. ShellCheck is an online tool (but can also come as an editor extension) that analyzes your shell scripts and tells you what's wrong. The tool gives you many resources and possible improvements. By looking at ShellCheck and implementing its advice, your scripts get at least one level better, if not two!

ShellCheck screenshot

Today, I came across Bash pitfalls. It's an incredible useful bag of 59 common bash mistakes and how to do better. This page is one for the bookmarks! Let me share my "favorites".

Never forget the double-quotes when using variables

Rule number one when writing shell scripts – quote your variables. After using ShellCheck for several months now, I can say that I rarely make this particular mistake anymore.

Variables without quotes can behave differently than you might expect.

Let me show you only one example where missing quotes bite you.

headline="* Headline *"                 
echo $headline   # "dir1 dir2 dir3 Headline dir1 dir2 dir3"
                 # ☝️ echos everything matching the "*" glob pattern

echo "$headline" # "* Headline *"
                 # ☝️ works as expected

Variables that include spaces or globbing patterns can result in unexpected expansion.

This behavior not only applies to echo. Have a look at the following copy command without variable quotes: cp $file $target. If $file or $target include certain characters, it will break and go south, too.

Rule number one, forever and ever – use quotes when dealing with variables in bash.

Why you shouldn't use echo in the first place

I wasn't aware of the next behavior on this list. What happens if a variable includes -n and you want to echo it out?

$ var="-n hello world"
$ echo $var
hello world$ # whoops?! What's this?

echo considers options in variables. 😲 The included -n option leads to the command not printing a trailing newline character. The safe way to print is to use printf.

var="-n hello world"
printf "%s\n" "$var" # print a passed-in string followed by \n

Using printf, you can strictly define how variables should be printed by defining placeholders (%s is a string placeholder). Go for printf to avoid surprises.

How to check for successful directory navigation

If you're navigating the file system in your shell command using cd, you should make sure the navigations succeeded before moving on. For example, if you're planning to remove some caching files, you want to be sure that you're in the correct directory before running anything related to file removal.

The safe way to approach navigations is to always check for success:

# run a single command only after successful navigation
cd /some-dir && some-command

# run multiple commands after navigation
# exit if the navigation was not successful
cd /some-dir || exit 1

And these are only three tips when writing bash scripts. Read all the 59 Bash Pitfalls online and improve your bash scripts. ✌️

Was this post helpful?
Yes? Cool! You might want to check out Web Weekly for more WebDev shenanigans. The last edition went out 4 days ago.
Stefan standing in the park in front of a green background

About Stefan Judis

Frontend nerd with over ten years of experience, freelance dev, "Today I Learned" blogger, conference speaker, and Open Source maintainer.

Related Topics

Related Articles