2012-07-15 22 views
24

サブプロセスのstderr出力をstdoutにリダイレクトしたいとします。定数STDOUTはそうすべきですか?サブプロセスstderrをstdoutにリダイレクト

しかし、

$ python >/dev/null -c 'import subprocess;\ 
         subprocess.call(["ls", "/404"],stderr=subprocess.STDOUT)' 

出力何かをします。それはなぜですか?そして、stdoutでエラーメッセージをどうやって得るのですか?

+0

ところで、それはpython 3.5で修正されました。 – max

答えて

29

答えはsource codeです。

subprocess.STDOUT
特別値(...)標準エラーが標準出力と同じハンドルに入る必要があることを示していること:それは言うとき特に、documentationが誤解されています。

STDOUTは(技術的-1)「デフォルト」に設定されているのでstderr=subprocess.STDOUTが評価される場合、標準エラーが同様に「デフォルト」に設定されています。残念ながら、これはstderrの出力がstderrに変わることを意味します。 subprocess.STDOUTはありません使用して、実際に

$ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"], 
         stderr=sys.stdout.fileno())' 
+0

stderrをそのまま残すこともできます: 'stderr = sys.stderr.fileno()'。いい例です。私はすべてのスクリプトでこのテクニックを使用します。私たちは従来のPython 2.xを持っています。だから私はどこに混乱せずに行くように言いましたか正確に分かります。 –

6

:レガシー2.xのはPythonのバージョンとの互換性のため、

$ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"], 
         stderr=sys.stdout.buffer)' 

をまたは:

は、標準出力ファイルを渡す代わりに subprocess.STDOUT、問題を解決するために、 正確にドキュメントに記載されているもの:stderrをstdoutにリダイレクトします。

proc = subprocess.Popen(self.task["command"], shell=False, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
output = "" 
while (True): 
    # Read line from stdout, break if EOF reached, append line to output 
    line = proc.stdout.readline() 
    line = line.decode() 
    if (line == ""): break 
    output += line 

出力には、stdoutとstderrの両方からのプロセス出力が含まれます。

stderr=subprocess.STDOUTすべてのstderr出力を直接呼び出しプロセスのstdoutにリダイレクトします。これは大きな違いです。

+0

-1このケースは、 'stdout'が' None'であるという質問とは無関係です。そして、 'subprocess.STDOUT'は"呼び出し側コンソール "にリダイレクトされません(自分のプロセスが与えられたファイルハンドル1を意味すると思います)。Popenを' ['ls'、 '/404 '] '、[エラーメッセージは表示されません](http://ideone.com/2JhcRT)。 – phihag

+0

あなたは幾分正しいです。しかし、これはまったく無関係ではないと私は考えています。これは、誤解を招くような文書についてのあなたのポストを明確にすることを意図しているからです。私はあなたのポストの下にコメントを残していただろうが、1年前に私はそうすることは許されなかった。 – Maxxim

+0

'' ls'のstderrに行くことを示す ''/dev/null'は、 '' python -c ''サブプロセス、sys;サブプロセスコール(["ls"、 "/ 404"]、stderr = subprocess.STDOUT) stderr(ファイルディスクリプタ2)は出力が表示されないためです(システムに '/ 404'がないと仮定して)。そのPythonのドキュメントは本当にその話題を嫌っていました。私たちにとっては、stdout/stderrを操作するのに慣れ親しんでいるスクリプターを悩ましています。単純なやり方で何かをする方法を見つけるためにここに来なければなりません。混乱を招くことはありません。 –

関連する問題