Bash
backslash escaped characters and whitespace can be a headache if not understood properly. This post will endeavour to explore whitespace and backslash escaped characters with practical examples.
What are Backslash Escaped Characters
These are character sequences that, in certain cases, indicate a special character that is, usually, hard to see for the human reader, such as <tab>
and <newline>
. This is the list from the man
bash
pages:
a alert (bell)
b backspace
e an escape character
f form feed
n new line
r carriage return
t horizontal tab
v vertical tab
\ backslash
' single quote
nnn the eight-bit character whose value is the octal value nnn (one to three digits)
xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
cx a control-x character
So, for example, n
represents <newline>
. Please note that these escaped characters are only mentioned in the following context:
Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.
The expanded result is single-quoted, as if the dollar sign had not been present.
Backslash Escaped Characters are NOT the Characters they Represent
It may be tempting to think that n
is the same as the actual <newline>
character that is added when you press enter
. They are actually not equal as we will see in the examples.
Examples
No Quotes
Backslash Escaped newline (n)
[ahmed@amayem ~]$ echo hellonworld
hellonworld
Notice that the backslash is removed. This is because of the following mentioned in the man
bash
pages:
A non-quoted backslash () is the escape character. It preserves the literal value of the next character that follows, with the exception of <newline>. If a <newline> pair appears, and the backslash is not itself quoted, the <newline> is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).
So basically the backslash made sure that the n
is kept as an n
.
Actual Newline (Pressing Enter)
[ahmed@amayem ~]$ echo hello
hello
[ahmed@amayem ~]$ world
As is expected, once we enter a <newline>
(by pressing enter) bash
understands it as the end of the command and so only hello
is printed. world
appears in the next prompt indicating that the previous command has already ended.
Single Quotes
Backslash Escaped newline (n)
[ahmed@amayem ~]$ echo 'hellonworld'
hellonworld
This time the backslash is printed, which means it lost it’s special ability as in the previous example. This is mentioned in the man
bash
pages:
Enclosing characters in single quotes preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
Basically the single quotes take away the quoting abilities of the backslash.
Actual Newline (Pressing Enter)
[ahmed@amayem ~]$ echo 'hello
> world'
hello
world
Here the single quotes preserved the <newline>
and prevented bash
from thinking that the <newline>
is the end of the command. It printed out the <newline>
properly then the word world
.
Double Quotes
Backslash Escaped newline (n)
[ahmed@amayem ~]$ echo "hellonworld"
hellonworld
This has the same effect as the single quotes, but there are some differences as mentioned in the man
bash
pages:
Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $, `, , and, when history expansion is enabled, !. The characters $ and ` retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: $, `, ", , or <newline>. A double quote may be quoted within double quotes by preceding it with a backslash.
So the double quotes are like the single quotes except that some characters retain their special meaning.
Actual Newline (Pressing Enter)
[ahmed@amayem ~]$ echo "hello
> world"
hello
world
It worked properly.
Single Quotes Preceded by $ ($string)
Backslash Escaped newline (n)
[ahmed@amayem ~]$ echo $'hellonworld'
hello
world
Finally the escaped character is replaced with an actual <newline>
. The following is what the man
bash
pages have to say (as shown earlier as well).
Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.
The expanded result is single-quoted, as if the dollar sign had not been present.
Actual Newline (Pressing Enter)
[ahmed@amayem ~]$ echo $'hello
> world'
hello
world
The <newline>
is preserved as expected.
Summary
Beware that backslash escaped characters of the ANSI C standard will not be replaced with what is expected unless they are part of a string in the the $'string'
form. Also remember that the backslash escaped characters are not the same as the actual character they represent.
References
man
bash
pages