web-dev-qa-db-fra.com

Comment scp en python?

Quel est le moyen le plus pythonique de scp un fichier en Python? Le seul itinéraire que je connaisse est

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

qui est un hack, et qui ne fonctionne pas en dehors des systèmes de type Linux, et qui a besoin de l'aide du module Pexpect pour éviter les invites de mot de passe, à moins que vous n'ayez déjà configuré SSH sans mot de passe sur l'hôte distant.

Je suis au courant de conch de Twisted, mais je préférerais éviter de mettre en œuvre scp moi-même via des modules ssh de bas niveau.

Je suis au courant de paramiko, un module Python qui prend en charge ssh et sftp; mais cela ne supporte pas scp.

Contexte: je me connecte à un routeur qui ne prend pas en charge sftp mais ssh/scp. Par conséquent, sftp n'est pas une option.

EDIT: Il s'agit d'un doublon de Comment copier un fichier sur un serveur distant dans Python à l'aide de SCP ou SSH? . Cependant , cette question ne donne pas de réponse spécifique à scp qui traite les clés depuis python. J'espère un moyen d'exécuter du code un peu comme

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')
143
Michael Gundlach

Essayez le module paramiko_scp . C'est très facile à utiliser. Voir l'exemple suivant:

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())

Appelez ensuite scp.get () ou scp.put () pour effectuer des opérations scp.

( code SCPClient )

90
Tom Shen

Vous pourriez être intéressé à essayer Pexpect ( code source ). Cela vous permettrait de gérer les invites interactives pour votre mot de passe.

Voici un exemple d'utilisation (pour ftp) du site Web principal:

# 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')
14
Pat Notz

Vous pouvez également vérifier paramiko . Il n'y a pas encore de module scp, mais il supporte totalement sftp.

[EDIT] Désolé, vous avez manqué la ligne où vous avez parlé de paramiko. Le module suivant est simplement une implémentation du protocole scp pour paramiko. Si vous ne souhaitez pas utiliser paramiko ou conch (les seules implémentations SSH que je connaisse pour Python), vous pouvez retravailler cette opération pour qu'elle s'exécute sur une session SSH normale à l'aide de tubes.

scp.py pour paramiko

10
JimB

si vous installez PuTTY sur win32, vous obtenez un pscp (PuTTY scp).

vous pouvez donc aussi utiliser le hack os.system sur win32.

(et vous pouvez utiliser PuTTY-Agent pour la gestion des clés)


désolé, ce n'est qu'un hack (mais vous pouvez l'envelopper dans une classe python)

6
Blauohr

Impossible de trouver une réponse directe et ce module "scp.Client" n'existe pas. Au lieu de cela, ceci me convient:

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
Maviles

Jetez un coup d'œil à 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/')
5
user443854

Cela fait un bon bout de temps depuis que cette question a été posée et, entre-temps, une autre bibliothèque capable de gérer cette question est apparue: vous pouvez utiliser la fonction copie incluse dans le Plumbum = bibliothèque:

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
pmos

Vous pouvez utiliser le sous-processus de package et l'appel de commande pour utiliser la commande scp à partir du shell.

from subprocess import call

cmd = "scp user1@Host1:files user2@Host2:files"
call(cmd.split(" "))
4
user7529863

À ce jour, la meilleure solution est probablement 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)
3
Loïc

Il ya quelque temps, j’ai mis en place un script de copie SCP python _ qui dépend de paramiko. Il comprend un code permettant de gérer les connexions avec une clé privée ou un agent de clé SSH avec un repli sur l’authentification par mot de passe.

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

1
ccpizza

Si vous êtes sur * nix, vous pouvez utiliser sshpass

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

Hmmm, une autre option serait peut-être d'utiliser quelque chose comme sshfs (il y a un sshfs pour Mac aussi). Une fois que votre routeur est monté, vous pouvez simplement copier les fichiers directement. Je ne sais pas si cela fonctionne pour votre application particulière, mais c'est une solution intéressante à garder à portée de main.

1
Pat Notz