首页 文章

如何在python scp?

提问于
浏览
135

在Python中scp文件的最pythonic方法是什么?我所知道的唯一途径是

os.system('scp "%s" "%s:%s"' % (localfile, remotehost, remotefile) )

这是一个hack,并且在类似Linux的系统之外不起作用,并且需要Pexpect模块的帮助以避免密码提示,除非您已经将无密码SSH设置到远程主机 .

我'm aware of Twisted' s conch ,但我宁愿避免通过低级ssh模块自己实现scp .

我知道 paramiko ,一个支持ssh和sftp的Python模块;但它不支持scp .

背景:我正在连接到不支持sftp但支持ssh / scp的路由器,所以sftp不是一个选项 .

EDIT :这是How to copy a file to a remote server in Python using SCP or SSH?的副本 . However ,那个问题并没有希望找到一种运行代码的方式

import scp

client = scp.Client(host=host, user=user, keyfile=keyfile)
# or
client = scp.Client(host=host, user=user)
client.use_system_keys()
# or
client = scp.Client(host=host, user=user, password=password)

# and then
client.transfer('/etc/local/filename', '/etc/remote/filename')

13 回答

  • 6

    你也可以看看paramiko . 目前还没有scp模块,但它完全支持sftp .

    [编辑]抱歉,错过了你提到paramiko的路线 . 以下模块只是paramiko的scp协议的一个实现 . 如果你不想使用paramiko或conch(我知道python的唯一ssh实现),你可以重做这个以使用管道运行常规ssh会话 .

    scp.py for paramiko

  • 0

    如果你在win32上安装putty你得到一个pscp(putty scp) .

    所以你也可以在win32上使用os.system hack .

    (并且您可以使用油灰剂进行密钥管理)


    对不起它只是一个黑客(但你可以把它包装在一个python类)

  • 3

    截至今天,最好的解决方案可能是 AsyncSSH

    https://asyncssh.readthedocs.io/en/latest/#scp-client

    async with asyncssh.connect('host.tld') as conn:
        await asyncssh.scp((conn, 'example.txt'), '.', recurse=True)
    
  • 6

    没有't find a straight answer, and this 1397362 module doesn'存在 . 相反,this适合我:

    from paramiko import SSHClient
    from scp import SCPClient
    
    ssh = SSHClient()
    ssh.load_system_host_keys()
    ssh.connect('example.com')
    
    with SCPClient(ssh.get_transport()) as scp:
       scp.put('test.txt', 'test2.txt')
       scp.get('test2.txt')
    
  • 13

    如果你在* nix上你可以使用sshpass

    sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path
    
  • 1

    我没有't think there'任何一个你可以轻松下载来实现scp的模块,但是你可能会觉得这很有用:http://www.ibm.com/developerworks/linux/library/l-twist4.html

  • 4

    自从提出这个问题以来已经有一段时间了,与此同时,另一个可以解决这个问题的库已经出现了:您可以使用Plumbum库中包含的copy函数:

    import plumbum
    r = plumbum.machines.SshMachine("example.net")
       # this will use your ssh config as `ssh` from shell
       # depending on your config, you might also need additional
       # params, eg: `user="username", keyfile=".ssh/some_key"`
    fro = plumbum.local.path("some_file")
    to = r.path("/path/to/destination/")
    plumbum.path.utils.copy(fro, to)
    
  • -2

    看看fabric . 可以找到一个例子here .

  • 85

    您可以使用package子进程和命令调用来使用shell中的scp命令 .

    from subprocess import call
    
    cmd = "scp user1@host1:files user2@host2:files"
    call(cmd.split(" "))
    
  • 9

    嗯,也许另一种选择是使用像sshfs这样的东西(Mac也有sshfs) . 安装路由器后,您可以直接复制文件 . 我是一个很好的解决方案,可以保持方便 .

  • 1

    我刚才把一个依赖于paramiko的python SCP副本放在一起 . 它包括用于处理与私钥或SSH密钥代理的连接以及回退到密码身份验证的代码 .

    http://code.activestate.com/recipes/576810-copy-files-over-ssh-using-paramiko/

  • 3

    试试模块paramiko_scp . 它非常易于使用 . 请参阅以下示例:

    def createSSHClient(server, port, user, password):
        client = paramiko.SSHClient()
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(server, port, user, password)
        return client
    
    ssh = createSSHClient(server, port, user, password)
    scp = SCPClient(ssh.get_transport())
    

    然后调用scp.get()或scp.put()来执行scp操作 .

    SCPClient code

  • 1

    您可能有兴趣尝试PexpectSourceForge project) . 这将允许您处理密码的交互式提示 .

    以下是主网站上的示例用法(对于ftp):

    # This connects to the openbsd ftp site and
       # downloads the recursive directory listing.
       import pexpect
       child = pexpect.spawn ('ftp ftp.openbsd.org')
       child.expect ('Name .*: ')
       child.sendline ('anonymous')
       child.expect ('Password:')
       child.sendline ('noah@example.com')
       child.expect ('ftp> ')
       child.sendline ('cd pub')
       child.expect('ftp> ')
       child.sendline ('get ls-lR.gz')
       child.expect('ftp> ')
       child.sendline ('bye')
    

相关问题