2013-02-06 68 views
9

我從我的Python腳本調用了一個java程序,並且它輸出了許多我不想要的無用信息。我曾嘗試addind stdout=None到Popen功能:忽略subprocess的輸出.Popen

subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=None) 

但它的確如此。任何想法?

回答

31

3.3 documentation

標準輸入,輸出和錯誤指定執行程序的標準輸入,標準輸出和標準錯誤文件句柄。有效值是PIPE,DEVNULL,現有文件描述符(正整數),現有文件對象和None。

所以:

subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=subprocess.DEVNULL) 

這個只存在於3.3及更高版本。但文檔說:

DEVNULL表示將使用特殊文件os.devnull。

os.devnull存在回到2.4的方式(在subprocess之前存在)。所以,你可以手動做同樣的事情:

with open(os.devnull, 'w') as devnull: 
    subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=devnull) 

需要注意的是,如果你正在做的事情更加複雜,不適合到一個單一的線,你需要保持開放devnullPopen的整個生命對象,而不僅僅是它的構造。 (也就是說,把整個事情的with語句內。)

重定向到/dev/null(POSIX)或NUL:(Windows)中的好處是,你沒有創建不必要的管道,而且,更重要的是,可以」 t運行到邊界情況,其中子進程阻塞寫入該管道。

缺點是,理論上,subprocess可能在os.devnull沒有的某些平臺上工作。如果你只關心POSIX和Windows上的CPython,PyPy和Jython(這是你們中的大多數人),這永遠不會成爲問題。對於其他情況,請在分發代碼之前進行測試。

+0

+1:devnull。確保'devnull'在子進程處於活動狀態時保持打開狀態(with-statement意味着否則)。最後一段看起來沒有必要:DEVNULL通過CPython中的os.devnull實現。 os.devnull與Jython一起使用。 – jfs

+0

@ J.F.Sebastian:在'check_call'(在​​'with'內)之後,'devnull'不再需要。但是,是的,也許我應該澄清,對於不適合單一行的更復雜的用例,整個事情需要放在'with'內,而不僅僅是'Popen'。 – abarnert

+0

@JFSebastian:與此同時,對於'os.devnull',它是否確實存在於每個有「子進程」存在的平臺上,因此不需要「在使用前檢查」,或者你知道它也存在在Jython上,因此我應該將Jython移動到您不需要檢查的平臺列表中? – abarnert

6

documentation

隨着None默認設置,不會發生重定向。

您需要設置stdoutsubprocess.PIPE,然後調用.communicate(),只要忽略捕獲輸出。

p = subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
p.communicate() 

雖然我懷疑使用比就足夠了subprocess.call()更適合您的需要:

subprocess.call(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
+1

@sjtaheri:謝謝你的糾正,我自己申請了。 –

+4

創建和忽略管道通常是有效的,但是如果它寫得太多(當然它可能在你的系統上工作並且對你的一個用戶失敗),它可能導致子進程阻塞,所以我認爲它確實不是一個'在這裏只是「通話」而不是「通信」。這就是爲什麼'DEVNULL'被添加了 - 所以你只能'調用'而不用擔心它。 (好吧,在稍微複雜的情況下,你設置了'stderr = DEVNULL',而不是'stdout',只是'check_output'。但是同樣的想法。) – abarnert

+0

@abarnert:啊,沒有意識到已經添加了;只是在Python 3文檔中找到它。 –