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 flag:

-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.  

So, 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 the-shell, -c and bash -c export foo=bar as arguments).

Most shells will interpret that command line as running the bash command with bash, -c, export and foo=bar as arguments (so run export while $0 contains foo=bar) while you'd want it to run it with bash, -c and export foo=bar as arguments.

For that, you'd need to use a command line like:

ssh localhost "bash -c 'export foo=bar'"

(or:

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 bash, -c and 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 rc or 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).

Tags:

Bash

Ssh