如何使用SCP或SSH将文件复制到Python中的远程服务器?

如何使用SCP或SSH将文件复制到Python中的远程服务器?

How to copy a file to a remote server in Python using SCP or SSH?

我在本地计算机上有一个文本文件,它由在cron中运行的每日Python脚本生成。

我想添加一些代码,以便通过SSH将该文件安全地发送到我的服务器。


要使用Paramiko库在Python中执行此操作(即不通过subprocess.Popen或类似方法包装scp),您可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
import os
import paramiko

ssh = paramiko.SSHClient()
ssh.load_host_keys(os.path.expanduser(os.path.join("~",".ssh","known_hosts")))
ssh.connect(server, username=username, password=password)
sftp = ssh.open_sftp()
sftp.put(localpath, remotepath)
sftp.close()
ssh.close()

(您可能希望处理未知主机,错误,创建所需的任何目录,等等)。


如果你想要简单的方法,这应该工作。

你首先想要".close()"这个文件,所以你知道它是从Python刷新到磁盘的。

1
2
3
import os
os.system("scp FILE USER@SERVER:PATH")
#e.g. os.system("scp foo.bar joe@srvr.net:/path/to/foo.bar")

您需要生成(在源计算机上)并预先安装(在目标计算机上)ssh密钥,以便scp自动使用您的公共ssh密钥进行身份验证(换句话说,因此您的脚本不会要求输入密码) 。

ssh-keygen示例


您可能使用子进程模块。像这样的东西:

1
2
3
import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)

其中destination可能是user@remotehost:remotepath的形式。谢谢
@Charles Duffy指出我原来答案中的弱点,它使用单个字符串参数来指定scp操作shell=True - 它不会处理路径中的空格。

模块文档包含您可能希望与此操作一起执行的错误检查示例。

确保您已设置正确的凭据,以便可以在计算机之间执行无人值守的无密码scp。有一个stackoverflow问题已经存在。


