← All Articles

Bash Bonanza: Quoting and Escaping Part 2

Dimitrios LisenkoDimitrios Lisenko
Jun 14th 17Updated Jul 7th 22

Bash Bonanza: Quoting and Escaping

Welcome to the second part of the Bash Bonanza series!

We previously looked at the single quotes in bash as being the safe option for strings, as everything inside the quotes is a literal character. The only exception is the single quote itself, which will close the string - fortunately there is a workaround, which we also had a look at.

So now let's say that you're happily bashing along, when suddenly, you need to refer to a previously defined variable.

Naturally, you open man bash, and read that this is done by surrounding the variable name in curly braces and prepending a dollar sign - ${variable_name} - and is called parameter expansion.

The braces are optional, but I use them as a matter of habit because they protect the variable name from other characters, and also offer some additional functionality, which you will need once you start using bash arrays - stay tuned!

Unfortunately, fellow basher of heads against the keyboard , you have just opened a can of worms!

For example, let's say you do the following.

$ variable_with_spaces='hello world!'
$ printf '%s\n' ${variable_with_spaces}
hello
world!

As you can see, instead of passing a single argument to printf: hello world!, we have actually passed two arguments to printf: hello and world!.

This happens because, like the name parameter expansion suggests, printf ${variable_name} does NOT tell bash to pass the variable referred to by variable_name as an argument to printf. Instead it tells bash to first expand, or substitute the value of the variable in place, and then pass the result as arguments to printf.

$ printf '%s\n' ${variable_with_spaces}
# IS EQUIVALENT TO
$ printf '%s\n' hello world!

This can actually be incredibly dangerous, as shown in the following example.

$ ls
file_one file_two
$ x='* is my favourite character'
$ printf '%s\n' ${x}
file_one
file_two
is
my
favourite
character

In order for bash to parse variable_name as a single argument with the literal value, you will need to surround the parameter expansion in quotes, just as you would normally for a string. However, recall that single quotes won't work - the literal value of the dollar sign will be used.

Enter the double quotes, which will retain the special properties of the dollar sign, including parameter expansion.

Hence, I present to you the way I use parameter expansion when working with bash.

$ variable_with_spaces='hello world!'
$ printf '%s\n' "${variable_with_spaces}"
hello world!
$ x='* is my favourite character'
$ printf '%s\n' "${x}"
* is my favourite character

Also recall from the previous part of the series that when strings are next to each other in bash, regardless of quote type, they are parsed as a single argument.

As such my preference is to use double quotes only for parameter expansion and other expansions that I am absolutely certain of, and single quotes for the rest. A fairly contrived example follows.

$ sentence='The value of the product is: '
$ printf '%s\n' "${sentence}"'$100.'
The value of the product is: $100.

This covers the absolute basics of quoting and escaping in bash! Armed with this knowledge, we can start exploring more advanced functionality in future parts of this series.


Try Cloud 66 for Free, No credit card required