Why the behaviour of both command are different?
Because the \
character is an escape character inside "
quotes, and \$
is one of escape sequences. Some parts from bash manual double qoutes:
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 backslash retains its special meaning only when followed by one of the following characters: ‘$’, ‘`’, ‘"’, ‘\’, or newline.
Within double quotes, backslashes that are followed by one of these characters are removed.
Backslashes preceding characters without a special meaning are left unmodified.
The "special meaning" of \
character is meant to be the escaping thing:
A non-quoted backslash ‘\’ is the Bash escape character. It preserves the literal value of the next character that follows
Because ^
is not one of $
`
"
\
, then "\^"
preserves both \
and ^
so it's is equal to '\^'
.
Because $
is one of them, then "\$"
is equal to '$'
. The slash get's removed and \$
is interpreted as $
.
Such typos are easy to find out with set -x
.
$ ( set -x; grep -E "\$" /dev/null; )
+ grep -E '$' /dev/null
$ ( set -x; grep -E '\$' /dev/null; )
+ grep -E '\$' /dev/null