有几种不同的方法可以解决这个问题:

  • 包装命令行程序
  • 使用提供SSH功能的Python库(例如 - Paramiko或Twisted Conch)
  • 每种方法都有自己的怪癖。如果要包装"ssh","scp"或"rsync"等系统命令,则需要设置SSH密钥以启用无密码登录。您可以使用Paramiko或其他库在脚本中嵌入密码,但您可能会发现缺少文档令人沮丧,特别是如果您不熟悉SSH连接的基础知识(例如 - 密钥交换,代理等)。毫无疑问,SSH密钥几乎总是比这类东西的密码更好。

    注意:如果您计划通过SSH传输文件,它很难击败rsync,特别是如果替代方案是普通的旧scp。

    我已经使用了Paramiko来关注更换系统调用,但由于易于使用和直接熟悉,我发现自己被回归到包装的命令。你可能会有所不同。我不久前给了海螺一次,但它并没有吸引我。

    如果选择系统调用路径,Python提供了一系列选项,如os.system或命令/子进程模块。如果使用版本2.4+,我会使用子进程模块。


    达到了同样的问题,但不是"黑客"或模拟命令行:

    在这里找到这个答案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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')

    您可以执行类似的操作,以处理主机密钥检查

    1
    2
    import os
    os.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path username@hostname:remote_path")


    fabric可用于通过ssh上传文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/env python
    from fabric.api import execute, put
    from fabric.network import disconnect_all

    if __name__=="__main__":
        import sys
        # specify hostname to connect to and the remote/local paths
        srcdir, remote_dirname, hostname = sys.argv[1:]
        try:
            s = execute(put, srcdir, remote_dirname, host=hostname)
            print(repr(s))
        finally:
            disconnect_all()

    您可以使用专为此设计的vassal包。

    你所需要的只是安装vassal并做

    1
    2
    3
    from vassal.terminal import Terminal
    shell = Terminal(["scp username@host:/home/foo.txt foo_local.txt"])
    shell.run()

    此外,它将为您节省身份验证凭据,而无需一次又一次地键入它们。


    如果您不想使用SSL证书,请尝试此操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import subprocess

    try:
        # Set scp and ssh data.
        connUser = 'john'
        connHost = 'my.host.com'
        connPath = '/home/john/'
        connPrivateKey = '/home/user/myKey.pem'

        # Use scp to send file from local to host.
        scp = subprocess.Popen(['scp', '-i', connPrivateKey, 'myFile.txt', '{}@{}:{}'.format(connUser, connHost, connPath)])

    except CalledProcessError:
        print('ERROR: Connection to host failed!')

    我使用sshfs通过ssh挂载远程目录,并使用shutil复制文件:

    1
    2
    $ mkdir ~/sshmount
    $ sshfs user@remotehost:/path/to/remote/dst ~/sshmount

    然后在python中:

    1
    2
    import shutil
    shutil.copy('a.txt', '~/sshmount')

    此方法的优点是,如果要生成数据而不是本地缓存并发送单个大文件,则可以流式传输数据。


    一个非常简单的方法如下:

    1
    2
    import os
    os.system('sshpass -p"password" scp user@host:/path/to/file ./')

    不需要python库(只有操作系统),它的工作原理


    使用外部资源paramiko;

    1
    2
    3
    4
    5
    6
    7
    8
    9
        from paramiko import SSHClient
        from scp import SCPClient
        import os

        ssh = SSHClient()
        ssh.load_host_keys(os.path.expanduser(os.path.join("~",".ssh","known_hosts")))
        ssh.connect(server, username='username', password='password')
        with SCPClient(ssh.get_transport()) as scp:
                scp.put('test.txt', 'test2.txt')

    通过子进程调用scp命令不允许在脚本中接收进度报告。 pexpect可用于提取该信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import pipes
    import re
    import pexpect # $ pip install pexpect

    def progress(locals):
        # extract percents
        print(int(re.search(br'(\d+)%$', locals['child'].after).group(1)))

    command ="scp %s %s" % tuple(map(pipes.quote, [srcfile, destination]))
    pexpect.run(command, events={r'\d+%': progress})

    查看本地网络中的python copy文件(linux - > linux)


    有点hacky,但以下应该工作:)

    1
    2
    3
    4
    import os
    filePath ="/foo/bar/baz.py"
    serverPath ="/blah/boo/boom.py"
    os.system("scp"+filePath+" user@myserver.com:"+serverPath)


    推荐阅读

      计算机主板BIOS设置详细-BIOS知识

      计算机主板BIOS设置详细-BIOS知识,,什么是电脑BIOS,一般电脑主板已经设置完毕后,电脑就开始按del键进入BIOS。系统启动BIOS,即微机的基本输入

      计算机蓝屏故障的计算机蓝屏解决方案

      计算机蓝屏故障的计算机蓝屏解决方案,,电脑蓝屏电脑故障经常使用电脑的朋友经常遇到,因为电脑蓝屏是一个非常普遍的现象,所以很难预测,什么时

      计算机自动关机的原因是什么

      计算机自动关机的原因是什么,,计算机(计算机),通常称为计算机,是一种用于高速计算的电子计算机。它可以进行数值计算和逻辑计算,还具有存储记忆

      电脑功率计算|电脑功率计算公式

      电脑功率计算|电脑功率计算公式,,电脑功率计算公式  从设计角度出发一般取300w/台基本都可以满足要求,可以从以下几个方面分析一下电脑功

      如何设置计算机视图视图的统一视图

      如何设置计算机视图视图的统一视图,,不知道你是否有这样的使用电脑经验,电脑在不同的文件夹打开,有时这个文件夹是用来查看列表的方式,但是当

      的故障_计算机解决无法打印文档

      的故障_计算机解决无法打印文档,,核心提示:最近,打印机出现了一个奇怪的现象,在打印正常之前,打印机不能打印最近的突然,提示发送打印作业,计算

      PC计算机:AMDCPU核心细节

      PC计算机:AMDCPU核心细节,,核心提示:AthlonXP的核心型athlonxp有4种不同的核心类型,但都有个共同点:他们都使用socketa接口,他们都使用PR标称值

      分析计算机减速的原因

      分析计算机减速的原因,,核心提示:做以上九点,我相信你的爱是快的。当然,如果速度很慢,你应该考虑硬件升级。学习电脑组装,就来吧… 有很多人说