Quoting
Double quotes for variable and command substitution
Section titled “Double quotes for variable and command substitution”Variable substitutions should only be used inside double quotes.
calculation='2 * 3'echo "$calculation" # prints 2 * 3echo $calculation # prints 2, the list of files in the current directory, and 3echo "$(($calculation))" # prints 6Outside of double quotes, $var takes the value of var, splits it into whitespace-delimited parts, and interprets each part as a glob (wildcard) pattern. Unless you want this behavior, always put $var inside double quotes: "$var".
The same applies to command substitutions: "$(mycommand)" is the output of mycommand, $(mycommand) is the result of split+glob on the output.
echo "$var" # goodecho "$(mycommand)" # goodanother=$var # also works, assignment is implicitly double-quotedmake -D THING=$var # BAD! This is not a bash assignment.make -D THING="$var" # goodmake -D "THING=$var" # also goodCommand substitutions get their own quoting contexts. Writing arbitrarily nested substitutions is easy because the parser will keep track of nesting depth instead of greedily searching for the first " character. The StackOverflow syntax highlighter parses this wrong, however. For example:
echo "formatted text: $(printf "a + b = %04d" "${c}")" # “formatted text: a + b = 0000”Variable arguments to a command substitution should be double-quoted inside the expansions as well:
echo "$(mycommand "$arg1" "$arg2")"Difference between double quote and single quote
Section titled “Difference between double quote and single quote”| Double quote | Single quote |
|---|---|
| Allows variable expansion | Prevents variable expansion |
| Allows history expansion if enabled | Prevents history expansion |
| Allows command substitution | Prevents command substitution |
* and @ can have special meaning | * and @ are always literals |
| Can contain both single quote or double quote | Single quote is not allowed inside single quote |
$, ```bash, ", \ can be escaped with \ to prevent their special meaning | All of them are literals |
Properties that are common to both:
- Prevents globbing
- Prevents word splitting
Examples:
$ echo "!cat"echo "cat file"cat file$ echo '!cat'!catecho "\"'\"""'"$ a='var'$ echo '$a'$a$ echo "$a"varNewlines and control characters
Section titled “Newlines and control characters”A newline can be included in a single-string or double-quoted string. Note that backslash-newline does not result in a newline, the line break is ignored.
newline1=''newline2=""newline3=$'\n'empty=\
echo "Line${newline1}break"echo "Line${newline2}break"echo "Line${newline3}break"echo "No line break${empty} here"Inside dollar-quote strings, backslash-letter or backslash-octal can be used to insert control characters, like in many other programming languages.
echo $'Tab: [\t]'echo $'Tab again: [\009]'echo $'Form feed: [\f]'echo $'Line\nbreak'Quoting literal text
Section titled “Quoting literal text”All the examples in this paragraph print the line
!"#$&'()*;<=>? @[\]^`{|}~A backslash quotes the next character, i.e. the next character is interpreted literally. The one exception is a newline: backslash-newline expands to the empty string.
echo \!\"\#\$\&\'\(\)\*\;\<\=\>\?\ \ \@\[\\\]\^\`\{\|\}\~All text between single quotes (forward quotes ', also known as apostrophe) is printed literally. Even backslash stands for itself, and it’s impossible to include a single quote; instead, you can stop the literal string, include a literal single quote with a backslash, and start the literal string again. Thus the 4-character sequence '\'' effectively allow to include a single quote in a literal string.
echo '!"#$&'\''()*;<=>? @[\]^`{|}~'# ^^^^Dollar-single-quote starts a string literal $'…' like many other programming languages, where backslash quotes the next character.
echo $'!"#$&\'()*;<=>? @[\\]^`{|}~'# ^^ ^^Double quotes " delimit semi-literal strings where only the characters " \ $ and ```bash retain their special meaning. These characters need a backslash before them (note that if backslash is followed by some other character, the backslash remains). Double quotes are mostly useful when including a variable or a command substitution.
echo "!\"#\$&'()*;<=>? @[\\]^\`{|}~"# ^^ ^^ ^^echo "!\"#\$&'()*;<=>? @[\]^\`{|}~"# ^^ ^ ^^ \[ prints \[Interactively, beware that ! triggers history expansion inside double quotes: "!oops" looks for an older command containing oops; "\!oops" doesn’t do history expansion but keeps the backslash. This does not happen in scripts.
Syntax
Section titled “Syntax”- \C (any one character except newline)
- ‘all literal except single quotes’; ‘this: ''' is a single quote’
- $‘only \ and ’ are special; \n = newline etc.’
- “$variable and other text; ”\$` are special”