2014-01-10 46 views
0

我的代碼:SSH到AWS服務器和編輯hosts文件

出於某種原因,這似乎無限循環和重複打印「here2」和「LS -lah」輸出。有什麼不明顯的事情我做錯了嗎?

def update_hosts_file(public_dns,hosts_file_info): 
    for dns in public_dns: 
     print 'here2' 
     ssh = paramiko.SSHClient() 
     ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # wont require saying 'yes' to new fingerprint 
     key_path = os.path.join(os.path.expanduser(KEY_DIR), KEY_NAME)+'.pem' 
     ssh.connect(dns,username='ubuntu',key_filename=key_path) 
     ssh.exec_command('touch testing') 
     a,b,c=ssh.exec_command("ls -lah") 
     print b.readlines() 
     a,b,c=ssh.exec_command("file = open('/home/ubuntu/hosts', 'w')") 
     #print b.readlines() 
     ssh.exec_command("file.write('127.0.0.1 localhost\n')") 
     for tag,ip in hosts_file_info.iteritems(): 
      ssh.exec_command("file.write('%s %s\n' % (ip,tag))") 
     ssh.exec_command("file.close()") 
     ssh.close() 

public_dns = 'ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com' 
print public_dns 
hosts_file_info = {} 
#hosts_file_info['1']='test' 
#hosts_file_info['2']='test2' 
#hosts_file_info['3']='test3' 
#print hosts_file_info 
update_hosts_file(public_dns,hosts_file_info) 
+1

它看起來像你想,如果他們的bash命令來執行Python語句,比如'文件= open('/ home/ubuntu/hosts','w')'。我不知道這是否會給你一個bash語法錯誤,或'file'像'無法打開「=」(沒有這樣的文件)'一個錯誤,但我相信它不會做任何有用的。 – abarnert

+0

BTW,檢查出布http://docs.fabfile.org/en/1.8/。這使得很多這種自動化方式變得簡單和方便。 –

回答

2

你的第一個問題是:public_dns是一個字符串,所以for dns in public_dns:將遍歷該字符串的字符。你會嘗試代碼'e',然後用'c',然後用'2',依此類推。這不是一個無限循環,但是它是一個長度爲42的循環,我可以很容易地看到你感到無聊並在完成之前取消它。

如果你只想要一臺服務器,你還需要一個字符串列表,它只是該列表將只有一個字符串,像這樣:

public_dns = ['ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com'] 

你的下一個問題是,你的ssh代碼沒有任何意義。您試圖執行Python語句,如file = open('/home/ubuntu/hosts', 'w'),就好像它們是bash命令一樣。在bash中,該命令是一個語法錯誤,因爲在shell腳本中不能使用括號。如果你固定的,這純粹是對file命令撥打電話,這會抱怨不能夠找到一個名爲=文件。您可以將Python腳本上傳到刪除服務器,然後運行它,通過<<HERE嵌入一個,或者嘗試編寫交互式Python解釋器的腳本,但不能在bash解釋器中運行Python代碼。

最重要的是,exec_command啓動命令,並立即返回你的標準輸入/輸出/標準錯誤通道。它不會等到命令完成。所以,你不能通過一個接一個地執行a,b,c = ssh.exec_command(…)來排序多個命令。


那麼,你怎麼解決這個問題呢?重新開始真正有意義,而不是試圖弄清楚每個部分是什麼意圖以及如何使其工作。

據我所知,在每臺機器上,您正嘗試創建一個新文件,其內容僅基於本地數據,而且在所有機器上都是相同的。那麼,爲什麼要嘗試在每個創建該文件的遠程機器上運行代碼?只要創建在本地,一次,並將其上傳到每個遠程機器如,用的paramiko的sftp。像這樣的東西(顯然未經檢驗的,因爲我沒有你的數據,服務器證書等):

hosts = ['127.0.0.1 localhost\n'] 
for ip, tag in hosts_file_info.iteritems(): 
    hosts.append('%s %s\n' % (ip,tag)) 
for dns in public_dns: 
    ssh = paramiko.SSHClient() 
    # etc. up to connect 
    sftp = paramiko.SFTPClient.from_transport(ssh.get_transport()) 
    f = sftp.open('/home/ubuntu/hosts', 'w') 
    f.writelines(hosts) 
    f.close() 
+0

感謝隊友,不知道我可以使用sftp –

2

您正在循環public_dns變量中的每個字母。你可能想是這樣的:

public_dns = ['ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com']