2014-01-16 105 views
0

好吧,所以即時嘗試拿我的ssh密鑰,並將其推到我的根的授權密鑰列表,所以這就是爲什麼我嘗試了許多不同的變化。記住即時通訊新的Python:在Linux中的Python腳本

import subprocess 
f = open("/Users/MacUser/server.lst", "r") 
USER = "root" 

def multi_com(f): 

    for EACH in f: 

      com_keys = subprocess.Popen('cat ~/.ssh/id_pub.rsa | ssh ' + USER + "@" + EACH + 'tee -a .ssh/authorized_keys', stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
      output, errors = com_keys.communicate() 
      return com_keys 
      print output 

multi_com(f) 

我server.lst包含許多喜歡和每一行都有一個單獨的FQDN是這樣的:

abc1.domain.com 
abc2.domain.com 
abc3.domain.com 
abc4.domain.com  

任何幫助,將不勝感激

+0

你也許可以試試scp來將授權密鑰複製到每臺機器上。 – viper

+0

您的for-loop將僅運行1次迭代,因爲該返回語句。而且,「print output」行將永遠不會到達。 – iCodez

+0

我有150個服務器來做到這一點,還有其他用戶的密鑰也存儲在那裏。即時嘗試附加文件,而不是覆蓋文件 – user102825

回答

2

第一(subprocess.Popen)的第一個參數應該是參數列表,而不是單個字符串,除非(a)您使用shell=True,或者(b)編寫Windows特定的代碼。在你的情況下,這兩者都不是真的。

這就是說,如果你想運行該命令,你應該使用shell=True。否則,您只需運行cat命令,將|作爲第二個參數,將ssh作爲第三個參數,等等。而cat不知道該怎麼辦;它只是尋找一個名爲|的文件,並且失敗。如果你想使用像|管道這樣的shell特性,你必須使用shell。

雖然我們在這裏,'… ssh ' + USER + "@" + EACH + 'tee -a…'主機名和tee之間沒有空格,這不太可能是你想要的。這就是許多原因,% -formatting或format功能是更好的一個:

cmdline = 'cat ~/.ssh/id_pub.rsa | ssh {}@{} tee -a .ssh/authorized_keys'.format(USER, EACH) 

話雖這麼說,你不應該使用你不需要殼特徵。該文檔有關於Replacing Older Functions with the subprocess Module的很大一部分,並且第一個示例的其中一個示例說明如何替換shell管道,並在Python中完成所有操作。

對於這個問題,幾乎從來沒有一個很好的理由把cat foo管到另一個程序。只要通過它foo作爲其輸入。在shell中,bar < foocat foo | bar相似,但稍微簡單一點,開銷較少;在Python中,打開文件然後通過stdin=foo很多比管道cat更容易。

話雖如此,試圖驅動ssh作爲命令行應用程序有各種你不想處理的棘手問題;使用paramikofabric這樣的庫會更好。

另一方面,如果您確實想要使用命令行工具和shell管道等等,bash是比Python更好的語言。