• scp: ambiguous target

    From Kenny McCormack@21:1/5 to All on Tue Aug 2 15:07:44 2022
    $ 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".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to oe.throttle@xoxy.net on Tue Aug 2 16:07:30 2022
    In article <83wnbqd5ol.fsf@helmutwaitzmann.news.arcor.de>,
    Helmut Waitzmann <oe.throttle@xoxy.net> wrote:
    gazelle@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) - 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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Tue Aug 2 17:30:02 2022
    gazelle@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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Tue Aug 2 19:21:48 2022
    gazelle@shell.xmission.com (Kenny McCormack):
    In article <83wnbqd5ol.fsf@helmutwaitzmann.news.arcor.de>,
    Helmut Waitzmann <oe.throttle@xoxy.net> wrote:
    gazelle@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 -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From S.K.R. de Jong@21:1/5 to Kenny McCormack on Tue Aug 2 18:04:36 2022
    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"

    ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Kenny McCormack on Tue Aug 2 18:59:58 2022
    On 2022-08-02, Kenny McCormack <gazelle@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From William Ahern@21:1/5 to Kaz Kylheku on Tue Aug 2 15:13:29 2022
    Kaz Kylheku <480-992-1380@kylheku.com> wrote:
    On 2022-08-02, Kenny McCormack <gazelle@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to william@25thandClement.com on Wed Aug 3 02:32:43 2022
    In article <95kori-2o82.ln1@wilbur.25thandClement.com>,
    William Ahern <william@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.

    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

    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to All on Wed Nov 30 17:51:37 2022
    tl;dr -> scp errs out if the target directory (on remote system) name has spaces in it.

    Something like:

    $ scp file "RemSys:/path/that contains spaces"

    Get an err msg something about "ambiguous target".

    Workaround/fix is to double quote like thus:

    $ scp file "RemSys:'/path/that contains spaces'"

    I was able to figure this out, but it is weird. Any idea if/where/how this problem is documented?


    --
    "I think I understand delicate, but why do I have to wash my hands, and
    be standing in cold water when doing it?"

    Kaz Kylheku <kaz@kylheku.com> in comp.lang.c

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Kenny McCormack on Wed Nov 30 20:05:44 2022
    On 2022-11-30, Kenny McCormack <gazelle@shell.xmission.com> wrote:

    tl;dr -> scp errs out if the target directory (on remote system) name has spaces in it.

    Fixed in OpenSSH 9.0:

    ------------------->
    This release switches scp(1) from using the legacy scp/rcp protocol
    to using the SFTP protocol by default.

    Legacy scp/rcp performs wildcard expansion of remote filenames (e.g.
    "scp host:* .") through the remote shell. This has the side effect of
    requiring double quoting of shell meta-characters in file names
    included on scp(1) command-lines, otherwise they could be interpreted
    as shell commands on the remote side.

    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.

    Another area of potential incompatibility relates to the use of remote
    paths relative to other user's home directories, for example -
    "scp host:~user/file /tmp". The SFTP protocol has no native way to
    expand a ~user path. However, sftp-server(8) in OpenSSH 8.7 and later
    support a protocol extension "expand-path@openssh.com" to support
    this.

    In case of incompatibility, the scp(1) client may be instructed to use
    the legacy scp/rcp using the -O flag.
    <-------------------

    If you have at least OpenSSH 8.7:

    ------------------->
    - scp(1): experimental support for transfers using the SFTP protocol
    as a replacement for the venerable SCP/RCP protocol that it has
    traditionally used. SFTP offers more predictable filename handling
    and does not require expansion of glob(3) patterns via the shell
    on the remote side.

    SFTP support may be enabled via a temporary scp -s flag. It is
    intended for SFTP to become the default transfer mode in the
    near future, at which time the -s flag will be removed. The -O
    flag exists to force use of the original SCP/RCP protocol for
    cases where SFTP may be unavailable or incompatible.
    <-------------------

    --
    Christian "naddy" Weisgerber naddy@mips.inka.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hauke Fath@21:1/5 to Kenny McCormack on Wed Nov 30 21:43:40 2022
    Kenny McCormack <gazelle@shell.xmission.com> wrote:

    tl;dr -> scp errs out if the target directory (on remote system) name has spaces in it.

    $ scp file "RemSys:/path/that contains spaces"

    Get an err msg something about "ambiguous target".

    Workaround/fix is to double quote like thus:

    $ scp file "RemSys:'/path/that contains spaces'"

    I was able to figure this out, but it is weird.

    Not really. In the first example, the shell strips the double quotes and invokes scp with the path as one argument.

    --
    Now without signature.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to naddy@mips.inka.de on Thu Dec 1 08:57:19 2022
    In article <slrntofdso.gau.naddy@lorvorc.mips.inka.de>,
    Christian Weisgerber <naddy@mips.inka.de> wrote:
    On 2022-11-30, Kenny McCormack <gazelle@shell.xmission.com> wrote:

    tl;dr -> scp errs out if the target directory (on remote system) name has
    spaces in it.

    Fixed in OpenSSH 9.0:

    ------------------->
    This release switches scp(1) from using the legacy scp/rcp protocol
    to using the SFTP protocol by default.

    Legacy scp/rcp performs wildcard expansion of remote filenames (e.g.
    "scp host:* .") through the remote shell. This has the side effect of >requiring double quoting of shell meta-characters in file names
    included on scp(1) command-lines, otherwise they could be interpreted
    as shell commands on the remote side.

    Thanks. This was a helpful, informative post.

    ...

    SFTP support may be enabled via a temporary scp -s flag. It is
    intended for SFTP to become the default transfer mode in the
    near future, at which time the -s flag will be removed. The -O
    flag exists to force use of the original SCP/RCP protocol for
    cases where SFTP may be unavailable or incompatible.

    I haven't gotten around to testing this, but it looks like adding:

    -S /usr/lib/sftp-server

    to the "scp" command line would enable the new behavior (i.e., unless/until
    I get the newest versions of things installed on my system). Is that
    correct? Note that, AFAICT, the option is "-S" (capital S), not "-s".

    Note also that, on my system(s), /usr/lib/sftp-server is a symlink to /usr/lib/openssh/sftp-server.

    --
    "The most unsettling aspect of my atheism for Christians is
    when they realize that their Bible has no power to make me
    wince. They are used to using it like a cattle prod to get
    people to cower into compliance." - Author unknown

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Kenny McCormack on Thu Dec 1 19:51:02 2022
    On 2022-12-01, Kenny McCormack <gazelle@shell.xmission.com> wrote:

    I haven't gotten around to testing this, but it looks like adding:

    -S /usr/lib/sftp-server

    to the "scp" command line would enable the new behavior (i.e., unless/until
    I get the newest versions of things installed on my system). Is that correct?

    No. In either mode, scp will invoke ssh to connect to the remote
    host:

    $ scp foo host:bar
    will spawn
    /usr/bin/ssh -x -oPermitLocalCommand=no -oClearAllForwardings=yes \
    -oRemoteCommand=none -oRequestTTY=no -oForwardAgent=no -s -- host sftp

    $ scp -O foo host:bar
    will spawn
    /usr/bin/ssh -x -oPermitLocalCommand=no -oClearAllForwardings=yes \
    -oRemoteCommand=none -oRequestTTY=no -oForwardAgent=no -- host scp -t bar

    You can use the -S option to replace "/usr/bin/ssh" with something
    else. The only practical use that comes to mind would be a wrapper
    script that calls /usr/bin/ssh with some additional options, given
    that scp doesn't have a configuration file.

    - - - -

    Nowadays people might no longer know, but Tatu Ylönen wrote ssh as
    a drop-in replacement for the Berkeley rlogin/rsh/rcp suite. The
    scp command was directly derived from the rcp code; rcp in turn had
    been written by Bill Joy all the way back in 1982.

    The completely revamped SSH2 protocol gained a whole file transfer
    subprotocol (SFTP), for which OpenSSH has provided the sftp(1)
    client. However, people prefer the scp(1) command line syntax, so
    after years of hemming and hawing, OpenSSH has finally gone ahead
    and moved scp over to SFTP, and fixed the quoting issue in the
    process--or deliberately broke compatibility, however you want to
    see it.

    --
    Christian "naddy" Weisgerber naddy@mips.inka.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to naddy@mips.inka.de on Thu Dec 1 22:54:35 2022
    In article <slrntoi1d6.1ecg.naddy@lorvorc.mips.inka.de>,
    Christian Weisgerber <naddy@mips.inka.de> wrote:
    On 2022-12-01, Kenny McCormack <gazelle@shell.xmission.com> wrote:

    I haven't gotten around to testing this, but it looks like adding:

    -S /usr/lib/sftp-server

    to the "scp" command line would enable the new behavior (i.e., unless/until >> I get the newest versions of things installed on my system). Is that
    correct?

    No. In either mode, scp will invoke ssh to connect to the remote
    host:

    $ scp foo host:bar
    will spawn
    /usr/bin/ssh -x -oPermitLocalCommand=no -oClearAllForwardings=yes \
    -oRemoteCommand=none -oRequestTTY=no -oForwardAgent=no -s -- host sftp

    $ scp -O foo host:bar
    will spawn
    /usr/bin/ssh -x -oPermitLocalCommand=no -oClearAllForwardings=yes \
    -oRemoteCommand=none -oRequestTTY=no -oForwardAgent=no -- host scp -t bar

    You can use the -S option to replace "/usr/bin/ssh" with something
    else. The only practical use that comes to mind would be a wrapper
    script that calls /usr/bin/ssh with some additional options, given
    that scp doesn't have a configuration file.

    - - - -

    Nowadays people might no longer know, but Tatu Ylnen wrote ssh as
    a drop-in replacement for the Berkeley rlogin/rsh/rcp suite. The
    scp command was directly derived from the rcp code; rcp in turn had
    been written by Bill Joy all the way back in 1982.

    The completely revamped SSH2 protocol gained a whole file transfer >subprotocol (SFTP), for which OpenSSH has provided the sftp(1)
    client. However, people prefer the scp(1) command line syntax, so
    after years of hemming and hawing, OpenSSH has finally gone ahead
    and moved scp over to SFTP, and fixed the quoting issue in the
    process--or deliberately broke compatibility, however you want to
    see it.

    Again, thanks. Very interesting stuff.

    --
    1/20/17: A great day for all those people who are sick of being told
    they don't know how to spell "you're" (or "there").

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)