jbardin / scp.py

scp module for paramiko
Other
529 stars 139 forks source link

Fix put with trailing slash #161

Closed remram44 closed 2 years ago

remram44 commented 3 years ago

From @etirta @ https://github.com/jbardin/scp.py/issues/146#issuecomment-871867990

Fixes #146

remram44 commented 3 years ago

@etirta The difference in behavior you mentioned appears here: https://github.com/jbardin/scp.py/blob/8e8c6c2460747a8b0479469bcfb26a76486925b5/test.py#L254-L261

I believe it works similarly to rsync, but command-line scp doesn't seem to behave that way, so I am not entirely sure what we should do. Either is better than the current crashing behavior of course.

etirta commented 3 years ago

@remram In my undertsanding, scp is actually using rcp protocol, except it's done on top of SSH tunnel. Hence, I wouldn't be surprise if rsync is also using the same protocol as rcp. So yeah, I believe you are correct that it should works similarly to rsync. But may be the implementation on how to handle the src path locally is different between rsync and scp command line utility.

Re: scp command line utility, It is not a big deal if when one execute scp /path/to/src/ rmtUser@rmtHost:/path/to/dst/ ends up with /path/to/dst/src/src-content..., as one can easily resort to shell globbing scp /path/to/src/* rmtUser@rmtHost:/path/to/dst/ in order to get /path/to/dst/src-content.... But inside a program, glob is not as trivia as while in shell :).

FYI, I did end up using glob as workaround, hopefully until this proposal get merged into a newer PySCP version. So from: scpTgt.put(f'{tmp_path}/{dstRoot}/', f'{rmtPath}/', recurse=True) But since it works the way I wanted only towards older scp in the remote host, my workaround is: scpTgt.put((*(str(p) for p in pathlib.Path(f'{tmp_path}/{dstRoot}/').glob('*')),), f'{rmtPath}/', recurse=True)

So it is possible the rsync command line utility is doing similar in the above when the user give src path as a directory.

Cheers