2012-11-02 11 views
5

Questo è il mio primo post in StackOverflow, quindi spero di farlo nel modo giusto! :)esegue script python locale su sshClient() con Paramiko nella macchina remota

Ho questo compito da fare per il mio nuovo lavoro che deve connettersi a diversi server ed eseguire uno script python in tutti loro. Non ho molta familiarità con i server (e ho appena iniziato ad usare paramiko), quindi mi scuso per eventuali grossi errori!

Lo script che voglio eseguire su di essi modifica il file authorized_keys ma per iniziare, lo sto provando con un solo server e non ancora utilizzando lo script di cui sopra (non voglio fare un errore e bloccare il server nel mio primo compito!). Sto solo cercando di elencare la directory nella macchina remota con una funzione molto semplice chiamata getDir(). Finora, sono stato in grado di connettersi al server con paramiko utilizzando le nozioni di base (sto usando PPB per eseguire il debug lo script tra l'altro):

try_paramiko.py

#!/usr/bin/python 

import paramiko 
from getDir import get_dir 
import pdb 


def try_this(server): 
    pdb.set_trace() 
    ssh = paramiko.SSHClient() 
    ssh.load_host_keys("pth/to/known_hosts") 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    my_key = paramiko.RSAKey.from_private_key_file("pth/to/id_rsa") 
    ssh.connect(server, username = "root", pkey = my_key) 
    i, o, e = ssh.exec_command(getDir()) 

Questo è il la funzione di recuperare l'elenco di directory:

getDir.py

#!/usr/bin/python 

import os 
import pdb 


def get_dir(): 
    pdb.set_trace() 
    print "Current dir list is:" 
    for item in os.listdir(os.getcwd()): 
     print item 

Durante il debug ho ricevuto la lista di directory della mia macchina locale al posto di quello dalla macchina remota ... c'è un modo passare una funzione python come parametro attraverso paramiko? Vorrei avere solo lo script a livello locale ed eseguirlo in remoto come quando lo si fa con un file bash da ssh con:

ssh -i pth/to/key [email protected] 'bash -s' < script.sh 

in modo da evitare in realtà per copiare lo script python per ogni macchina e quindi eseguirlo dal (suppongo che con il comando precedente lo script venga copiato anche sul computer remoto e poi cancellato, giusto?) C'è un modo per farlo con paramiko.sshClient()?

ho anche cercato di modificare il codice e utilizzare lo standard output del canale che crea exec_command alla lista directory lasciando gli script come:

try_paramiko.py

#!/usr/bin/python 

import paramiko 
from getDir import get_dir 
import pdb 


def try_this(server): 
    pdb.set_trace() 
    ssh = paramiko.SSHClient() 
    ssh.load_host_keys("pth/to/known_hosts") 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    my_key = paramiko.RSAKey.from_private_key_file("pth/to/id_rsa") 
    ssh.connect(server, username = "root", pkey = my_key) 
    i, o, e = ssh.exec_command(getDir()) 
    for line in o.readlines(): 
     print line 
    for line in e.readlines(): 
     print line  

getDir.py

def get_dir(): 
    return ', '.join(os.listdir(os.getcwd())) 

Ma con questo, in realtà tenta di eseguire l'elenco delle directory locali come comandi (che in realtà ha senso che modo in cui ce l'ho). Ho dovuto convertire l'elenco in una stringa perché stavo avendo un errore TypeE dicendo che si aspetta una stringa o un buffer di caratteri di sola lettura, non una lista ... So che questo era un tentativo disperato di passare la funzione ... qualcuno sa come potrei fare una cosa del genere (passare una funzione locale tramite paramiko per eseguirla su una macchina remota)? Se avete qualche correzione o suggerimento sul codice, sono molto graditi (in realtà, qualsiasi tipo di aiuto sarebbe molto apprezzato!).

Grazie mille in anticipo! :)

+0

Scegli questa [domanda] (http://stackoverflow.com/questions/8764895/recursively-execute-a-locally-defined-python-script-on-remote-machines) – Bula

+0

@Bula, grazie mille . Ora sto passando a Fabric per farlo! – eberbis

risposta

4

Non è possibile eseguire la funzione python tramite ssh. ssh è solo un tunnel con il tuo codice su un lato (client) e shell su un altro (server). Dovresti eseguire i comandi di shell sul lato remoto.

Se l'uso del codice ssh non è critico, suggerisco fabric come libreria per scrivere gli strumenti di amministrazione.Contiene strumenti per una facile gestione di ssh, trasferimento di file, sudo, esecuzione parallela e altro.

+1

Grazie mille @mechmind, passerò a Fabric. Mi aiuti davvero! Ho provato a dare alcuni punti alla tua risposta, ma sono ancora un principiante con pochissimi punti reputazione! Mi dispiace per quello! – eberbis

2

penso che si potrebbe desiderare cambiare le paramaters siete di passaggio in ssh.exec_command Ecco un'idea:

Invece di fare:

def get_dir(): 
    return ', '.join(os.listdir(os.getcwd())) 

i, o, e = ssh.exec_command(getDir()) 

si potrebbe desiderare di provare:

i, o, e = ssh.exec_command('pwd') 
o.printlines() 

E altre cose da esplorare:

  • Scrivere uno script bash o un Python che risiede sui tuoi server. Puoi usare Paramiko per accedere al server ed eseguire lo script con ssh.exec_command(some_script.sh) o ssh.exec_command(some_script.py)
  • Paramiko ha alcune utilità FTP/SFTP in modo che tu possa effettivamente usarlo per mettere lo script sul server e quindi eseguirlo.
+0

Grazie mille Stephen! Il fatto è che volevo evitare di copiare il file su tutti i server. Sapevo di avere la possibilità di scpare il file su tutti i server, ma non volevo che fosse così. Ad ogni modo, apprezzo il tempo dedicato a rispondere alla mia domanda :) – eberbis

Problemi correlati