Chapter 5. Quoting

Quoting means just that, bracketing a string in quotes. This has the effect of protecting special characters in the string from reinterpretation or expansion by the shell or shell script. (A character is "special" if it has an interpretation other than its literal meaning. For example, the asterisk * represents a wild card character in globbing and Regular Expressions).

 bash$ ls -l [Vv]*
 -rw-rw-r--    1 bozo  bozo       324 Apr  2 15:05 VIEWDATA.BAT
 -rw-rw-r--    1 bozo  bozo       507 May  4 14:25 vartrace.sh
 -rw-rw-r--    1 bozo  bozo       539 Apr 14 17:11 viewdata.sh
 
 bash$ ls -l '[Vv]*'
 ls: [Vv]*: No such file or directory

Certain programs and utilities reinterpret or expand special characters in a quoted string. An important use of quoting is protecting a command-line parameter from the shell, but still letting the calling program expand it.

 bash$ grep '[Ff]irst' *.txt
 file1.txt:This is the first line of file1.txt.
 file2.txt:This is the First line of file2.txt.

Note that the unquoted grep [Ff]irst *.txt works under the Bash shell. [1]

Quoting can also suppress echo's "appetite" for newlines.

 bash$ echo $(ls -l)
 total 8 -rw-rw-r-- 1 bo bo 13 Aug 21 12:57 t.sh -rw-rw-r-- 1 bo bo 78 Aug 21 12:57 u.sh
 
 
 bash$ echo "$(ls -l)"
 total 8
 -rw-rw-r--  1 bo bo  13 Aug 21 12:57 t.sh
 -rw-rw-r--  1 bo bo  78 Aug 21 12:57 u.sh

5.1. Quoting Variables

When referencing a variable, it is generally advisable to enclose its name in double quotes. This prevents reinterpretation of all special characters within the quoted string -- except $, ` (backquote), and \ (escape). [2] Keeping $ as a special character within double quotes permits referencing a quoted variable ("$variable"), that is, replacing the variable with its value (see Example 4-1, above).

Use double quotes to prevent word splitting. [3] An argument enclosed in double quotes presents itself as a single word, even if it contains whitespace separators.

   1 List="one two three"
   2 
   3 for a in $List     # Splits the variable in parts at whitespace.
   4 do
   5   echo "$a"
   6 done
   7 # one
   8 # two
   9 # three
  10 
  11 echo "---"
  12 
  13 for a in "$List"   # Preserves whitespace in a single variable.
  14 do #     ^     ^
  15   echo "$a"
  16 done
  17 # one two three

A more elaborate example:

   1 variable1="a variable containing five words"
   2 COMMAND This is $variable1    # Executes COMMAND with 7 arguments:
   3 # "This" "is" "a" "variable" "containing" "five" "words"
   4 
   5 COMMAND "This is $variable1"  # Executes COMMAND with 1 argument:
   6 # "This is a variable containing five words"
   7 
   8 
   9 variable2=""    # Empty.
  10 
  11 COMMAND $variable2 $variable2 $variable2
  12                 # Executes COMMAND with no arguments. 
  13 COMMAND "$variable2" "$variable2" "$variable2"
  14                 # Executes COMMAND with 3 empty arguments. 
  15 COMMAND "$variable2 $variable2 $variable2"
  16                 # Executes COMMAND with 1 argument (2 spaces). 
  17 
  18 # Thanks, Stéphane Chazelas.

Tip

Enclosing the arguments to an echo statement in double quotes is necessary only when word splitting or preservation of whitespace is an issue.


Example 5-1. Echoing Weird Variables

   1 #!/bin/bash
   2 # weirdvars.sh: Echoing weird variables.
   3 
   4 echo
   5 
   6 var="'(]\\{}\$\""
   7 echo $var        # '(]\{}$"
   8 echo "$var"      # '(]\{}$"     Doesn't make a difference.
   9 
  10 echo
  11 
  12 IFS='\'
  13 echo $var        # '(] {}$"     \ converted to space. Why?
  14 echo "$var"      # '(]\{}$"
  15 
  16 # Examples above supplied by Stephane Chazelas.
  17 
  18 echo
  19 
  20 var2="\\\\\""
  21 echo $var2       #   "
  22 echo "$var2"     # \\"
  23 echo
  24 # But ... var2="\\\\"" is illegal. Why?
  25 var3='\\\\'
  26 echo "$var3"     # \\\\
  27 # Strong quoting works, though.
  28 
  29 
  30 # ************************************************************ #
  31 # As the first example above shows, nesting quotes is permitted.
  32 
  33 echo "$(echo '"')"           # "
  34 #    ^           ^
  35 
  36 
  37 # At times this comes in useful.
  38 
  39 var1="Two bits"
  40 echo "\$var1 = "$var1""      # $var1 = Two bits
  41 #    ^                ^
  42 
  43 # Or, as Chris Hiestand points out ...
  44 
  45 if [[ "$(du "$My_File1")" -gt "$(du "$My_File2")" ]]
  46 #     ^     ^         ^ ^     ^     ^         ^ ^
  47 then
  48   ...
  49 fi
  50 # ************************************************************ #

Single quotes (' ') operate similarly to double quotes, but do not permit referencing variables, since the special meaning of $ is turned off. Within single quotes, every special character except ' gets interpreted literally. Consider single quotes ("full quoting") to be a stricter method of quoting than double quotes ("partial quoting").

Note

Since even the escape character (\) gets a literal interpretation within single quotes, trying to enclose a single quote within single quotes will not yield the expected result.
   1 echo "Why can't I write 's between single quotes"
   2 
   3 echo
   4 
   5 # The roundabout method.
   6 echo 'Why can'\''t I write '"'"'s between single quotes'
   7 #    |-------|  |----------|   |-----------------------|
   8 # Three single-quoted strings, with escaped and quoted single quotes between.
   9 
  10 # This example courtesy of Stéphane Chazelas.

Notes

[1]

Unless there is a file named first in the current working directory. Yet another reason to quote. (Thank you, Harald Koenig, for pointing this out.

[2]

Encapsulating "!" within double quotes gives an error when used from the command line. This is interpreted as a history command. Within a script, though, this problem does not occur, since the Bash history mechanism is disabled then.

Of more concern is the apparently inconsistent behavior of \ within double quotes, and especially following an echo -e command.

 bash$ echo hello\!
 hello!
 bash$ echo "hello\!"
 hello\!
 
 
 bash$ echo \
 >
 bash$ echo "\"
 >
 bash$ echo \a
 a
 bash$ echo "\a"
 \a
 
 
 bash$ echo x\ty
 xty
 bash$ echo "x\ty"
 x\ty
 
 bash$ echo -e x\ty
 xty
 bash$ echo -e "x\ty"
 x       y
 	      

Double quotes following an echo sometimes escape \. Moreover, the -e option to echo causes the "\t" to be interpreted as a tab.

(Thank you, Wayne Pollock, for pointing this out, and Geoff Lee and Daniel Barclay for explaining it.)

[3]

"Word splitting," in this context, means dividing a character string into separate and discrete arguments.