2011-10-06 22 views
9

Arkaplan: Ben bir ders için bir programda teslim etmek zorunda kaldığım her andan itibaren süreci otomatikleştirmek için python ve paramiko kullanıyorum. Kaynak kodu göndermek için "handin" adlı bir komut kullanıyoruz, ancak bu bir okul bilgisayarından yapılmalıdır. Bu yüzden, evden kod gönderdiğimde, şunları yapmam gerekiyor: okul sunucularına sftp, dosyaları bir bilgisayara, ssh'e, okul bilgisayarına koy, 'handin' komutunu kullan 'Python paramiko betiği, exec_command sırasında çıktı okuma sorunları()

Dosyaları okul makinelerine başarılı bir şekilde koyabiliyorum. Exec_command ('dosyalarımı el ile') kullanmaya çalıştığımda ve sonra sonraki eylemi belirlemek için çıktıyı okuduğumda sorun oluşuyor.

yüzden

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

var Ama bu nedense bir kilitlenmeye neden, script hiçbir şey yapıyor gibi görünmektedir ve sonunda tüm süreci (ctrl + c çalışmıyor) öldürmek zorunda. Exec_command'ın doğru şekilde tamamlanmadığından (try/catch bloğundan çıkıyor olsa bile) veya ağ sorunlarına ya da neyin olduğuna emin değilim.

Herhangi bir fikrin var mı?

güncelleme:

sorun yürütülürken handin komutuyla etkileşim beraberdir. Komutu çalıştırdıktan sonra, handin hala çalışıyor olabilir veya olmayabilir. İlk gönderiminde başarı diyorsa, falan filan yapın ve yürütmeyi tamamlayın. Herşey iyi. Ancak tekrar gönderirsem her dosya için bir yazmayı (stdin.write ('y')) yetkilendirmem gerekiyor.

TL/DR:

nasıl exec_command() hala çalışan girişi için bekleyen ve taleb() buna göre stdout'ta gelen olup olmadığını kontrol edebilirim?

+0

TL/DR için bir çözümünüz var mı? Ayrıca, girişi beklemeden önce metni nasıl bilebilirim, ör. @ parola ... –

cevap

5

Sorun, uzak komutun girişi beklemesi olabilir (bunu söylemediğiniz sürece, bir şeyleri stdin'e yazmanızı bekler). stdin.channel.shutdown_write()'u (stdin.close()'un kendisinin tek başına hile yapamayacağına inanıyorum: bu yalnızca bir sifona neden olur)

+0

Ne için kontrol etmek için bir okuma yapmak gerekiyordu. Birden çok kez elinize geçerseniz, her bir dosya için [y/N] üzerine yazmak isteyip istemediğinizi sorar, eğer ilk kez daha fazla giriş gerektirmezse. Exec_command sırasında çıkışı nasıl kontrol edebilirim? – macgregor

+0

stdout.readlines() aslında ssh komutlarının çıktısını okuyor, komut dosyasından gelen 'read' (girdi) ve ssh komutuna göndermiyor. Bunu yapmak için stdin.write() gerekir. – bdk

+0

Bunun farkındayım, yanlış anlıyorsunuz.Özgün yazımı güncelledim, belki de – macgregor

8

Yukarıdaki kod snippit'inde yanlış bir şey göremiyorum. Aşağıdaki program, bir ana bilgisayara giriş yapan ve dosyaları görüntülemek için ls komutunu çalıştıran eksiksiz bir betiktir. Sadece denedim ve benim için çalışıyor. Belki de bunu deneyin ve sizin için işe yarayıp yaramadığını görün. Çalışmıyorsa, ssh sunucunuza, çalıştırdığınız komutu veya paramiko kurulumuna özgü bir sorundan şüpheleniyorum. Eğer sizin için işe yarayacaksa, bunun mevcut işlevlerinize doğru hareket etmesi ve nerede kırıldığını görmek için sadece bir değişiklik yapma konusudur. Bu sizin için çalışıyorsa

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

sonraki öneri çalıştırmak çalıştığınız gerçek handin komutuyla 'ls /' yerine çalışmak olacaktı. Komutun kullanıcı girişi için bekletilmesi mümkündür, vb.

+0

numaralı bağlantıyı kaldıracaktır, evet, benimle bağlantı kurarken, temel komutlar harika çalışıyor. Komut yürütme sırasında neyin girileceğini anlamaya çalışmak için readline'ı kullanmaya çalışıyorum – macgregor

+0

Neredeyse kesinlikle elinizdeki komutunuz. Etkileşimli davranışı bekler. Bağlantıda 'sudo dmesg' kullanan bu örneğe bakın ve bu nedenle bir şifre istemine yanıt vermek zorunda: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/ – bdk

+0

Tamam, bunu dinamik olarak yapmalıyım. Komut yürütme sırasında stdout'u okuyabilmek için kaç kez kullanmam gerektiğini kontrol etmek için bir yol var mı 'y' – macgregor

İlgili konular