Bug 2563 - ssh bash -c drops arguments of the first command send to the remote.
Summary: ssh bash -c drops arguments of the first command send to the remote.
Status: CLOSED WONTFIX
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 7.2p1
Hardware: All All
: P3 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-08 19:40 AEST by Pascal Bourguignon
Modified: 2021-04-23 14:58 AEST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pascal Bourguignon 2016-04-08 19:40:55 AEST
$ ssh -n -x -T $remote /bin/bash -c 'echo a b c'
doesn't execute ssh 


$ /bin/bash -c 'echo a b c'
a b c
$ /bin/bash -c '/bin/bash -c "echo a b c"'
a b c
$  ssh -n -x -T localhost /bin/bash -c 'echo a b c'

$  ssh -n -x -T localhost /bin/bash -c ':;echo a b c'
a b c

$ rm bar
$ ssh localhost /bin/bash -c 'echo foo bar baz > ~/bar'
X11 forwarding request failed on channel 0
$ cat bar

$ rm bar
$ ssh -x -n -T localhost /bin/bash -c 'printf "%s\n" foo bar baz > ~/bar'
printf: usage: printf [-v var] format [arguments]
$ ssh -x -n -T localhost /bin/bash -c 'echo foo foo foo;echo bar bar bar'

bar bar bar
$ 

So, strangely enough, only the arguments of the first command are removed; the command itself and the redirection are transmitted and executed, as well as the following commands if any.


This occurs the same way on linux and on MacOSX (with bash 4.3 on Linux, bash 3.2 on MacOSX) and the following versions of ssh; and this occurs the same way whether we ssh to localhost, or remotely to a different system.

$ ssh -V
OpenSSH_6.7p1 Debian-5+deb8u1, OpenSSL 1.0.1k 8 Jan 2015
$ 

$ ssh -V
OpenSSH_6.9p1, LibreSSL 2.1.8
Comment 1 Jakub Jelen 2016-04-08 20:30:23 AEST
It does not look like a bug. The `ssh` accepts single argument as an command, even though everyone is misusing it to use more of them. From manual page for ssh:

    ssh [...] [user@]hostname [command]

The correct wording of your command would be:

    ssh -n -x -T $remote "/bin/bash -c 'echo a b c'"
Comment 2 Pascal Bourguignon 2016-04-08 21:51:09 AEST
You're right, the documentation specifies a single argument for the command, so we can't say it's a bug.


Then let's transform this into a feature request/enhancement, to upgrade the syntax to:

   ssh ... [command [arguments...]]

to match the behavior of su and sudo, amongst other commands.


That said, it could be argued that eg. sudo also takes [command], without documenting it accepting arguments, but it accepts them and it processes them as expected:

$ sudo bash -c 'echo foo;echo bar'
foo
bar
$



If [command [arguments...]] wasn't documented and implemented, I would move to signal an error when giving superfluous arguments (both to ssh and sudo, and any other such command not documenting what it accepts).



There's an argument to be made for using only [command] for sudo, ssh and the like (even su): shell expansions are dones in the caller shell, so if we don't use a single command-and-argument parameter, we have more risks of issuing "not-what-I-mean" commands such as:

    ssh $remote ls *

But again, if we take this argument and reject [command [arguments...]], then it would be better for the user (and less risky) to signal an error for such a command.
Comment 3 Pascal Bourguignon 2016-04-08 22:07:43 AEST
I've identified the reason of the observed behavior: bash -c takes a single command (as documented), but if it is followed by arguments, then they are used as "command line arguments", assigned to $0 $1 ...

For example:

$ bash -c 'echo $0 $@' foo \; echo bar
foo ; echo bar
$

so:
    ssh ... bash -c 'echo foo;echo bar'

sends and executes remotely:

    bash -c echo foo ; echo bar

with:
 
    bash -c echo foo

assigning foo to $0 (no other command line argument), bash executing therefore just 'echo'.

Then something strange occurs, since it seems that the following
    ; echo bar
gets evaluated somehow (probably by a shell forked by ssh on the remote side).



The whole situation is messy, and I definitely think that ssh should either concatenate the arguments to make a single command to be executed remotely, or it should signal an error when it's given additionnal arguments, instead of forwarding them to the remote side to be processed in ways that are not very strictly controlled, documented or well known.
Comment 4 Damien Miller 2016-04-08 23:03:11 AEST
(In reply to Pascal Bourguignon from comment #3)
 > The whole situation is messy, and I definitely think that ssh should
> either concatenate the arguments to make a single command to be
> executed remotely, or it should signal an error when it's given
> additionnal arguments, instead of forwarding them to the remote side
> to be processed in ways that are not very strictly controlled,
> documented or well known.

Unfortunately we're about 20 years too late to make changes to ssh's argument handling. Doing so now would break a very large number of working setups.
Comment 5 Damien Miller 2021-04-23 14:58:47 AEST
closing resolved bugs as of 8.6p1 release