2012-04-18 100 views
0

我在Python 2橫跨這個偉大replacment來抓getstatusoutput()功能*,它同樣適用於Unix和Windows。不過,我認爲output的構建方式有問題。它只返回輸出的最後一行,但我不明白爲什麼。任何幫助都是極好的。Python的getstatusoutput更換不返回完整的輸出

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell.""" 
    """This new implementation should work on all platforms.""" 
    import subprocess 
    pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True) 
    output = "".join(pipe.stdout.readlines()) 
    sts = pipe.returncode 
    if sts is None: sts = 0 
    return sts, output 
+0

爲什麼不在try塊中使用'subprocess.check_call'?你可以在'except'部分得到返回碼(如果它不是零)。 – wim 2012-04-18 02:50:54

+0

如果我想要輸出,即使返回代碼爲0,該怎麼辦? – MFB 2012-04-18 03:00:43

回答

2

這裏有一個錯誤。

召喚:

pipe = subprocess.Popen(...) 

揭開序幕的過程。行:

output = "".join(pipe.stdout.readlines()) 

讀取進程的標準輸出(如果有錯誤輸出也可能被卡住了,但因爲你沒有重定向標準錯誤,這是安全的;在更一般的情況下,你需要使用.communicate()功能以避免可能的楔入)。你可能會想:好,現在我讀過所有的輸出,子進程顯然已經完成了,所以pipe.returncode應設置。但事實上,如果更換:

sts = pipe.returncode 
if sts is None: sts = 0 

與代碼,包括診斷某種(或只是刪除第二行完全),你會發現,至少在某些系統上,有時,stsNone。原因是subprocess模塊還沒有機會檢索它。此時應更換這些線路有:

sts = pipe.wait() 

收集結果,並消除對is None測試的需要。 (這是安全地調用.wait()即使你使用.communicate()和/或已經被稱爲.wait()。)

"".join(...)可以稍微更有效地利用剛剛完成:

output = pipe.stdout.read() 

所有這一切說,它確實爲我獲得完整的輸出。也許你從對換行只使用'\r'和你的Python沒有通用換行的支持是建什麼讀什麼? (如果我運行的東西產生\r -for-newline,我仍然得到所有的行,用實際的換行符分隔。)

+0

感謝這個優秀的解釋。我已經學到了很多。不過,我認爲你正在使用換行符。我只是從我的功能中得到''n \''。您可以請擴展新行問題嗎? – MFB 2012-04-18 04:49:43

+0

每[文檔](http://docs.python.org/library/functions.html#open),「通用換行符」是指:讀一個輸入流時,輸入線,任何的普通'「結尾」 \ r'或'\ r \ n'或普通的'\ n'會使Python「看見」一個簡單的'\ n'字符。但是這需要Python的支持。如果沒有,一個普通的'\ r'會被視爲'\ r',並且如果你打印出結果字符串,你可能看不到任何東西。例如:>>> print'something \ relse'' * *出現*以打印'elsething'。 – torek 2012-04-18 04:55:26

+0

這很有道理,但不應該讓'\ n'混合輸入所有輸出?相反,即使我知道子進程(在這種情況下是ffmpeg)正在輸出更多的信息,我也只是獲得一個'\ n'。 – MFB 2012-04-18 05:00:13