Strings

People often stumble when it comes to the various ways strings can be quoted in Bash. There are two characters which can be used for quoting in bash: " and '; each has its own time and place.

Review

Let’s review some key concepts of bash scripting that we’ve already seen so far to serve as a base for our discussion.

Command Line Arguments

When running the command

$ cp myfile.txt ../mydir

Bash receives two distinct arguments because we separated these arguments by spaces.

Problem: what if our filenames or arguments have spaces inside them?

Special Characters

There are a variety of characters which have special meaning in Bash. Some of these characters serve as signals that Bash should replace or expand text with some other text. These characters in particular are $, which is used for environment variables and command substitution, and `, which is used as an alternate form of $(...) ($(...) == `...`).

Problem: what if we need to include these characters as is, without having them turn into something else?

Quoting & Escaping

The way that bash handles strings, referred to as “quoting”, handles both of these problems. Additionally, certain special characters can be explicitly declared as “non-special”, i.e. they should be printed as is. This is called “escaping”.

Grouping Arguments with Spaces

You can pass a string containing a space as a single argument by enclosing that string in quotes. Both string characters (" and ') will perform this grouping:

# copies the files "my", "file", "with", "spaces.txt" to "../mydir"

$ cp my file with spaces.txt ../mydir

# copies a single file named "my file with spaces.txt" to "../mydir"

$ cp "my file with spaces.txt" ../mydir

# does the same thing as double quotes

$ cp 'my file with spaces.txt' ../mydir

Escaping

A similar result can be accomplished with escaping. Just the same as in a programming language like Java or Python, certain sequences starting with \ have a special meaning, and are referred to as “escape sequences”.

Sequence Meaning
\$ literal $
\" literal "
\' literal '
\` literal `
\\ literal \

For a more complete list, see here.

Example

# copies a single file named "my file with spaces.txt" to "../mydir"

$ cp my\ file\ with\ spaces.txt ../mydir

Single vs Double Quotes

As we’ve already seen, both single and double quotes let you group arguments with spaces. What’s the difference then?

From the bash manual:

Enclosing characters in single quotes (') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

Enclosing characters in double quotes (") preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !.

This means that strings enclosed in double quotes will still have variables expanded and command substitution performed.

Examples

$ export myVariable="Hello, world\!"

$ echo myVariable
myVariable

$ echo $myVariable
Hello, world!

$ echo "$myVariable"
Hello, world!

$ echo '$myVariable'
$myVariable

$ ls
myfile.txt

$ echo $(ls)
myfile.txt

$ echo "$(ls)"
myfile.txt

$ echo '$(ls)'
$(ls)
Copyright © 2014, Great Practical Ideas in Computer Science.