Parke
2018-Oct-21 05:54 UTC
The first command of a nested compound command receives no arguments
Hello, The following three commands work as expected: root at cosmic:~# ssh localhost 'echo 1 && echo 2 && echo 3' 1 2 3 root at cosmic:~# ssh localhost "dash -c 'echo 1 && echo 2 && echo 3'" 1 2 3 root at cosmic:~# ssh localhost echo 1 2 3 4 5 1 2 3 4 5 The following three commands produce unexpected behavior. Specifically, it appears that the first nested command is called with no arguments. root at cosmic:~# ssh localhost dash -c 'echo 1 && echo 2 && echo 3' 2 3 root at cosmic:~# ssh localhost dash -c 'touch a && touch b && touch c' touch: missing file operand Try 'touch --help' for more information. root at cosmic:~# ssh localhost dash -c 'touch a b && touch c d && touch e f' touch: missing file operand Try 'touch --help' for more information. Is the above the intended behavior? If so, why? What is going on? It seems strange to me. The above commands were run on Ubuntu 18.10 on a VPS at Digital Ocean. The openssh package version appears to be: 1:7.7p1-4. Another pair of examples: root at cosmic:~# ssh localhost dash -c 'hostname && hostname && hostname' cosmic cosmic cosmic root at cosmic:~# ssh localhost dash -c 'echo `hostname` && echo `hostname` && echo `hostname`' cosmic cosmic Another strange example: root at cosmic:~# ssh localhost dash -c 'exit 2 && exit 3 && exit 4' (Will exit with status of 3.) Thank you, Parke
Timo Kilpilehto
2018-Oct-21 11:10 UTC
The first command of a nested compound command receives no arguments
On Sun, Oct 21, 2018 at 9:06 AM Parke <parke.nexus at gmail.com> wrote:> The following three commands produce unexpected behavior. > Specifically, it appears that the first nested command is called with > no arguments. > > root at cosmic:~# ssh localhost dash -c 'echo 1 && echo 2 && echo 3' > > 2 > 3 > root at cosmic:~# ssh localhost dash -c 'touch a && touch b && touch c' > touch: missing file operand > Try 'touch --help' for more information. > root at cosmic:~# ssh localhost dash -c 'touch a b && touch c d && touch e f' > touch: missing file operand > Try 'touch --help' for more information. > > Is the above the intended behavior? If so, why? What is going on? > It seems strange to me.Hi Parke, This has nothing to do with openssh or even chaining commands really. We can see similar behaviour when just using eval and sh -c: eval sh -c "echo none of this makes any difference" -> prints empty line So, what happens here? The eval utility shall construct a command by concatenating arguments together, separating each with a <space> character. The constructed command shall be read and executed by the shell. So, in short what happens is this gets executed: sh -c echo none of this makes any difference -> again, prints empty line And why does this happen you might ask? Here's what man page says about option -c: -c string If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0. In other words what this means is that shell will execute the sole command (echo) we provided in a sub shell as an inline script. Then the rest of the arguments if any will be provided to the script as positional arguments starting with $0. However, our script does not use them for anything, it just runs echo with no arguments. In order to make it output these arguments we'd have to do something like this: sh -c 'echo $@' _ now something gets printed -> outputs "now something gets printed" In the end it may just be easier to use quoting on the entire inline script to execute: sh -c "echo now something gets printed" And in order to persist the quoting through evaluating using eval or ssh or anything of the sort we need extra layer of quoting: eval 'sh -c "echo now something gets printed"' So to summarise ssh handles in this case the command precisely as if using eval which I would say is quite likely the intended behaviour and exactly what one would expect. I hope this clarifies things for you. Best regards, Timo
Christian Weisgerber
2018-Oct-21 11:56 UTC
The first command of a nested compound command receives no arguments
On 2018-10-21, Parke <parke.nexus at gmail.com> wrote:> root at cosmic:~# ssh localhost dash -c 'echo 1 && echo 2 && echo 3' > > 2 > 3This should give you an idea: $ sh -c 'sh -c echo 1 && echo 2 && echo 3' 2 3 -- Christian "naddy" Weisgerber naddy at mips.inka.de