2013-01-18 18 views
1

我已閱讀了一堆示例,但沒有一個適用於此特定任務。Python - subprocess.Popen - ssh -t user @ host'service --status-all'

Python代碼:

x = Popen(commands, stdout=PIPE, stderr=PIPE, shell=True) 
print commands 
stdout = x.stdout.read() 
stderr = x.stderr.read() 
print stdout, stderr 
return stdout 

輸出:

[[email protected]]$ python helpers.py 
['ssh', '-t', '[email protected]', ' ', "'service --status-all'"] 
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] 
      [-D [bind_address:]port] [-e escape_char] [-F configfile] 
      [-I pkcs11] [-i identity_file] 
      [-L [bind_address:]port:host:hostport] 
      [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] 
      [-R [bind_address:]port:host:hostport] [-S ctl_path] 
      [-W host:port] [-w local_tun[:remote_tun]] 
      [[email protected]]hostname [command] 

爲什麼會出現這個錯誤? 使用os.popen(...)它工作,它至少執行,但我無法通過SSH隧道檢索遠程命令的輸出。

+0

輸出表明您沒有向命令傳遞足夠/正確的參數。 –

+0

刪除空白項目,並刪除最後一個參數的單引號。 – Keith

+0

順便說一句,你使用公鑰認證?或密碼認證? – Keith

回答

8

我覺得你的命令列表是錯誤的:

commands = ['ssh', '-t', '[email protected]', "service --status-all"] 
x = Popen(commands, stdout=PIPE, stderr=PIPE) 

另外,我不認爲你應該通過shell=True如果你打算到一個列表傳遞給Popen

例如做這一點:

Popen('ls -l',shell=True) 

或本:

Popen(['ls','-l']) 

但不是這樣的:

Popen(['ls','-l'],shell=True) 

最後,存在一個方便的功能將字符串分割爲一個列表以同樣的方式你殼會:

import shlex 
shlex.split("program -w ith -a 'quoted argument'") 

將返回:

['program', '-w', 'ith', '-a', 'quoted argument'] 
+0

我愛你! 我想我已經嘗試了一切,除了刪除'和shell = True的組合。我試過了他們,最終以錯誤的方式結束了,但是刪除了這兩個工作。 (< pretend >)神(< /pretend >)我愛的人如何快速回答這裏.. – Torxed

+0

哦,不是粗魯的菜鳥問題.. 因爲我們中有些人得到的大腦凍結甚至壽我們編程的Python快10年,一次不會被挑選它發生在人類給我希望:)所以,如果我可以,我會給你更多的積分,爲一個很好的答案! (不能將你的答案標記爲解決方案,1分鐘左右) – Torxed

+0

@mgilson你能解釋爲什麼有必要將一個命令分解爲每一塊(空格分隔)來傳遞它嗎?命令= ['ssh','-t','user @ host','service --status-all'] –