I want to pass a string in a heredoc that contains a variable, and multiple "$" characters. The command without the heredoc is:
FOO='BAR'
echo ${FOO}: '$NOT_A_VARIABLE'
The FOO
variable is correctly substituted and the '$NOT_A_VARIABLE'
string avoids substitution because it is single quoted. The command returns as expected:
BAR: $NOT_A_VARIABLE
Now if I do the same inside the heredoc:
sh << EOF
echo ${FOO}: '$NOT_A_VARIABLE'
EOF
The output is not what I desired:
BAR:
It seems, that the '$NOT_A_VARIABLE'
is substituted even though it is surrounded by single quotes.
I know that this can be avoid by escaping the $
with a backslash: \$
but this solution is annoying since there might be multiple $
characters randomly distributed in the string.
I wonder if there is a smart use of quotes (single/double) or other solutions that might fix it.
The contents of your here document are treated as a double-quoted string, just as if you had written
echo "$FOO: '$NOT_A_VARIABLE'" | sh
If you want to suppress all parameter expansion in the here document, you can quote the delimiter:
sh << 'EOF'
echo ${FOO}: '$NOT_A_VARIABLE'
EOF
which will pass
echo ${FOO}: '$NOT_A_VARIABLE'
as the input to sh
.
If you only want to suppress a specific expansion, escape the $
just as you would in a double-quoted string.
# echo "$FOO: \$NOT_A_VARIABLE" | sh
sh << EOF
echo ${FOO}: \$NOT_A_VARIABLE
EOF