Bash AliasingBash ArithmeticBash ArraysBash Associative arraysBash Avoiding date using printfBash Brace ExpansionBash Case statementBash CGI ScriptsBash Chain of commands and operationsBash Change shellBash co-processesBash Color script output (cross-platform)Bash Conditional ExpressionsBash Control StructuresBash Copying (cp)Bash Creating directoriesBash Customizing PS1Bash Cut CommandBash DebuggingBash Decoding URLBash Design PatternsBash File execution sequenceBash File Transfer using scpBash FindBash FunctionsBash getopts : smart positional-parameter parsingBash global and local variablesBash GrepBash Handling the system promptBash Here documents and here stringsBash history substitutionsBash Internal variablesBash IntroductionBash Job ControlBash Jobs and ProcessesBash Jobs at specific timesBash Keyboard shortcutsBash Listing FilesBash Managing PATH environment variableBash MathBash NamespaceBash Navigating directoriesBash on Windows 10Bash ParallelBash Parameter ExpansionBash Pattern matching and regular expressionsBash PipelinesBash PitfallsBash Process substitutionBash Programmable completionBash QuotingBash Read a file (data stream, variable) line-by-line (and/or field-by-field)Bash RedirectionBash ScopingBash Script shebangBash Scripting with ParametersBash Select keywordBash Sleep utilityBash SourcingBash Splitting FilesBash straceBash the cut commandBash true, false and : commandsBash Type of ShellsBash Typing variablesBash Using catBash Using sortBash Using trap to react to signals and system eventsBash when to use evalBash Word splittingNetworking with Bash

Bash Quoting

From WikiOD

Syntax[edit | edit source]

  • \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"

Double quotes for variable and command substitution[edit | edit source]

Variable substitutions should only be used inside double quotes.

calculation='2 * 3'
echo "$calculation"         # prints 2 * 3
echo $calculation           # prints 2, the list of files in the current directory, and 3
echo "$(($calculation))"    # prints 6

Outside 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"             # good
echo "$(mycommand)"     # good 
another=$var            # also works, assignment is implicitly double-quoted
make -D THING=$var      # BAD! This is not a bash assignment.
make -D THING="$var"    # good
make -D "THING=$var"    # also good

Command 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[edit | edit source]

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
$, `, ", \ 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


$ echo "!cat"
echo "cat file"
cat file
$ echo '!cat'
echo "\"'\""
$ a='var'
$ echo '$a'
$ echo "$a"

Newlines and control characters[edit | edit source]

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.



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[edit | edit source]

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 ` 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.