Linux 带有 paramiko 的 SCP,使用不同的远程和本地目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10338911/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:01:02  来源:igfitidea点击:

SCP with paramiko, using different remote and local directories

pythonlinuxparamiko

提问by Federico Sciarretta

I have a Python code that uses Paramiko.

我有一个使用 Paramiko 的 Python 代码。

#!/usr/bin/env python

import paramiko

username = ('user')
password = ('1234')
hostname = ('test-server.com')
ports = 22
localD = ('/var/tmp/testxxxxxxxx.tar.gz')
remoteD = ('/var/tmp/testxxxxxxxx.tar.gz')



paramiko.util.log_to_file('/tmp/paramiko.log')
transport = paramiko.Transport((hostname, ports))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put(remotepath=remoteD, localpath=localD)

sftp.close()
transport.close()

With this code, the local-dir and the remote-dir should be equals. if not "file not found" How can I change or use another remote-dir different to local-dir? Example:

使用此代码,local-dir 和 remote-dir 应该相等。如果不是“找不到文件”,我如何更改或使用与本地目录不同的另一个远程目录?例子:

localD = ('/var/tmp/testxxxxxxxx.tar.gz')
remoteD = ('/home/user/testxxxxxxxx.tar.gz')

Thank you

谢谢

采纳答案by John Gaines Jr.

Since the error message says 'No such file or directory', I'd first check to make sure the directory exists on remote system and is writable by the credentials you're using. The SFTPClient class has all sorts of other methods you can call to verify the existence of target paths and create them if they don't exist yet.

由于错误消息显示“没有这样的文件或目录”,我首先检查以确保该目录存在于远程系统上并且可以由您使用的凭据写入。SFTPClient 类具有各种其他方法,您可以调用这些方法来验证目标路径是否存在,如果尚不存在则创建它们。

For example, calling the stat() method passing in the destination path should give you back a tuple the same as that returned by os.stat. Try running this script (I just hacked up a little path check routine and dropped it into your script):

例如,调用传入目标路径的 stat() 方法应该会返回一个与 os.stat 返回的元组相同的元组。尝试运行此脚本(我只是编写了一个小路径检查例程并将其放入您的脚本中):

#!/usr/bin/env python

import paramiko

username = ('user')
password = ('1234')
hostname = ('test-server.com')
ports = 22
localD = ('/var/tmp/testxxxxxxxx.tar.gz')
remoteD = ('/var/tmp/testxxxxxxxx.tar.gz')

def check(sftp, path):
    parts = path.split('/')
    for n in range(2, len(parts) + 1):
        path = '/'.join(parts[:n])
        print 'Path:', path,
        sys.stdout.flush()
        try:
            s = sftp.stat(path)
            print 'mode =', oct(s.st_mode)
        except IOError as e:
            print e

paramiko.util.log_to_file('/tmp/paramiko.log')
transport = paramiko.Transport((hostname, ports))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
check(sftp, remoteD)

sftp.close()
transport.close()

Output should be something like this:

输出应该是这样的:

Path: /var mode = 040755
Path: /var/tmp mode = 040700
Path: /var/tmp/testxxxxxxxx.tar.gz [Errno 2] No such file

The mode numbers will most likely differ, but you shouldn't get "No such file" error on any of the parts of the path other than the file name. If you do, then it probably means you need to construct the path down to the point where you want to put the file using sftp.mkdir()

模式编号很可能会有所不同,但您不应在路径的任何部分(文件名以外的部分)出现“无此类文件”错误。如果这样做,则可能意味着您需要使用 sftp.mkdir() 构建路径到要放置文件的位置

回答by lkcl

this is sftp, it's not SCP. when connecting to devices which have dropbear (such as those on OpenWRT) there isno sftp sub-system, so sftp fails. instead i use a tar command (paramiko abstracted behind the "connect" function.

这是 sftp,不是 SCP。连接到具有dropbear(如那些上的OpenWRT)设备时,有没有SFTP子系统,所以SFTP失败。相反,我使用 tar 命令(paramiko 在“connect”函数后面抽象。

i am however looking for actualSCP over paramiko and unfortunately the answer here, which is at the top of a google search, doesn't actuallyanswer the question.

然而,我正在通过 paramiko寻找实际的SCP,不幸的是,这里的答案位于谷歌搜索的顶部,实际上并没有回答这个问题。

# argh argh argh dropbear on openwrt not compiled with sftp
# have to use some horribleness...

tw = connect(ipaddr, "root", server_root_password, command="tar xvf -",
             debug_level=debug_level)

tf = StringIO()
tar = tarfile.open(mode= "w:", fileobj = tf)
taradd(tar, "etc/tinc/....")
taradd(tar, ".....", ...)
taradd(tar, "....", ...)
taradd(tar, "etc/init.d/tinc", ...., ex=True)
tar.close()

tf.seek(0)
txt = tf.read()
tw.t.write(txt)
tw.t.write('^D')
tw.t.w.close()
tw.t.w = None
tw.close()

回答by lkcl

https://github.com/jbardin/scp.py

https://github.com/jbardin/scp.py

far from not actually answering the question which is asked, the above code provides an actual implementation of scp that is compatible with the openssh SCP protocol. personally i've not tested it with dropbear yet but it is code that actually answers the question that's in the subject line.

上面的代码并没有真正回答所提出的问题,而是提供了与 openssh SCP 协议兼容的 scp 的实际实现。我个人还没有用 dropbear 测试过它,但它是实际回答主题行中问题的代码。

SCP != SFTP.

SCP != SFTP。