Joe Doyle
Joe Doyle

Reputation: 432

script doesn't see arg in '$ ssh bash script arg'

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

Answers (1)

Charles Duffy
Charles Duffy

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

Related Questions