Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

scp: ambiguous target

69 views
Skip to first unread message

Kenny McCormack

unread,
Aug 2, 2022, 11:07:50 AM8/2/22
to
$ cd
$ mkdir 'this is a test'
$ scp -p .profile 'localhost:this is a test'
scp: ambiguous target
Status: 1
$ mv this\ is\ a\ test thisisatest
$ scp -p .profile 'localhost:thisisatest'
(This time, it works)
$ rmdir 'thisisatest'

Apparently, scp can't handle directories with spaces in their names.

Note: I cleaned this up a bit for posting. If you have trouble replicating
the error, let me know, and I'll make a suggestion as to what to try next.

--
Modern Christian: Someone who can take time out from using Leviticus
to defend homophobia and Exodus to plaster the Ten Commandments on
every school and courthouse to claim that the Old Testament is merely
"ancient laws" that "only applies to Jews".

Helmut Waitzmann

unread,
Aug 2, 2022, 11:31:34 AM8/2/22
to
gaz...@shell.xmission.com (Kenny McCormack):
> $ cd
> $ mkdir 'this is a test'
> $ scp -p .profile 'localhost:this is a test'
>scp: ambiguous target
>Status: 1

Does

scp -p .profile 'localhost:'\''this is a test'\'

work?

Kenny McCormack

unread,
Aug 2, 2022, 12:07:36 PM8/2/22
to
In article <83wnbqd...@helmutwaitzmann.news.arcor.de>,
Possibly. I'll have to test it at some point.

I kinda guessed that that was the underlying problem - that it gets passed
through two levels of shell and thus needs to be doubly-quoted.

Still, it *should* work (as is) - or at least be documented.

P.S. I've had similar situations with "ssh", where you have to
doubly-quote to get it to work. But there, it is explicit that two shells
are involved. With "scp", this is not made explicit.

--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/FreeCollege

Helmut Waitzmann

unread,
Aug 2, 2022, 1:27:54 PM8/2/22
to
gaz...@shell.xmission.com (Kenny McCormack):
>In article <83wnbqd...@helmutwaitzmann.news.arcor.de>,
>Helmut Waitzmann <oe.th...@xoxy.net> wrote:
>>gaz...@shell.xmission.com (Kenny McCormack):
>>> $ cd
>>> $ mkdir 'this is a test'
>>> $ scp -p .profile 'localhost:this is a test'
>>>scp: ambiguous target
>>>Status: 1
>>
>>Does
>>
>> scp -p .profile 'localhost:'\''this is a test'\'
>>
>>work?
>
>Possibly. I'll have to test it at some point.
>
>
>I kinda guessed that that was the underlying problem - that it gets
>passed through two levels of shell and thus needs to be
>doubly-quoted.
>
>Still, it *should* work (as is) -
>

The problem with "should work as is" is, that "scp" (via "ssh")
doesn't and cannot know anything about the shell running at the
remote system:  The shell there might be a POSIX compliant shell, a
"csh", "tcsh", "fish", "ksh", Bourne shell, Microsoft power
shell(?), …

Therefore "scp" doesn't know how to quote for the remote shell
command line.


>or at least be documented.
>

Yes.  That would enable the "scp" invoker (i. e. you and me), who
knows the remote system, how to do proper quoting for the shell
remote command line.

>P.S. I've had similar situations with "ssh", where you have to
>doubly-quote to get it to work. But there, it is explicit that two
>shells are involved. With "scp", this is not made explicit.

That's why I refrain from using "scp" at all.  I prefer to start a
"tar" command at the local and (via "ssh") at the remote site and
send the tape archive via stdout/stdin to have it instantly created
and extracted.  I would do something like

tar cf - .profile |
ssh -- "$remote_account" "$(
my_quote_words_for_shells tar xpf -
)"

when knowing that a POSIX compliant shell is running at the remote
site, whereas "my_quote_words_for_shells" quotes its given arguments
according to the quoting rules for a POSIX compliant shell,
concatenates them using spaces to be used as a (part of a) command
line, and sends the result to stdout.

If the local and remote shells both are "bash", one can use


printf ' %q' tar xpf -


rather than


my_quote_words_for_shells tar xpf -

S.K.R. de Jong

unread,
Aug 2, 2022, 2:04:45 PM8/2/22
to
On Tue, 2 Aug 2022 15:07:44 -0000 (UTC), Kenny McCormack wrote:

> $ cd
> $ mkdir 'this is a test'
> $ scp -p .profile 'localhost:this is a test'
> scp: ambiguous target Status: 1
> $ mv this\ is\ a\ test thisisatest $ scp -p .profile
> 'localhost:thisisatest'
> (This time, it works)
> $ rmdir 'thisisatest'
>
> Apparently, scp can't handle directories with spaces in their names.

Have you tried

scp -p .profile localhost:"this\ is\ a\ test"

?

Kaz Kylheku

unread,
Aug 2, 2022, 3:00:02 PM8/2/22
to
On 2022-08-02, Kenny McCormack <gaz...@shell.xmission.com> wrote:
> $ cd
> $ mkdir 'this is a test'
> $ scp -p .profile 'localhost:this is a test'
> scp: ambiguous target
> Status: 1
> $ mv this\ is\ a\ test thisisatest
> $ scp -p .profile 'localhost:thisisatest'
> (This time, it works)
> $ rmdir 'thisisatest'
>
> Apparently, scp can't handle directories with spaces in their names.

