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

时间:2020-03-05 18:54:53  来源:igfitidea点击:

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

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

解决方案

回答

如果我们想要简单的方法,这应该可行。

我们需要首先" .close()"文件,以便我们知道它已从Python刷新到磁盘。

import os
os.system("scp FILE USER@SERVER:PATH")
#e.g. os.system("scp foo.bar [email protected]:/path/to/foo.bar")

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

ssh-keygen示例

回答

有点骇人听闻,但以下方法应该可以:)

import os
filePath = "/foo/bar/baz.py"
serverPath = "/blah/boo/boom.py"
os.system("scp "+filePath+" [email protected]:"+serverPath)

回答

我们可能会使用子流程模块。像这样的东西:

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

其中"目的地"的格式可能是" 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+版本,我将使用子流程模块。

回答

要使用Paramiko库在Python中执行此操作(即不通过subprocess.Popen或者类似程序包装scp),我们需要执行以下操作:

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()

(我们可能希望处理未知的主机,错误,创建任何必要的目录等)。