如何在Python中使用scp?
在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操作。