It's a bit weird. According to this "how scp works" page,
retrievable thanks to archive.org:

https://web.archive.org/web/20170215184048/https://blogs.oracle.com/janp/entry/how_the_scp_protocol_works

the filename is a combination of something passed on the command
line and in the protoco.

The receiving end can be unit-tested by echoing data to its stdin,
and the following example is presented:

$ rm -f /tmp/test
$ { echo C0644 6 test; printf "hello\\n"; } | scp -t /tmp
[ .. snip progress output ...]
$ cat /tmp/test
hello

The name of the file created by the receiving "scp -t" is a
combination of the -t argument, and the filename given in
the protocol by the "C0644 6 test" line.

The C protocol packet seems like it might be able to handle spaces.

I wonder whether the scp client couldn't just use / as the
-t argument and give a full path relativce to / in
in the C packet. (Or do the names in the packet have to be
simple base names with no slashes?)

The protocol also has commands for creating directories recursively;
Perhaps the scp client could be hacked to always uses that facility
under the hood even for what look like single file transfers.

Proof of concept:

Create the directory with spaces:

$ mkdir 'dir with spaces'

Now use the directory D protocol command to pretend we are recursively
copying a directory called 'dir with spaces', which contains a file
called 'test'. We pipe these commands to the remote scp command using
the ssh command (not using scp locally):

$ ( echo 'D0755 0 dir with spaces' ; echo C0644 6 test; printf 'hello\n'; echo E ) | ssh localhost scp -rt .
kaz@localhost's password:

OK, the result:

$ ls -l dir\ with\ spaces/
total 4
-rw-r--r-- 1 kaz kaz 6 Aug 2 11:53 test
$ cat dir\ with\ spaces/test
hello

So to reap instead of remotely executing "scp -t dir with spaces" and
then using a "C 0644 6 test" comamnd to do a single file, we remotely
execute "scp -t ." and follow the directory D workflow with a nested
file C in it.

I'm guessing that for a path path like 'a b/c d/e f/f', you have to
parse that and issue multiple nested D comands for "a b", "c d", and
"e f", and end each one with a corresponding E; i.e. taht the protocol
D command will not do a "mkdir -p" type operation to create all the
needed path components. Maybe it does, though?

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

William Ahern

unread,
Aug 2, 2022, 6:15:13 PM8/2/22
to
Kaz Kylheku <480-99...@kylheku.com> wrote:
> On 2022-08-02, Kenny McCormack <gaz...@shell.xmission.com> wrote:
>> $ cd
>> $ mkdir 'this is a test'
>> $ scp -p .profile 'localhost:this is a test'
>> scp: ambiguous target
>> Status: 1
>> $ mv this\ is\ a\ test thisisatest
>> $ scp -p .profile 'localhost:thisisatest'
>> (This time, it works)
>> $ rmdir 'thisisatest'
>>
>> Apparently, scp can't handle directories with spaces in their names.
>
> It's a bit weird. According to this "how scp works" page,
> retrievable thanks to archive.org:
>
> https://web.archive.org/web/20170215184048/https://blogs.oracle.com/janp/entry/how_the_scp_protocol_works

As of OpenSSH 9.0 (8.8/8.9 in OpenBSD), scp use the sftp protocol by
default, an eventuality alluded to in that Oracle article. Notably,

This creates one area of potential incompatibility: scp(1) when using the
SFTP protocol no longer requires this finicky and brittle quoting, and
attempts to use it may cause transfers to fail. We consider the removal of
the need for double-quoting shell characters in file names to be a benefit
and do not intend to introduce bug-compatibility for legacy scp/rcp in
scp(1) when using the SFTP protocol.

Source: https://www.openssh.com/txt/release-9.0

It seems RHEL 9 switched the default mode even earlier. See
https://www.redhat.com/en/blog/openssh-scp-deprecation-rhel-9-what-you-need-know

Kenny McCormack

unread,
Aug 2, 2022, 10:32:48 PM8/2/22
to
In article <95kori-...@wilbur.25thandClement.com>,
William Ahern <wil...@25thandClement.com> wrote:
...
>As of OpenSSH 9.0 (8.8/8.9 in OpenBSD), scp use the sftp protocol by
>default, an eventuality alluded to in that Oracle article. Notably,
>
> This creates one area of potential incompatibility: scp(1) when using the
> SFTP protocol no longer requires this finicky and brittle quoting, and
> attempts to use it may cause transfers to fail. We consider the removal of
> the need for double-quoting shell characters in file names to be a benefit
> and do not intend to introduce bug-compatibility for legacy scp/rcp in
> scp(1) when using the SFTP protocol.

Yeah. That's what I would have expected. That it would "just work" and
not need to spawn a shell - with all the "finickiness" that that entails.
I wonder when Debian will make this switch...

--
People who want to share their religious views with you
almost never want you to share yours with them. -- Dave Barry
0 new messages