关于ssh:如何在python中scp?

How to scp in python?

在python中使用scp文件最简单的方法是什么?我唯一知道的路线是

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

这是一种黑客行为,它在Linux系统之外不起作用,需要pexpect模块的帮助以避免密码提示,除非您已经为远程主机设置了无密码ssh。

我知道Twisted的conch,但我宁愿避免自己通过低级ssh模块实现scp。

我知道paramiko,一个支持ssh和sftp的python模块;但它不支持scp。

背景:我正在连接一个不支持sftp但支持ssh/scp的路由器,所以sftp不是一个选项。

编辑:这是如何使用scp或ssh将文件复制到python中的远程服务器的副本?但是,这个问题并没有给出处理来自Python内部的密钥的特定于SCP的答案。我希望能找到一种运行代码的方法

1
2
3
4
5
6
7
8
9
10
11
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')

尝试模块Paramiko_SCP。它很容易使用。请参见以下示例:

1
2
3
4
5
6
7
8
9
10
11
12
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操作。

(SCP客户端代码)


您可能对尝试pexpect(源代码)感兴趣。这将允许您处理输入密码的交互式提示。

以下是主网站上的示例用法(用于ftp)截图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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 ('[email protected]')
child.expect ('ftp> ')
child.sendline ('cd pub')
child.expect('ftp> ')
child.sendline ('get ls-lR.gz')
child.expect('ftp> ')
child.sendline ('bye')


你也可以去看看帕拉米科。目前还没有SCP模块,但它完全支持SFTP。

[编辑]抱歉,错过了你提到帕拉米科的那一行。下面的模块只是Paramiko的SCP协议的一个实现。如果您不想使用paramiko或conch(我知道的针对python的唯一ssh实现),您可以重新编写它,使用管道在常规的ssh会话上运行。

帕拉米科的SCP.PY


找不到直接答案,此"scp.client"模块不存在。相反,这很适合我:

1
2
3
4
5
6
7
8
9
10
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')

如果您在win32上安装putty,您将得到一个pscp(putty scp)。

所以您也可以在win32上使用os.system hack。

(可使用腻子剂进行钥匙管理)

对不起,这只是一个黑客(但您可以用Python类包装它)


您可以使用包子进程和命令调用来使用shell中的scp命令。

1
2
3
4
from subprocess import call

cmd ="scp user1@host1:files user2@host2:files"
call(cmd.split(""))


问这个问题已经很久了,与此同时,又出现了另一个可以处理这个问题的库:可以使用Plumbum库中包含的复制功能:

1
2
3
4
5
6
7
8
import plumbum
r = plumbum.machines.SshMachine("example.net")
   # this will use your ssh config as `ssh` from shell
   # depending on your config, you might also need additional
   # params, eg: `user="username", keyfile=".ssh/some_key"`
fro = plumbum.local.path("some_file")
to = r.path("/path/to/destination/")
plumbum.path.utils.copy(fro, to)


看看织物。转移。

1
2
3
4
5
6
7
from fabric import Connection

with Connection(host="hostname",
                user="admin",
                connect_kwargs={"key_filename":"/home/myuser/.ssh/private.key"}
               ) as c:
    c.get('/foo/bar/file.txt', '/tmp/')


到目前为止,最好的解决方案可能是AsyncSSH

https://asyncsh.readthedocs.io/en/latest/scp客户端

1
2
async with asyncssh.connect('host.tld') as conn:
    await asyncssh.scp((conn, 'example.txt'), '.', recurse=True)

不久前,我编写了一个依赖于paramiko的python scp复制脚本。它包括用于处理与私钥或ssh密钥代理之间的连接的代码,以及返回密码验证的代码。

http://code.activestate.com/recipes/576810-copy-files-over-ssh-using-paramiko/


嗯,也许另一个选择是使用类似sshfs的东西(Mac也有一个sshfs)。一旦你的路由器被挂载,你就可以直接复制文件。我不确定这是否适用于您的特定应用程序,但这是一个很好的解决方案,可以随时使用。


如果您在*nix上,可以使用sshspass

1
sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path

我认为没有任何一个模块可以轻松下载来实现SCP,但是您可能会发现这很有用:http://www.ibm.com/developerworks/linux/library/l-twist4.html