Why does exporting a variable in an ssh shell print the list of exported variables?
When you run a command through
ssh, it is run by calling your
$SHELL with the
-c If the -c option is present, then commands are read from the first non-option argument command_string. If there are arguments after the command_string, the first argument is assigned to $0 and any remaining arguments are assigned to the positional parameters.
ssh remote_host "bash -c foo" will actually run:
/bin/your_shell -c 'bash -c foo'
Now, because the command you are running (
export foo=bar) contains spaces and is not properly quoted to form a whole, the
export is taken as the command to be run and the rest are saved in the positional parameters array. This means that
export is run and
foo=bar is passed to it as
$0. The final result is the same as running
/bin/your_shell -c 'bash -c export'
The correct command would be:
ssh remote_host "bash -c 'export foo=bar'"
ssh concatenates the arguments with spaces and has the login shell of the remote user interpret it, so in:
ssh localhost bash -c 'export foo=bar'
ssh is asking the remote shell to interpret the
bash -c export foo=bar
command (in effect, if the remote host is Unix-like, it will run the remote shell with
bash -c export foo=bar as arguments).
Most shells will interpret that command line as running the
bash command with
foo=bar as arguments (so run
foo=bar) while you'd want it to run it with
export foo=bar as arguments.
For that, you'd need to use a command line like:
ssh localhost "bash -c 'export foo=bar'"
ssh localhost bash -c \'export foo=bar\'
for that matters) so the:
bash -c 'export foo=bar'
command line be passed to the remote shell. That command line would be interpreted by most shells as running the
bash command with
export foo=bar as arguments. Note that using
ssh localhost 'bash -c "export foo=bar"'
would not work if the login shell of the remote user was
es for instance where
" is not a special quoting operator. Single quotes are the most portable quoting operators (though there is some variation on how they are interpreted between shells, see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user? for more on that).