SSH Commands
SSH commands differ from ordinary shell commands; that is, the shell command
is very different from
despite the misleading visual similarity of the two.
The verbose ssh -v -v -v, usually a good debug step, will only indicate that "sh -c echo foo; echo bar" was sent.
The shell quotes have been removed; that is done by the shell that runs the original command. In either case the shell '' will not be present, as can be confirmed with a process tracing tool.
That is, the shell code results in something like the following C being run; the single quotes were for the shell itself to group the echos into a single argument.
If we think about
for a bit, we may figure out what has happened. This is a better state to be in than denial over the fact that our mental model is perhaps at odds with reality.
What does this do? It runs the echo command without any arguments. The foo cannot be an argument to echo; if it were, we would see it printed. How about a minimal test case with no ssh involved?
There is no foo. If you quote things up as "echo foo" or 'echo foo' there will be foo. But that's not what we told ssh to run. Anyways, foo here is an argument to whatever it is that the -c does run.
However in "sh -c echo foo" the echo does nothing with the $0 and thus prints a blank line. This is like having the not very useful function
and then to wonder why foo is not printed.
At this point we might guess that ssh has sent the commands as a single string and not as individual arguments,
which means that if -c needs to see a single argument that will need to be quoted on the remote system:
and, this quoting must also be quoted to protect it from the shell that is running the ssh command:
And to test:
Additional levels of quoting might get out of hand if the sh script is to do anything at all complicated; in that case I would most likely first copy the code to the system, and then run it with suitable arguments. Another option is to use a different language. For example TCL uses a different quoting syntax than the shell does; {...} is a literal quote:
Or in C:
If anything, alternate language implementations may help distinguish the syntax of the outer shell layer from that of the sh run by way of the ssh command.
tags #ssh #sh