EOF
to make here document expansions happen on the server
side rather than on the client.ssh host.example.com << EOF
echo "Logged in on $HOSTNAME"
EOF
ssh host.example.com << "EOF"
echo "Logged in on $HOSTNAME"
EOF
When the end token of a here document is unquoted, parameter expansion and command substitution will happen on in contents of the here doc.
This means that before sending the commands to the server, the client
replaces $HOSTNAME
with localhost, thereby sending
echo "Logged in on localhost"
to the server. This has the
effect of printing the client's hostname instead of the server's.
Scripts with any kind of variable use are especially problematic because all references will be expanded before the script run. For example,
ssh host << EOF
x="$(uname -a)"
echo "$x"
EOF
will never print anything, neither client nor server details, since before evaluation, it will be expanded to:
x="Linux localhost ... x86_64 GNU/Linux"
echo ""
By quoting the here token, local expansion will not take place, so
the server sees echo "Logged in on $HOSTNAME"
which is
expanded and printed with the server's hostname, which is usually the
intention.
If the client should expand some or all variables, this message can and should be ignored.
To expand a mix of local and remote variables, the here doc end token should be unquoted, and the remote variables should be escaped, e.g.
ssh host.example.com << EOF
echo "Logged in on \$HOSTNAME from $HOSTNAME"
EOF
ShellCheck is a static analysis tool for shell scripts. This page is part of its documentation.