如何在Python中使用SCP或SSH将文件复制到远程服务器?
我在本地电脑上有一个文本文件,这个文件是通过每天运行的Python脚本生成的,脚本是通过cron这个工具来定时执行的。
我想加一点代码,把这个文件安全地通过SSH发送到我的服务器上。
14 个回答
34
你可能会用到 subprocess模块。大概可以这样写:
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的问题可以参考。
183
要在Python中做到这一点(也就是说,不通过subprocess.Popen或类似的方法来使用scp),可以使用Paramiko这个库,代码大概是这样的:
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()
(你可能还需要处理一些未知主机、错误、创建必要的目录等等问题)。
75
你可以使用 scp
这个命令来复制文件,它是通过 SSH 来进行的。你可以用 subprocess.run
来调用这个命令:
import subprocess
subprocess.run(["scp", FILE, "USER@SERVER:PATH"])
#e.g. subprocess.run(["scp", "foo.bar", "joe@srvr.net:/path/to/foo.bar"])
如果你是在同一个 Python 程序里创建要发送的文件,那么你需要在打开文件的 with
块之外调用 subprocess.run
命令(或者如果你没有使用 with
块,先调用 .close()
来关闭文件),这样你就能确保文件已经从 Python 写入到磁盘上。
你需要提前在源机器上生成一个 ssh 密钥,并在目标机器上安装这个密钥,这样 scp
就可以自动用你的公钥进行身份验证(换句话说,你的脚本就不会要求输入密码了)。