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