2015-01-27 63 views
0

我有一個python腳本,用於調用重命名文件的bash腳本。然後我需要文件的新名稱,以便python可以對它進行一些進一步的處理。我使用subprocess.Popen來調用shell腳本。 shell腳本回顯新的文件名,所以我可以使用stdout = subprocess.PIPE來獲取新的文件名。將shell腳本輸出分配給python變量,忽略錯誤消息

問題是,有時bash腳本會根據具體情況嘗試用舊名稱重命名該文件,因此會給出消息,指出mv命令中的這兩個文件是相同的。我剔除了其他所有內容,並在下面列出了一個基本示例。

$ ls -1 
test.sh 
test.txt 

這個shell腳本只是強制錯誤信息的一個例子。

$ cat test.sh 
#!/bin/bash 
mv "test.txt" "test.txt" 
echo "test" 

在蟒蛇:

$ python 
>>> import subprocess 
>>> p = subprocess.Popen(['/bin/bash', '-c', './test.sh'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
>>> p.stdout.read() 
"mv: `test.txt' and `test.txt' are the same file\ntest\n" 

我怎麼能忽略來自mv命令的消息,只得到echo命令的輸出?如果一切順利,shell腳本的唯一輸出將是echo的結果,所以我只需要忽略mv錯誤消息。

感謝,

傑蘭特

+2

如果您不想在'stdout'上看到錯誤消息,請勿將'stderr'發送到'stdout'。 –

+0

所以你不想知道命令是否成功? –

回答

0

直接stderr爲null,正是如此

$ python 
>>> import os 
>>> from subprocess import * 
>>> p = Popen(['/bin/bash', '-c', './test.sh'], stdout=PIPE, stderr=open(os.devnull, 'w')) 
>>> p.stdout.read() 
+0

除非您從管道讀取,否則不要設置'stderr = PIPE'。 ['os.devnull'是便攜式](http://stackoverflow.com/a/28181836/4279) – jfs

+0

我看到沒有問題,允許GC收割未使用的PIPE。但是'os.devnull'是我不知道的一個很好的竅門。 – user590028

+0

未讀PIPE是一個等待發生的死鎖。在子流程文檔中計數關於它的警告數量。 – jfs

0

爲了讓子的輸出,而忽略其錯誤消息:

#!/usr/bin/env python 
from subprocess import check_output 
import os 

with open(os.devnull, 'wb', 0) as DEVNULL: 
    output = check_output("./test.sh", stderr=DEVNULL) 

check_output()拋出一個異常如果腳本返回非零st的ATU。

請參閱How to hide output of subprocess in Python 2.7

+0

我假設OP是否想忽略'stderr',他不想要例外,不是嗎? – user590028

+0

我不這麼認爲。如果OP想要完全忽略錯誤,顯式的'try/except'可以加上 – jfs

+0

謝謝你。雖然在這種情況下,我不希望有一個例外,但如果出現錯誤,我相信這一點很重要。 –