What's the difference between <<EOF and <<\EOF heredocs in shell What's the difference between <<EOF and <<\EOF heredocs in shell shell shell

What's the difference between <<EOF and <<\EOF heredocs in shell


From the POSIX spec:

If any character in word is quoted, the delimiter shall be formed by performing quote removal on word, and the here-document lines shall not be expanded. Otherwise, the delimiter shall be the word itself.

So the <<EOF version has the shell expand all variables before running the here doc contents and the <<\EOF (or <<'EOF' or <<EO'F' etc.) versions don't expand the contents (which lets bash in this case do that work).

Try it with cat instead of bash for a clearer view on what is happening.

Also with printf '[%s]\n' "$s" and/or possibly bash -x instead of bash:

$ bash -x <<EOFs=fdsprintf '[%s]\n' "$s"EOF+ s=fds+ printf '[%s]\n' ''[]$ bash -x <<\EOFs=fdsprintf '[%s]\n' "$s"EOF+ s=fds+ printf '[%s]\n' fds[fds]


Documentation: http://www.gnu.org/software/bash/manual/bash.html#Here-Documents

In your first example the delimiter is unquoted, so variable expansion occurs and it's like you're running the code

echo "s=fdsecho $s" | bash

which expands $s in the current shell, where it's empty. So the new shell sees

s=fdsecho 


Read the Advanced Bash Scripting Guide & bash reference manual in particular about redirections:

The format of here-documents is:

<<[-]word        here-documentdelimiter

No parameter and variable expansion, command substitution, arithmetic expansion, or filename expansion is performed on word. 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. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \newline is ignored, and ‘\’ must be used to quote the characters ‘\’, ‘$’, and ‘`’.