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')
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 )
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')
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.
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)
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')
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/')
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)
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(" "))
À 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)
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/
Si vous êtes sur * nix, vous pouvez utiliser sshpass
sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path
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.