In short, use:
- unquoted heredoc keywords, e.g.,
EOF
- regular dollar char for outer (i.e. local) variables, e.g.,
$FOO
- escaped dollar char for inner (i.e. remote) variables, e.g.
\$BAR
If you leave the heredoc keyword (i.e. EOF
) unquoted then the heredoc body is processed locally, so that $FOO
is expanded to foo
and BAR
is expanded to the empty string. Then your ssh
command becomes:
BAR="bar"
echo "FOO=foo"
echo "BAR="
If you quote the heredoc keyword then variable expansion is suppressed, so that your ssh
command becomes this instead:
BAR="bar"
echo "FOO=$FOO"
echo "BAR=$BAR"
Since FOO
is probably not defined in the remote shell environment, the expression "FOO=$FOO"
is evaluated as "FOO=''"
, i.e. FOO
is set to the empty string.
If you want to use both variables then you'll need to leave the heredoc keyword unquoted, so that variable expansion takes place for the locally defined variable, and then escape (with a backslash) the variable that you want to be expanded remotely, i.e.:
#!/bin/sh
FOO="foo"
ssh some.remote.host << EOF
BAR="bar"
echo "FOO=$FOO"
echo "BAR=\$BAR"
EOF
In this case your ssh command (as received by the remote server) will be the following:
BAR="bar"
echo "FOO=foo"
echo "BAR=$BAR"