2012-04-18 11 views
0

Python 2の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

+0

リターンコードが0でも出力をしたいのですが? – MFB

答えて

2

これにはバグがあります。

コール:

pipe = subprocess.Popen(...) 

キックオフプロセス。ライン:

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

はエラー出力があった場合、それがアップ詰まっ得ることができますが、あなたは標準エラー出力をリダイレクトしていなかったので、これは安全である(プロセスの標準出力を読み込み、より一般的な場合には、あなたは.communicate()機能を使用する必要があります可能性のある楔止めを避けるため)。あなたは考えているかもしれません:まあ、私はすべての出力を読み取ったので、サブプロセスは明らかに終了しているので、pipe.returncodeを設定する必要があります。あなたが交換した場合でも、実際には、いくつかの並べ替えの診断(または単に完全に二行を削除)を含むコードと

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

を、あなたはあるsts、少なくともいくつかのシステムでは時々、ことがわかりますNone。その理由は、subprocessモジュールがそれをまだ検索する機会がなかったからです。結果を収集し、is Noneテストの必要性を回避するために

sts = pipe.wait() 

:あなたがこれらの行を交換する必要があります。 (それはあなたが.communicate()を使用および/またはすでに.wait()呼ばれてきた場合でも.wait()を呼び出すしても安全です。)

"".join(...)だけで使用することによって、わずかに、より効率的に行うことができます。それがない、と述べている

output = pipe.stdout.read() 

すべて私のために完全な出力を得る。おそらく、改行のためにちょうど'\r'を使用していて、普遍的な改行をサポートしていないPythonがビルドされているのでしょうか? (\r -for-newlineを生成するものを実行すると、実際の改行で区切られたすべての行が得られます)

+0

この優秀な説明のおかげで。私はすでにたくさんのことを学んできました。しかし、私はあなたが改行のもので何かをしていると思います。私は自分の関数から '' \ n ''を返すだけです。改行問題を拡張していただけますか? – MFB

+0

[docs](http://docs.python.org/library/functions.html#open)によると、「普遍的な改行」とは、入力ストリームを読むときに、 \ r'または '\ r \ n'または普通の' \ n'はPythonに単純な '\ n'文字を"見せ "ます。しかし、これには、Pythonをサポート付きで構築する必要があります。もしそうでなければ、普通の '\ r'は' \ r'とみなされ、結果の文字列を 'print'すればすべてが見えないかもしれません。例: ''> 'print' something \ relse'' *が表示され、 'elsething'が表示されます。 – torek

+0

それは理にかなっていますが、 '\ n'ですべての出力を混ぜ合わせるべきではありませんか?代わりに、私はサブプロセス(この場合はffmpeg)が束をより多く出力していることを知っていても、単に単一の\ nを取得しています。 – MFB

関連する問題