37

I'm working with a bash script trying to stop it from attempting to replace variables inside my heredoc. How do set a heredoc to either A) escape the variable names instead of parsing them or B) return the entire string untouched?

cat > /etc/nginx/sites-available/default_php <<END
server {
    listen 80 default;
    server_name _;
    root /var/www/$host; <--- $host is a problem child
}
END

As is, when I it finishes injecting it into a file I'm left with this:

server {
    listen 80 default;
    server_name _;
    root /var/www/;
}

3 Answers 3

41

From the bash(1) man page:

If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded.

cat > /etc/nginx/sites-available/default_php <<"END"
5
  • 5
    +1 Escaping the "limit string" also works (\END). See also tldp.org/LDP/abs/html/here-docs.html#EX71C May 9, 2013 at 18:17
  • Single quotes work too
    – Joao Costa
    May 14, 2015 at 9:22
  • Same mechanism works for Korn shell (ksh).
    – jhfrontz
    Oct 2, 2015 at 20:17
  • 2
    It's worth noting that whilst this answers the second option in the OP's question, it doesn't answer the question title. Visitors here might be looking to answer the first option, where they still need some expansion, in which case they should use the answer by @halfgaar. This answer is still very useful of course, and clearly did serve the OP's purpose.
    – spikyjt
    Nov 2, 2020 at 16:57
  • @JohnMcCarthy - very helpful to know. Now it makes sense why 'EOF' works. May 10, 2022 at 20:59
36

Just with a backslash:

cat > /tmp/boeboe <<END
server {
    listen 80 default;
    server_name _;
    root /var/www/\$host';
}
END
2
  • Do you know how to disable injection of variable values without escaping each one?
    – Xeoncross
    Jun 16, 2012 at 15:59
  • 2
    What Ignacio said, but I didn't know that :)
    – Halfgaar
    Jun 17, 2012 at 6:53
0

@Xeoncross (and all landing here via search engine results) : it is possible to disable variable substitution by single-quoting the stop token :

cat > /tmp/boeboe << 'END'
server {
    listen 80 default;
    server_name _;
    root /var/www/$host;
}

# Example : here is another occurrence of '$host' which won't be substituted either
# When single-quoting the stop token, you don't have to escape all '$myVariable' anymore
END

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.