Как scp в питоне? - PullRequest
       145

Как scp в питоне?

141 голосов
/ 30 октября 2008

Какой самый питонный способ scp файла в Python? Единственный маршрут, о котором я знаю, это

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

, который является хаком, и который не работает вне linux-подобных систем, и который нуждается в помощи модуля Pexpect, чтобы избежать запросов пароля, если у вас уже не установлен SSH без пароля для удаленного хоста.

Мне известно о conch в Twisted, но я бы предпочел избегать реализации scp самостоятельно через низкоуровневые ssh-модули.

Мне известно о paramiko, модуле Python, который поддерживает ssh и sftp; но он не поддерживает scp.

Справочная информация: я подключаюсь к маршрутизатору, который не поддерживает sftp, но поддерживает ssh / scp, поэтому sftp не подходит.

EDIT : Это дубликат Как скопировать файл на удаленный сервер в 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 ]

87 голосов
/ 26 ноября 2010

Попробуйте модуль paramiko_scp . Это очень просто в использовании. Смотрите следующий пример:

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 код )

13 голосов
/ 30 октября 2008

Возможно, вам будет интересно попробовать 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')
10 голосов
/ 30 октября 2008

Вы также можете проверить paramiko . Там нет модуля scp (пока), но он полностью поддерживает sftp.

[EDIT] Извините, пропустил строку, где вы упомянули paramiko. Следующий модуль является просто реализацией протокола scp для paramiko. Если вы не хотите использовать paramiko или conch (единственные реализации ssh, которые я знаю для python), вы можете переделать это, чтобы запустить обычный сеанс ssh с использованием каналов.

scp.py для парамико

6 голосов
/ 24 июля 2016

Не удалось найти прямой ответ, и этот модуль "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')
6 голосов
/ 30 октября 2008

если вы установите putty на win32, вы получите pscp (putty scp).

, чтобы вы могли использовать хак os.system и на win32.

(и вы можете использовать замазку для управления ключами)


извините, это всего лишь взлом (но вы можете обернуть его в класс Python)

4 голосов
/ 07 февраля 2017

Вы можете использовать подпроцесс пакета и вызов команды, чтобы использовать команду scp из оболочки.

from subprocess import call

cmd = "scp user1@host1:files user2@host2:files"
call(cmd.split(" "))
4 голосов
/ 05 июля 2014

Прошло много времени с тех пор, как был задан этот вопрос, и в то же время появилась другая библиотека, которая может справиться с этим: Вы можете использовать функцию copy , включенную в библиотеку Plumbum :

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)
4 голосов
/ 23 ноября 2011

Посмотрите на fabric.transfer .

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/')
2 голосов
/ 19 мая 2018

На сегодняшний день лучшее решение, вероятно, AsyncSSH

https://asyncssh.readthedocs.io/en/latest/#scp-client

async with asyncssh.connect('host.tld') as conn:
    await asyncssh.scp((conn, 'example.txt'), '.', recurse=True)
1 голос
/ 21 мая 2012

Я недавно создал сценарий копирования SCP на python, который зависит от paramiko. Он включает в себя код для обработки соединений с секретным ключом или агентом ключа SSH с отступлением от аутентификации по паролю.

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

...