2008-10-30 16 views
122

¿Cuál es la forma más pitónica de analizar un archivo en Python? La única ruta que soy consciente es deCómo capturar python?

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

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

Conozco Twisted's conch, pero prefiero evitar la implementación de scp a través de los módulos ssh de bajo nivel.

Conozco paramiko, un módulo de Python que admite ssh y sftp; pero no es compatible con scp.

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

EDIT: Esto es un duplicado de How to copy a file to a remote server in Python using SCP or SSH?. Sin embargo,, esa pregunta no proporciona una respuesta específica de scp que trate las claves desde dentro de python. Estoy esperando una forma de ejecutar código de clase como de

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

Respuesta

4

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

por lo que puede utilizar el truco os.system en win32 también.

(y se puede utilizar la masilla-agente para la clave-managment)


lo siento, no es más que un truco (pero se puede envolver en una clase de Python)

+0

La única razón por la que funciona 'nix es que tiene SCP en la ruta; como señala Blauohr, eso no es demasiado difícil de arreglar. +1 – ojrac

12

Usted puede ser interesado en probar Pexpect (SourceForge project). Esto le permitiría tratar con indicaciones interactivas para su contraseña.

Aquí hay un recorte de ejemplo de uso (por FTP) desde el 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 ('[email protected]') 
    child.expect ('ftp> ') 
    child.sendline ('cd pub') 
    child.expect('ftp> ') 
    child.sendline ('get ls-lR.gz') 
    child.expect('ftp> ') 
    child.sendline ('bye') 
1

Hmmm, tal vez otra opción sería utilizar algo así como sshfs (hay un sshfs para Mac también). Una vez que haya montado su enrutador, simplemente copie los archivos directamente. No estoy seguro de si eso funciona para su aplicación particular, pero es una buena solución para tener a mano.

8

También puede visitar paramiko. No hay módulo scp (todavía), pero es completamente compatible con sftp.

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

scp.py for paramiko

+0

¿Está diciendo que la solución adjunta transferirá archivos de forma segura a cualquier máquina que ejecute sshd, incluso si no está ejecutando sftpd? Eso es exactamente lo que estoy buscando, pero no puedo decir por su comentario si esto simplemente envuelve sftp en una fachada similar a un scp. –

+2

Esto transferirá archivos con cualquier máquina que ejecute sshd, que tiene scp en la RUTA (scp no es parte de la especificación ssh, pero es bastante omnipresente). Esto invoca "scp -t" en el servidor y utiliza el protocolo scp para transferir archivos, que no tiene nada que ver con sftp. – JimB

+1

Tenga en cuenta que utilicé la implementación de opensp de scp como modelo, por lo que no está garantizado que funcione con otras versiones. Algunas versiones de sshd también pueden usar el protocolo scp2, que es básicamente el mismo que sftp. – JimB

76

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

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

Entonces llame scp.get() o scp.put() para hacer operaciones de CPS.

(SCPClient code)

+0

Excepto que el módulo no usa paramiko, es un código que al final 'scp' termina llamando a la línea de comando' scp' que solo funciona en * nix. –

+2

@Nick Bastin, funcionó muy bien para mí tanto en Linux como en Windows –

+7

De acuerdo, lo que se ve en el código fuente es la llamada remota a 'scp -t' o' scp -f' ('a' y 'from' modos, que existen para este propósito del servidor).Esto es esencialmente cómo funciona scp: se basa en otra copia de scp existente en el servidor. Este artículo lo explica muy bien: https://blogs.oracle.com/janp/entry/how_the_scp_protocol_works – laher

2

Tenga una mirada en fabric. Se puede encontrar un ejemplo here.

+2

¿Podría ser más específico? –

0

Si usted está en * nix puede utilizar sshpass

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

ha sido bastante tiempo ya que esta pregunta se hizo, y mientras tanto, otra biblioteca que puede manejar esto tiene surgido: puede utilizar la función copy incluido en la biblioteca Plumbum:

import plumbum 
r = plumbum.machines.RemoteMachine("example.net", 
user="username", keyfile=".ssh/some_key") 
fro = plumbum.local.path("some_file") 
to = r.path("/path/to/destination/") 
plumbum.path.utils.copy(fro, to) 
+0

¿Cómo puedo ingresar la contraseña de la clave privada con Plumbum? p – ekta

+0

@ekta: se le pedirá en la línea de comando. Si desea proporcionarlo desde su propio código, no creo que la API de plumbum lo admita. Pero 'SshMachine' de plumbum tiene acceso a' ssh-agent', por lo que si solo quieres evitar escribirlo siempre, esa es una forma de hacerlo. También puede presentar una solicitud de función en la página de github de plumbum. – pmos

4

No se pudo encontrar una respuesta directa, y este módulo "scp.Client" no existe. En cambio, this 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') 
2

Puede utilizar el subproceso paquete y la llamada de comandos para utilizar el comando scp de la cáscara.

from subprocess import call 

cmd = "scp [email protected]:files [email protected]:files" 
call(cmd.split(" ")) 
+1

¿Cómo es esto sustancialmente diferente del caso base mencionado por el interrogador? Sí, el subproceso es mejor que el sistema os.system, pero en ambos casos, no funciona fuera de los sistemas similares a Linux, tiene problemas con las solicitudes de contraseña, etc. – Foon