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 ‘`’.