Difference between single and double quotes in Bash

Viewed 358772

In Bash, what are the differences between single quotes ('') and double quotes ("")?

7 Answers

Others explained it very well, and I just want to give something with simple examples.

Single quotes can be used around text to prevent the shell from interpreting any special characters. Dollar signs, spaces, ampersands, asterisks and other special characters are all ignored when enclosed within single quotes.

echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'

It will give this:

All sorts of things are ignored in single quotes, like $ & * ; |.

The only thing that cannot be put within single quotes is a single quote.

Double quotes act similarly to single quotes, except double quotes still allow the shell to interpret dollar signs, back quotes and backslashes. It is already known that backslashes prevent a single special character from being interpreted. This can be useful within double quotes if a dollar sign needs to be used as text instead of for a variable. It also allows double quotes to be escaped so they are not interpreted as the end of a quoted string.

echo "Here's how we can use single ' and double \" quotes within double quotes"

It will give this:

Here's how we can use single ' and double " quotes within double quotes

It may also be noticed that the apostrophe, which would otherwise be interpreted as the beginning of a quoted string, is ignored within double quotes. Variables, however, are interpreted and substituted with their values within double quotes.

echo "The current Oracle SID is $ORACLE_SID"

It will give this:

The current Oracle SID is test

Back quotes are wholly unlike single or double quotes. Instead of being used to prevent the interpretation of special characters, back quotes actually force the execution of the commands they enclose. After the enclosed commands are executed, their output is substituted in place of the back quotes in the original line. This will be clearer with an example.

today=`date '+%A, %B %d, %Y'`
echo $today

It will give this:

Monday, September 28, 2015

There is a clear distinction between the usage of ' ' and " ".

When ' ' is used around anything, there is no "transformation or translation" done. It is printed as it is.

With " ", whatever it surrounds, is "translated or transformed" into its value.

By translation/ transformation I mean the following: Anything within the single quotes will not be "translated" to their values. They will be taken as they are inside quotes. Example: a=23, then echo '$a' will produce $a on standard output. Whereas echo "$a" will produce 23 on standard output.

Since this is the de facto answer when dealing with quotes in Bash, I'll add upon one more point missed in the answers above, when dealing with the arithmetic operators in the shell.

The Bash shell supports two ways to do arithmetic operation, one defined by the built-in let command and the other the $((..)) operator. The former evaluates an arithmetic expression while the latter is more of a compound statement.

It is important to understand that the arithmetic expression used with let undergoes word-splitting, pathname expansion just like any other shell commands. So proper quoting and escaping need to be done.

See this example when using let:

let 'foo = 2 + 1'
echo $foo
3

Using single quotes here is absolutely fine here, as there isn't any need for variable expansions here. Consider a case of

bar=1
let 'foo = $bar + 1'

It would fail miserably, as the $bar under single quotes would not expand and needs to be double-quoted as

let 'foo = '"$bar"' + 1'

This should be one of the reasons, the $((..)) should always be considered over using let. Because inside it, the contents aren't subject to word-splitting. The previous example using let can be simply written as

(( bar=1, foo = bar + 1 ))

Always remember to use $((..)) without single quotes

Though the $((..)) can be used with double quotes, there isn't any purpose to it as the result of it cannot contain content that would need the double quote. Just ensure it is not single quoted.

printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2

Maybe in some special cases of using the $((..)) operator inside a single quoted string, you need to interpolate quotes in a way that the operator either is left unquoted or under double quotes. E.g., consider a case, when you are tying to use the operator inside a curl statement to pass a counter every time a request is made, do

curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'

Notice the use of nested double quotes inside, without which the literal string $((reqcnt++)) is passed to the requestCounter field.

A minimal answer is needed for people to get going without spending a lot of time as I had to.

The following is, surprisingly (to those looking for an answer), a complete command:

$ echo '\'

whose output is:

\

Backslashes, surprisingly to even long-time users of bash, do not have any meaning inside single quotes. Nor does anything else.

Related