Reputation: 432
I'd like to see both commands print hello
$ bash -l -c "/bin/echo hello"
hello
$ ssh example_host bash -l -c /bin/echo hello
$
How can hello
be passed as a parameter in the ssh
command?
The bash -l -c
is needed, so login shell startup scripts are executed.
Getting ssh
to start a login shell would solve the problem too.
Upvotes: 1
Views: 163
Reputation: 295687
When you pass extra args after -c
, they're put into the argv of the shell while that command is executing. You can see that like so:
bash -l -c '/bin/echo "$0" "$@"' hello world
...so, those arguments aren't put on the command line of echo (unless you go out of your way to make it so), but instead are put on the command line of the shell which you're telling to run echo with no arguments.
That is to say: When you run
bash -l -c /bin/echo hello
...that's the equivalent of this:
(exec -a hello bash -c /bin/echo)
...which puts hello
into $0
of a bash which runs only /bin/echo
. Since running /bin/echo
doesn't look at $0
, of course it's not going to print hello
.
Now, because executing things via ssh means you're going through two steps of shell expansion, it adds some extra complexity. Fortunately, you can have the shell handle that for you automatically, like so:
printf -v cmd_str '%q ' bash -l -c '/bin/echo "$0" "$@"' hello world
ssh remote_host "$cmd_str"
This tells bash (printf %q
is a bash extension, not available in POSIX printf) to quote your command such that it expands to itself when processed by a shell, then feeds the result into ssh
.
All that said -- treating $0
as a regular parameter is bad practice, and generally shouldn't be done absent a specific and compelling reason. The Right Thing is more like the following:
printf -v cmd '%q ' /bin/echo hello world # your command
printf -v cmd '%q ' bash -l -c "$cmd" # your command, in a login shell
ssh remotehost "$cmd" # your command, in a login shell, in ssh
Upvotes: 2