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

144 投票
14 回答
395521 浏览
提问于 2025-04-11 09:16

我在本地电脑上有一个文本文件,这个文件是通过每天运行的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 就可以自动用你的公钥进行身份验证(换句话说,你的脚本就不会要求输入密码了)。

撰写回答