如何在Python中使用scp?

225 投票
13 回答
393572 浏览
提问于 2025-04-11 17:56

在Python中,最“Pythonic”的方式来使用scp传输文件是什么?我知道的唯一方法是

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

但这其实是个小技巧,而且只能在类Linux系统上工作。如果你没有设置无密码SSH连接到远程主机的话,还需要用到Pexpect模块来避免输入密码。

我知道Twisted的conch,但我不想通过低级的ssh模块自己实现scp。

我还知道paramiko,这是一个支持SSH和SFTP的Python模块;不过它不支持SCP。

背景:我正在连接一个不支持SFTP但支持SSH/SCP的路由器,所以SFTP对我来说不是一个选项。

编辑: 这个问题和如何在Python中使用SCP或SSH将文件复制到远程服务器?是重复的。不过,那个问题没有给出一个专门针对scp的答案,特别是如何在Python中处理密钥。我希望能找到一种方法来运行类似于

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 个回答

15

我找不到一个明确的答案,而且这个 "scp.Client" 模块根本不存在。相反,这个对我来说更合适:

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')
17

你可能会想试试 Pexpect源代码)。这个工具可以帮助你处理需要输入密码的互动提示。

下面是官网上关于如何使用它(以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')
163

试试这个Python的scp模块,配合Paramiko使用。它非常简单易用。下面是一个例子:

import paramiko
from scp import SCPClient

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代码)

撰写回答