2013-03-18 36 views
0

我試圖編寫一個函數,它將通過ssh與Popen發出命令並返回輸出。如何在Python中跳過ssh引用的shell命令

def remote(cmd): 
    escaped = escape(cmd) 
    return subprocess.Popen(escaped, ...).communicate()[0] 

我的問題是如何實現escape函數。有沒有一個Python模塊(2.6)有這方面的幫手?谷歌顯示有pipes.quotere.escape,但他們似乎只能用於本地運行的命令。隨着傳遞到SSH命令,似乎逃脫需要更加嚴格:

例如在本地機器上,這是確定:

echo $(hostname) 

當傳遞到ssh它必須是:

ssh server "echo \$(hostname)" 

另外,根據上下文,雙引號可以用不同的方式解釋。對於立即報價,您需要滿足以下條件:

ssh a4ipe511 "echo \\\"hello\\\"" 

要做到可變exansion,雙引號也可用於:

ssh a4ipe511 "echo \"\$(hostname)\"" 

正如你所看到的,用來轉義進入SSH命令的規則變得相當複雜。由於這個函數會被任何人調用,恐怕一些複雜的命令會導致函數返回不正確的輸出。

這是可以用內置的Python模塊解決的問題,還是我需要實現逃避自己?

回答

1

第一:

pipes.quotere.escape無關局部運行的命令。他們只是變換一個字符串;這是你的業務之後你用它做了什麼。所以要麼 - 特別是pipes.quote - 適合你想要的。

二:

如果你想使用ssh遠程主機上運行命令echo $(hostname),你不需要擔心殼逸出,因爲subprocess.Popen沒有通過你的命令進入默認外殼。因此,舉例來說,這個工作得很好:

>>> import subprocess 
>>> subprocess.call([ 'ssh', 'localhost', 'echo $(hostname)']) 
myhost.example.com 
0 

雙引號也行你所期望的:

>>> subprocess.call([ 'ssh', 'localhost', 'echo "one two"; echo three']) 
one two 
three 
0 

目前還不清楚,我認爲你確實有問題。

+0

謝謝,您的解決方案工作完美。它看起來像一個shell = False的序列傳遞,解決了這個問題。雖然我認爲這可能仍然是任何想通過傳遞字符串參數並使用shell = True來解決此問題的問題。 – trinth 2013-03-18 22:00:14