I think the fact that SSH’s wire protocol can only take single string as a command is a huge, unrecognized design flaw. It would be so much better to take an array of command name plus arguments, just like the underlying syscalls. The distinction is similar to Dockerfile giving the choice between a command as string vs. array, where the string gets passed to a shell, and the array doesn’t.
This was a long time ago and I wasn’t doing much system administration then on account of being way too young to hold a job (well, I’m not doing much of that now either but back then I was doing even less of it…) so I might be misremembering it. Please take this with a grain of salt – perhaps someone who did more Unix back then remembers this better? By the time I started doing anything with Unix, rsh was pretty much a relic.
I think that this is not specifically SSH’s design, I think it’s deliberately made to be identical to rsh’s. That was actually a very clever design choice – ssh was specifically meant to replace rsh, which was 10+ years at the time, so coming up with a tool that could run 10 years’ worth of scripts was important, otherwise no one would’ve wanted it. It was a very efficient solution to a non-technical problem.
I suppose it would be possible to add a second syntax today, similar to Docker’s. I don’t know if that would be a good idea. IMHO it wouldn’t be but I think I’m prooobably not in the target demographics for these things ¯_(ツ)_/¯
Edit: oh yeah, if anyone’s wondering what arcane incantation from the ancient lore of the Unix greybeards is required to do that, just do:
echo "cd /tmp ; pwd" | ssh email@example.com
There are probably other/better ways, this one’s just my favourite.
FWIW, this one comes naturally to me, it’s the Docker way that “feels” weird to me. I don’t think one’s objectively better than the other, it’s just that I’d been doing it this way (with many other tools, not just SSH) for many years by the time Docker showed up. (Then again, it makes a lot of sense in Docker’s context, and Docker didn’t have to be a drop-in replacement for anything other than “works on my machine”, so I think they did the right thing)
I appreciate the point, but one minor warning: unlike ssh user@machine command, your echo command | ssh user@machine does allocate a pty for ssh (unless you use -T), which may affect the behaviour of some commands.
ssh user@machine command
echo command | ssh user@machine
Oh, yeah, this is a useful thing to remember! I think newer versions are (at least on some systems?) smart enough to figure out not to allocate a pty if stdin isn’t an actual terminal but I think that’s a whole other minefield. The reason why I usually don’t add -T explicitly is weird muscle/brain memory trained on a couple of somewhat restricted use cases.
I can’t edit my post anymore so here’s hoping nobody reads this thread halfway in the future :-D.
Ambiguous parsing, undocumented escaping. Hidden complexity. My favorite topics and (imho) the shared root cause for various security bugs.
An opinion in good company.
See also: http://langsec.org/