简体   繁体   中英

invoking shell "source" via 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. ]

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' 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM