2015-03-13 47 views
0

當我在控制檯中運行程序時,我得到了一些文本輸出。 當我在Popen(..)中運行相同的程序時,使用相同的參數,stdout和stderr都是空的。Python2:subprocess.Popen()有另一個輸出,因爲它直接在控制檯上運行

我嘗試了一切,我可以想像像shell = False和shell = True,設置stdout = subprocess.PIPE,做一個os.chdir()改變到這個程序的目錄,嘗試p.wait()和p .communicate(),將該命令設置爲列表和字符串,但沒有任何效果。

例如:

p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 
out, err = p.communicate() 

- >出來,犯錯是空字符串,但如果我在控制檯運行此命令我得到真正的輸出。命令是使用完整路徑的,所以無論命令將在何處啓動。

我的問題是,有沒有程序檢測到他們沒有在真正的控制檯中運行的機制?如果是這樣,我該如何作弊。

或想念我什麼?

(在Win7 64位的Python 2.7.8。X32)

+0

我在文檔中看到:「在shell = True的Windows上,COMSPEC環境變量指定了默認的shell。在Windows上指定shell = True時,您希望執行的命令被內置到shell中(例如dir或copy)。您不需要shell = True來運行批處理文件或基於控制檯的可執行文件。 – 2015-03-13 13:26:09

+0

謝謝@glennjackman,所以我可以將殼變成False :) – 2015-03-13 13:43:34

+0

不知道爲什麼,但是當我打開Windows服務'COM +系統應用程序'後,'out'被填滿。現在一切正常。即使關閉和禁用此服務後,重新啓動電腦後。 o.O – 2015-03-13 13:45:49

回答

0
from subprocess import Popen, STDOUT, PIPE 
p = Popen(command, shell=True, stdout=PIPE, stderr=STDOUT, stdin=PIPE) 
while p.poll() is None: 
    print(p.stdout.read()) 
p.stdout.close() 
p.stdin.close() 

試試這個,看看它是否有什麼差別。另外請確保command是一個字符串,而不是一個列表/ touple,shell=True出於任何原因更好或只與字符串。 還要注意的是shell=True將讓你上吊,因爲它是不安全等

而且跳繩.communicate()你需要點擊關閉stdout否則緩衝區得到充分的,你可能會掛起,這兩個你和子進程。


如果這不起作用,請提供更多信息。比如使用的命令和預期的輸出(至少前幾行)

+0

謝謝,但這不起作用。 'p.stdout.read()'總是空的。 有趣的是:我打開了Windows服務的'COM +系統應用程序','out'被填滿。即使重新啓動電腦後關閉和禁用此服務。 o.O 有趣的2:如果我在'out,err = p.communicate()'之後放置一個斷點,那麼out就不是空的。但是,如果我一步一步調試'p = Popen(..)'和'out,err = p.communicate()',那麼out就是空的。 – 2015-03-13 13:40:10

+0

'也跳過.communicate()你需要點擊標準輸出,否則緩衝區將變滿,你可能會掛你的孩子進程。「 當然?我以另一種方式在python2.7的文檔中閱讀它。溝通()將每個輸出緩衝到內存中,所以如果數據量很大(或無限),那就不好了。 但在我的情況下,輸出只有幾個字符(小於50) – 2015-03-13 13:40:42

+0

@DuncanMCLeod這有兩方面的內容。 '.communicate()'可以填充你的內存直到它變滿,這可能是很多數據。我提出的另一個選項將填充**緩衝區**,這比您的RAM空間少得多的數據。如果緩衝區滿了,程序會掛起,因爲它會等待緩衝區清除,直到它可以繼續進程 - > stdout-buffer - > if buffer == full:wait',所以我提出的解決方案需要你點擊緩衝區,否則進程將等待緩衝區再次變爲空閒狀態:) – Torxed 2015-03-16 14:30:57

相關問題