2012-11-02 96 views
5

這是我在StackOverflow中的第一篇文章,所以我希望以正確的方式做到這一點! :)通過sshClient()在遠程機器上執行paramiko的本地python腳本

我有這個任務要做,我需要連接到幾個服務器,並在其中執行一個python腳本的新作業。我對服務器不是很熟悉(剛開始使用paramiko),所以我對任何重大錯誤表示歉意!

我想在它們上運行的腳本修改authorized_keys文件,但要啓動,我只用一臺服務器嘗試它,但尚未使用上述腳本(我不想犯一個錯誤並阻止服務器在我的第一項任務!)。 我只是想用一個叫做getDir()的非常簡單的函數來列出遠程機器中的目錄。到目前爲止,我已經能夠使用的基本知識(我使用PDB調試順便腳本)的paramiko連接到服務器:

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

這是函數來獲取目錄列表:

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 

在調試我得到了我的本地機器,而不是從遠程計算機上的一個目錄列表...有什麼辦法通過paramiko傳遞一個python函數作爲參數?我想只是有腳本本地並運行遠程當你與一個bash文件從SSH與做喜歡:

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

所以實際上避免python腳本複製到每一臺機器,然後從運行他們(我想用上面的命令腳本也將被複制到遠程機器,然後刪除,對不對?)有沒有辦法做到這一點與paramiko.sshClient()?

我還試圖修改代碼,並使用創建exec_command列出目錄留下的腳本,如通道的標準輸出:

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

但是,它實際上試圖運行本地目錄列表作爲命令(這實際上是有道理的,我有它)。我必須將列表轉換爲字符串,因爲我有一個TypeError說它期望一個字符串或一個只讀字符緩衝區,而不是一個列表......我知道這是一個絕望的嘗試來傳遞函數...是否任何人都知道我可以做這樣的事情(通過paramiko通過本地函數在遠程機器上執行它)? 如果您對代碼有任何更正或提示,他們非常受歡迎(實際上,任何形式的幫助都將非常感謝!)。

非常感謝! :)

+0

檢查這個[問題](http://stackoverflow.com/questions/8764895/recursively-execute-a-locally-defined-python-script-on-remote-machines) – Bula

+0

@Bula,非常感謝。我現在正在切換到Fabric來完成它! – eberbis

回答

4

你不能只通過ssh執行python函數。 ssh只是一端(客戶端)和另一端(服務器)上的代碼的隧道。你應該在遠端執行shell命令。

如果使用原始的ssh代碼不重要,我建議fabric作爲編寫管理工具的庫。它包含簡單的ssh處理,文件傳輸,sudo,並行執行等工具。

+1

非常感謝@mechmind,我要切換到Fabric。你真的幫助我!我試着給你一些答案,但我仍然是一個很少聲譽點的新手!對於那個很抱歉! – eberbis

2

我想你可能想改變你傳遞ssh.exec_command這裏PARAMATERS有一個想法:

而不是做:

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

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

你可能也想嘗試:

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

還有其他值得探討的事情:

  • 編寫一個bash腳本或生活在您的服務器上的Python。您可以使用Paramiko登錄到服務器並執行腳本ssh.exec_command(some_script.sh)ssh.exec_command(some_script.py)
  • Paramiko有一些FTP/SFTP實用程序,因此您可以實際使用它將腳本放在服務器上,然後執行它。
+0

非常感謝斯蒂芬! 問題是我想避免將文件複製到所有服務器。我知道我有可能將文件掃描到所有的服務器,但我不想那樣。 無論如何,我感謝您花時間回答我的問題:) – eberbis

相關問題