Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

invoking shell "source" via ssh

Tags:

sh

ssh

[ I am going to use /dev/null to illustrate the problem. If that bothers you, just replace it with any other shell initialization file, such as /etc/profile. ]

I am trying to invoke source within a shell called by ssh. The following works:

host$ source /dev/null
host$ sh -c 'source /dev/null'

But the following fails:

host$ ssh localhost sh -c 'source /dev/null'
/dev/null: line 0: source: filename argument required
source: usage: source filename [arguments]

But if I make source the second command in the shell, then it works:

host$ ssh localhost sh -c 'echo; source /dev/null'
host$ ssh localhost sh -c ':; source /dev/null'
host$

The question is why cannot I invoke source as the first command in a shell through ssh? And how to do it properly? (And for a bonus answer, why does it work when it is the second command?)
[ And the source command will not be the only command called; it is just a requirement before I invoke the other commands on the same ssh command. ]

like image 620
bjorn Avatar asked Oct 27 '25 17:10

bjorn


1 Answers

Your quoting is incomplete.

sh -c 'source /dev/null' invokes a new shell and passes it two parameters, the first is the option (-c), the second is the command-string for -c to operate on.

ssh localhost sh -c 'source /dev/null' invokes ssh to start a shell on localhost. This new shell is passed a command containing 4 words - in effect, the single-quotes are removed by ssh. This shell duly starts a second shell and passes it 3 parameters. In this case -c only receives source as the command-string.

You need additional quoting to replace the ones stripped by ssh. For example:

ssh localhost "sh -c 'source /dev/null'"

The reason ssh localhost sh -c 'echo; source /dev/null' appears to work is that ssh has passed two commands to the shell it starts: sh -c echo (which then exits), followed by source /dev/null

It may be helpful to imagine replacing ssh localhost with echo and seeing which quotes disappear.


The POSIX shell synopsis says:

sh -c [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]...
   command_string [command_name [argument...]]

-c   Read commands from the command_string operand. Set the value
     of special parameter 0 (see Special Parameters) from the value
     of the command_name operand and the positional parameters ($1,
     $2, and so on) in sequence from the remaining argument
     operands. No commands shall be read from the standard input.
like image 93
jhnc Avatar answered Oct 29 '25 08:10

jhnc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!