2011-10-06 19 views
9

Sfondo: Sto usando python e paramiko per automatizzare il processo che passo ogni volta che devo consegnare un programma per una classe. Usiamo un comando chiamato "handin" per inviare il codice sorgente, ma questo deve essere fatto da un computer scolastico. Quindi, quando invio il codice da casa, devo: sftp nei server della scuola, mettere i file in una directory, ssh nel computer della scuola, usare il comando 'handin'Script paramiko Python, problemi durante la lettura dell'output durante exec_command()

Posso mettere con successo i file sulle macchine della scuola. Il problema si verifica quando provo a usare exec_command ("consegna i miei file") e poi leggo l'output per determinare l'azione successiva.

quindi devo

try: 
    (stdin, stdout, stderr) = client.exec_command(s) 
except: 
    print 'whoops' 
    sys.exit() 
print stdout.readlines() 

Ma questo provoca una situazione di stallo per qualche ragione, lo script sembra essere non fare nulla e devo eventualmente uccidere l'intero processo (ctrl + c pretende molto lavoro). Non sono sicuro se exec_command non sta completando correttamente (anche se sta uscendo dal blocco try/catch) o se ho problemi di rete o cosa.

Qualche idea?

aggiornamento:

Il problema è interagenti con il comando handin durante l'esecuzione. Dopo aver eseguito il comando, handin potrebbe o potrebbe non essere ancora in esecuzione. Se è la prima volta che lo invia, dice il successo, bla bla, e termina l'esecuzione. Tutto bene. Ma se sto ri-invio devo autorizzare una sovrascrittura (stdin.write ('y')) per ogni file.

TL/DR:

Come si controlla se un exec_command() è ancora in esecuzione, in attesa di input, e readline() da stdout di conseguenza?

+0

Avete una soluzione per TL/DR? Inoltre, come posso conoscere il testo prima di attendere l'input, ad es. @ password ... –

risposta

5

Il problema potrebbe essere che il comando remoto è in attesa di input (si aspetta che tu scriva qualcosa su stdin, non sapendo che non lo farai a meno che tu non lo dica). Prova stdin.channel.shutdown_write() (credo che lo stesso non faccia il trucco stdin.close()

+0

Questo è quello che mi serviva per fare una readline da verificare. Se passi più volte ti chiede se vuoi sovrascrivere [y/N] per ogni file, se è la prima volta che non richiede ulteriori input. Come controllo l'output durante exec_command? – macgregor

+0

stdout.readlines() legge effettivamente l'output dei comandi ssh, non "legge" l'input dallo script e lo invia al comando ssh. Per farlo è necessario stdin.write(). – bdk

+0

Ne sono consapevole, fraintendimenti.Ho aggiornato il mio post originale, forse questo chiarirà le cose – macgregor

8

Non vedo niente di sbagliato con il codice snippit sopra. Il seguente programma è uno script completo che accede ad un host ed esegue il comando ls per visualizzare i file. L'ho appena provato e funziona per me. Forse prova questo e vedi se funziona per te. Se non funziona, sospetto alcuni problemi specifici del server ssh, del comando in esecuzione o dell'installazione di paramiko. Se funziona per te, è solo questione di apportare modifiche a questo per spostarti verso la tua funzionalità esistente e vedere dove si rompe.

import paramiko 
ssh=paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('<ip address here>',username='<username here>',password='<password here>') 
stdin,stdout,stderr = ssh.exec_command("ls /") 
print stdout.readlines() 

Se funziona per voi il mio suggerimento successivo sarebbe quello di provare a sostituire la 'ls /' con il comando effettivo Handin si sta tentando di eseguire. È possibile che il comando sia sospeso in attesa di input dell'utente, ecc.

+0

sì, mi sono collegato bene, i comandi di base funzionano alla grande. Sto cercando di usare la readline per capire cosa inserire successivamente durante l'esecuzione del comando. – macgregor

+0

È quasi certamente il tuo comando handin. Si aspetta un comportamento interattivo. Guarda questo esempio che usa 'sudo dmesg' nel link e quindi deve rispondere a una richiesta di password: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/ – bdk

+0

ok, ho bisogno di farlo dinamicamente però. C'è un modo per leggere lo stdout durante l'esecuzione del comando per verificare quante volte ho bisogno di scrivere 'y' – macgregor

Problemi correlati