Win32-OpenSSH icon indicating copy to clipboard operation
Win32-OpenSSH copied to clipboard

Different syntax for forward and backward scp

Open vritme opened this issue 3 years ago • 8 comments

1)First syntax difference: From local to remote: scp file.txt [email protected]:c:\users\remoteuser\desktop

  • just folder at the end of destination and it will work, file.txt will be created on the remote in the desktop folder.

If from remote to local: scp [email protected]:c:\users\remoteuser\desktop\file.txt c:\users\user\desktop\file.txt

  • only with file.txt at the end it will work, not specifying a destination filename leads to an error, but program has been given the path and the name of a source file, couldn't it generate full filepath needed for the file transfering as in the first case?

Is it such by protocol and why so?

2)Second, perhaps bug:

  • scp c:\users\user\desktop\file.txt [email protected]:c:\users\remoteuser\desktop, оr even
  • scp "c:\users\user\desktop\file.txt" [email protected]:c:\users\remoteuser\desktop, or just
  • scp desktop\file.txt [email protected]:c:\users\remoteuser\desktop - specifying relative or absolute local path leads to strange concatenation between local and remote path in scp's local path internal representation, hence leads to an error. Only
  • scp file.txt [email protected]:c:\users\remoteuser\desktop works, with plain filename as a local source path, so that navigating through cd commands becomes the only option of successfull usage of scp forward syntax.

Should scp "c:\users\user\desktop\file.txt" be escaped in some more robust way that just quotes because of ":" and how, or is it an implementation-specific decision to work just with plain filename as a source in a forward from local to remote scp?

vritme avatar Jun 03 '22 17:06 vritme

I found here https://man.openbsd.org/scp.1 one line, that might be related to my question, and I'm not sure if I fully got it: Local file names can be made explicit using absolute or relative pathnames to avoid scp treating file names containing ‘:’ as host specifiers.

As it might be understood: Local file names can be made (by developers of ssh and scp implementation) explicit (obligatory, required, necessary, as they are right now in win32 openssh scp implementation) using absolute or relative pathnames (maybe it's about this destination check, that enforce specifying filename at the end of backward scp from remote to local) to avoid scp treating file names containing ‘:’ as host specifiers (it's clear that there is some logic behind making local filenames obligatory, but how it's made and why is not obvious).

But really it seems to be that this part of openbsd man is just about normal relative or absolute path adding to a filename in order to scp work "better" that with just plain file, which might cause 'treating file names containing ‘:’ as host specifiers', but this paths don't work in gitbash scp client (both win7 and win 10 tested) -> openssh server (win 10) in source in forward from remote to local scp request. Maybe the problem is on gitbash client scp side from gitbash, how is it possible to let them know about this issue?

Ps. Also ':' in windows is not allowed in filenames, is it in linux?

vritme avatar Jun 04 '22 08:06 vritme

Also no support for start or start /b methods in cmd, which are supposed to return whithout waiting, but that probably is explained in scope article as no support for background ssh execution, am I right?

vritme avatar Jun 05 '22 04:06 vritme

I'm using bit bash (mingw) as scp client by the way, so I do calls to scp.exe provided by git bash.

vritme avatar Jun 05 '22 05:06 vritme

I've just discovered, that if relative or absolute path is specified in local source in addition to filename, then scp expects output destination to also contain finame, like this:

scp c:\users\user\desktop\file.txt [email protected]:c:\users\remoteuser\desktop\file.txt

scp c:\users\user\desktop\file.txt [email protected]:c:\users\remoteuser\desktop\ - this is not working

vritme avatar Jun 05 '22 07:06 vritme

Ps. Also ':' in windows is not allowed in filenames, is it in linux?

Linux allows all characters and bytes other than / (forward slash) and \0 (ASCII NUL) in filenames. The colon has no special meaning in Linux filesystems (although it does in various Unix tools, most notably make, scp and anything expecting a URL). I think the manual sentence about using relative or absolute paths just says that OpenSSH does not look for a colon as a hostname separator beyond the first slash, therefore if you wanted to use a colon as a filename, you could write it as the trivial relative path ./:. (Prefixing a filename with ./ is a common trick to escape characters that may have special meanings to Unix tools at or near the start of a filename, e.g. rm ./-i to avoid the filename -i being misinterpreted as a command-line option.)

mgkuhn avatar Sep 16 '22 10:09 mgkuhn

Note that Win32 accepts both backslash \ (from MS-DOS) and forward slash / (from POSIX) as a path separator, but OpenSSH originally only supported the forward slash. So perhaps the code for transferring the filename to the destination directory path only works with the latter?

Have you tried pushing over all your slashes into the other direction?

mgkuhn avatar Sep 16 '22 10:09 mgkuhn

So, happily, I managed to find out all working commands needed to my windows-to-windows ssh interaction. Here they are:

Forward scp from local to remote:

  1. scp file.txt [email protected]:c:\users\remoteuser\desktop - works
  2. scp c:\users\user\desktop\file.txt [email protected]:c:\users\remoteuser\desktop\file.txt - works
  3. scp c:\users\user\desktop\file.txt [email protected]:c:\users\remoteuser\desktop\ - doesn't work

Backward scp from remote to local:

  1. scp [email protected]:c:\users\remoteuser\desktop\file.txt file.txt - works
  2. scp [email protected]:c:\users\remoteuser\desktop\file.txt c:\users\user\desktop\file.txt - works
  3. scp [email protected]:c:\users\remoteuser\desktop\file.txt c:\users\user\desktop\ - doesn't work

Note that Win32 accepts both backslash \ (from MS-DOS) and forward slash / (from POSIX) as a path separator, but OpenSSH originally only supported the forward slash. So perhaps the code for transferring the filename to the destination directory path only works with the latter?

I think that might be an explanation of this behaviour, especially considering forward slash after port in this URI format (which is useful while using custom port other that default 22) - scp://[user@]host[:port][/path].

As an experiment, I've tried this commands with forward slashes:

scp c:/users/user/desktop/file.txt [email protected]:c:/users/remoteuser/desktop scp [email protected]:c:/users/remoteuser/desktop/file.txt c:/users/user/desktop

And... it worked :). It was a little counterintuitive, because both client and server hosts do fully support backslashes and even use them as a default, whilst file trasfering program\protocol - in fact also supports them, but with some hardly explainable at first glance exceptions).

Thank you @mgkuhn, that was in depth). Now I'm almost like the Linus Torvalds in his best years :D.

vritme avatar Sep 16 '22 22:09 vritme

It was a little counterintuitive, because both client and server hosts do fully support backslashes

I'd have to check the source code, but my suspicion is that neither OpenSSH client nor server understand that the backslash can be a path separator, and that it just happens to work in all those cases where they just have to hand over the entire path to the filesystem API, which does support backslashes, but that it fails as soon as they have to manipulate a path themselves, e.g. in order to determine the filename from a path.

In portable applications, the general advice these days is to only use the forward slash as the path separator, as that is more widely understood. On Windows, cmd.exe is the main application that I know that doesn't support them (e.g., try path completion with back and forward slashes), as are most command-line applications that use the forward slash already to start their command-line options.

It's a messy subject. I wish I could travel back in time to urge Bill Gates not to sell off Xenix, and to base Windows NT on Xenix with an MS-DOS emulator on top (and not on essentially a VMS rewrite with an MS-DOS emulator on top, which is what we have ended up with), similar to how Steven Jobs replaced with OSX his legacy OS with a Unix-style system underneath.

mgkuhn avatar Sep 17 '22 10:09 mgkuhn