¿Cómo scp en python?

¿Cuál es la forma más pirónica de crear un archivo en Python? La única ruta que conozco es

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

que es un truco, y que no funciona fuera de los sistemas similares a Linux, y que necesita ayuda del módulo Pexpect para evitar las solicitudes de contraseña, a menos que ya tenga configurado SSH sin contraseña para el host remoto.

Soy consciente de la conch de Twisted, pero preferiría evitar la implementación de scp a través de módulos ssh de bajo nivel.

Soy consciente de paramiko , un módulo de Python que soporta ssh y sftp; pero no soporta scp.

Antecedentes: me estoy conectando a un enrutador que no admite sftp pero sí es compatible con ssh / scp, por lo que sftp no es una opción.

EDITAR : Este es un duplicado de ¿Cómo copiar un archivo a un servidor remoto en Python usando SCP o SSH? . Sin embargo , esa pregunta no da una respuesta específica de scp que trate con claves desde Python. Espero una forma de ejecutar código como

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

Prueba el módulo paramiko_scp . Es muy fácil de usar. Vea el siguiente ejemplo:

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

Luego llame a scp.get () o scp.put () para realizar operaciones de scp.

( Código SCPClient )

Puede estar interesado en probar Pexpect ( código fuente ). Esto le permitiría lidiar con indicaciones interactivas para su contraseña.

Aquí hay un ejemplo de uso (para ftp) del sitio 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 ('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') 

También puedes echarle un vistazo a paramiko . No hay un módulo de scp (todavía), pero es totalmente compatible con sftp.

[EDITAR] Lo sentimos, perdí la línea donde mencionaste a paramiko. El siguiente módulo es simplemente una implementación del protocolo scp para paramiko. Si no desea usar paramiko o conch (las únicas implementaciones de ssh que conozco para python), puede volver a trabajar para ejecutar una sesión de ssh normal utilizando tuberías.

scp.py para paramiko

si instala masilla en win32 obtendrá un pscp (masilla scp).

para que pueda utilizar el sistema operativo OS.system en Win32 también.

(y puede utilizar el putty-agent para la gestión de claves)


lo siento, solo es un hack (pero puedes envolverlo en una clase de python)

No se pudo encontrar una respuesta directa, y este módulo “scp.Client” no existe. En su lugar, esto me conviene:

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

Puede usar el subproceso del paquete y la llamada de comando para usar el comando scp desde el shell.

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

Ha pasado bastante tiempo desde que se hizo esta pregunta, y mientras tanto, surgió otra biblioteca que puede manejar esto: puede usar la función de copia incluida en la biblioteca 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) 

Echa un vistazo a la tela .

 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/') 

A partir de hoy, la mejor solución es probablemente 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) 

Hmmm, quizás otra opción sería usar algo como sshfs (también hay sshfs para Mac). Una vez que haya montado el enrutador, puede copiar los archivos directamente. No estoy seguro de si eso funciona para su aplicación en particular, pero es una buena solución para tener a mano.

Hace un tiempo, armé un script de copia SCP de python que depende de paramiko. Incluye código para manejar conexiones con una clave privada o un agente de clave SSH con un respaldo a la autenticación de contraseña.

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

Si estás en * nix puedes usar sshpass

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

No creo que haya un módulo que pueda descargar fácilmente para implementar scp, sin embargo, podría encontrarlo útil: http://www.ibm.com/developerworks/linux/library/l-twist4.html