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, such as the wild card character, *.)

 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

Note

Certain programs and utilities can still reinterpret or expand special characters in a quoted string. This is an important use of quoting, 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, but not under tcsh.

When referencing a variable, it is generally advisable in enclose it in double quotes (" "). This preserves all special characters within the variable name, except $, ` (backquote), and \ (escape). [1] 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. [2] An argument enclosed in double quotes presents itself as a single word, even if it contains whitespace separators.
   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        # Executes COMMAND with no arguments. 
  12 COMMAND "$variable2" "$variable2" "$variable2"  # Executes COMMAND with 3 empty arguments. 
  13 COMMAND "$variable2 $variable2 $variable2"      # Executes COMMAND with 1 argument (2 spaces). 
  14 
  15 # Thanks, S.C.

Tip

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


Example 5-1. Echoing Weird Variables

   1 #!/bin/bash
   2 # weirdvars.sh: Echoing weird variables.
   3 
   4 var="'(]\\{}\$\""
   5 echo $var        # '(]\{}$"
   6 echo "$var"      # '(]\{}$"     Doesn't make a difference.
   7 
   8 echo
   9 
  10 IFS='\'
  11 echo $var        # '(] {}$"     \ converted to space.
  12 echo "$var"      # '(]\{}$"
  13 
  14 # Examples above supplied by S.C.
  15 
  16 exit 0

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 Stephane Chazelas.

Escaping is a method of quoting single characters. The escape (\) preceding a character tells the shell to interpret that character literally.

Caution

With certain commands and utilities, such as echo and sed, escaping a character may have the opposite effect - it can toggle on a special meaning for that character.

Special meanings of certain escaped characters

used with echo and sed

\n

means newline

\r

means return

\t

means tab

\v

means vertical tab

\b

means backspace

\a

means "alert" (beep or flash)

\0xx

translates to the octal ASCII equivalent of 0xx


Example 5-2. Escaped Characters

   1 #!/bin/bash
   2 # escaped.sh: escaped characters
   3 
   4 echo; echo
   5 
   6 echo "\v\v\v\v"      # Prints \v\v\v\v literally.
   7 # Use the -e option with 'echo' to print escaped characters.
   8 echo "============="
   9 echo "VERTICAL TABS"
  10 echo -e "\v\v\v\v"   # Prints 4 vertical tabs.
  11 echo "=============="
  12 
  13 echo "QUOTATION MARK"
  14 echo -e "\042"       # Prints " (quote, octal ASCII character 42).
  15 echo "=============="
  16 
  17 # The $'\X' construct makes the -e option unnecessary.
  18 echo; echo "NEWLINE AND BEEP"
  19 echo $'\n'           # Newline.
  20 echo $'\a'           # Alert (beep).
  21 
  22 echo "==============="
  23 echo "QUOTATION MARKS"
  24 # Version 2 and later of Bash permits using the $'\nnn' construct.
  25 # Note that in this case, '\nnn' is an octal value.
  26 echo $'\t \042 \t'   # Quote (") framed by tabs.
  27 
  28 # It also works with hexadecimal values, in an $'\xhhh' construct.
  29 echo $'\t \x22 \t'  # Quote (") framed by tabs.
  30 # Thank you, Greg Keraunen, for pointing this out.
  31 # Earlier Bash versions allowed '\x022'.
  32 echo "==============="
  33 echo
  34 
  35 
  36 # Assigning ASCII characters to a variable.
  37 # ----------------------------------------
  38 quote=$'\042'        # " assigned to a variable.
  39 echo "$quote This is a quoted string, $quote and this lies outside the quotes."
  40 
  41 echo
  42 
  43 # Concatenating ASCII chars in a variable.
  44 triple_underline=$'\137\137\137'  # 137 is octal ASCII code for '_'.
  45 echo "$triple_underline UNDERLINE $triple_underline"
  46 
  47 echo
  48 
  49 ABC=$'\101\102\103\010'           # 101, 102, 103 are octal A, B, C.
  50 echo $ABC
  51 
  52 echo; echo
  53 
  54 escape=$'\033'                    # 033 is octal for escape.
  55 echo "\"escape\" echoes as $escape"
  56 #                                   no visible output.
  57 
  58 echo; echo
  59 
  60 exit 0

See Example 35-1 for another example of the $' ' string expansion construct.

\"

gives the quote its literal meaning

   1 echo "Hello"                  # Hello
   2 echo "\"Hello\", he said."    # "Hello", he said.

\$

gives the dollar sign its literal meaning (variable name following \$ will not be referenced)

   1 echo "\$variable01"  # results in $variable01

\\

gives the backslash its literal meaning

   1 echo "\\"  # results in \

Note

The behavior of \ depends on whether it is itself escaped, quoted, or appearing within command substitution or a here document.
   1                       #  Simple escaping and quoting
   2 echo \z               #  z
   3 echo \\z              # \z
   4 echo '\z'             # \z
   5 echo '\\z'            # \\z
   6 echo "\z"             # \z
   7 echo "\\z"            # \z
   8 
   9                       #  Command substitution
  10 echo `echo \z`        #  z
  11 echo `echo \\z`       #  z
  12 echo `echo \\\z`      # \z
  13 echo `echo \\\\z`     # \z
  14 echo `echo \\\\\\z`   # \z
  15 echo `echo \\\\\\\z`  # \\z
  16 echo `echo "\z"`      # \z
  17 echo `echo "\\z"`     # \z
  18 
  19                       # Here document
  20 cat <<EOF              
  21 \z                      
  22 EOF                   # \z
  23 
  24 cat <<EOF              
  25 \\z                     
  26 EOF                   # \z
  27 
  28 # These examples supplied by Stephane Chazelas.

Elements of a string assigned to a variable may be escaped, but the escape character alone may not be assigned to a variable.
   1 variable=\
   2 echo "$variable"
   3 # Will not work - gives an error message:
   4 # test.sh: : command not found
   5 # A "naked" escape cannot safely be assigned to a variable.
   6 #
   7 #  What actually happens here is that the "\" escapes the newline and
   8 #+ the effect is        variable=echo "$variable"
   9 #+                      invalid variable assignment
  10 
  11 variable=\
  12 23skidoo
  13 echo "$variable"        #  23skidoo
  14                         #  This works, since the second line
  15                         #+ is a valid variable assignment.
  16 
  17 variable=\ 
  18 #        \^    escape followed by space
  19 echo "$variable"        # space
  20 
  21 variable=\\
  22 echo "$variable"        # \
  23 
  24 variable=\\\
  25 echo "$variable"
  26 # Will not work - gives an error message:
  27 # test.sh: \: command not found
  28 #
  29 #  First escape escapes second one, but the third one is left "naked",
  30 #+ with same result as first instance, above.
  31 
  32 variable=\\\\
  33 echo "$variable"        # \\
  34                         # Second and fourth escapes escaped.
  35                         # This is o.k.

Escaping a space can prevent word splitting in a command's argument list.
   1 file_list="/bin/cat /bin/gzip /bin/more /usr/bin/less /usr/bin/emacs-20.7"
   2 # List of files as argument(s) to a command.
   3 
   4 # Add two files to the list, and list all.
   5 ls -l /usr/X11R6/bin/xsetroot /sbin/dump $file_list
   6 
   7 echo "-------------------------------------------------------------------------"
   8 
   9 # What happens if we escape a couple of spaces?
  10 ls -l /usr/X11R6/bin/xsetroot\ /sbin/dump\ $file_list
  11 # Error: the first three files concatenated into a single argument to 'ls -l'
  12 #        because the two escaped spaces prevent argument (word) splitting.

The escape also provides a means of writing a multi-line command. Normally, each separate line constitutes a different command, but an escape at the end of a line escapes the newline character, and the command sequence continues on to the next line.

   1 (cd /source/directory && tar cf - . ) | \
   2 (cd /dest/directory && tar xpvf -)
   3 # Repeating Alan Cox's directory tree copy command,
   4 # but split into two lines for increased legibility.
   5 
   6 # As an alternative:
   7 tar cf - -C /source/directory . |
   8 tar xpvf - -C /dest/directory
   9 # See note below.
  10 # (Thanks, Stephane Chazelas.)

Note

If a script line ends with a |, a pipe character, then a \, an escape, is not strictly necessary. It is, however, good programming practice to always escape the end of a line of code that continues to the following line.

   1 echo "foo
   2 bar" 
   3 #foo
   4 #bar
   5 
   6 echo
   7 
   8 echo 'foo
   9 bar'    # No difference yet.
  10 #foo
  11 #bar
  12 
  13 echo
  14 
  15 echo foo\
  16 bar     # Newline escaped.
  17 #foobar
  18 
  19 echo
  20 
  21 echo "foo\
  22 bar"     # Same here, as \ still interpreted as escape within weak quotes.
  23 #foobar
  24 
  25 echo
  26 
  27 echo 'foo\
  28 bar'     # Escape character \ taken literally because of strong quoting.
  29 #foo\
  30 #bar
  31 
  32 # Examples suggested by Stephane Chazelas.

Notes

[1]

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

Of more concern is the inconsistent behavior of "\" within double quotes.
 bash$ echo hello\!
 hello!
 
 
 bash$ echo "hello\!"
 hello\!
 
 
 
 
 bash$ echo -e x\ty
 xty
 
 
 bash$ echo -e "x\ty"
 x       y
 	      
(Thank you, Wayne Pollock, for pointing this out.)

[2]

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