0

Python 2.*の関数のこの素晴らしい代替品に出会いましたgetstatusoutput()。これは、Unix と Windows で同じように機能します。outputしかし、私は、の構築方法に何か問題があると思います。出力の最後の行のみが返されますが、理由がわかりません。どんな助けでも素晴らしいでしょう。

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
4

1 に答える 1

2

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

呼び出し:

pipe = subprocess.Popen(...)

プロセスを開始します。この線:

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

プロセスの stdout を読み取ります (エラー出力があった場合、エラーが発生する可能性がありますが、stderr をリダイレクトしていないため、これは安全です。より一般的なケースでは、.communicate()可能性のあるウェッジを回避するために関数を使用する必要があります)。あなたは思うかもしれません: さて、すべての出力を読んだので、サブプロセスは明らかに終了したので、pipe.returncode設定する必要があります。しかし、実際には、次のように置き換えます。

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

ある種の診断を含む (または 2 行目を完全に削除する) コードを使用すると、少なくとも一部のシステムでsts None. その理由は、subprocessモジュールがまだそれを取得する機会がないためです。これらの行を次のように置き換える必要があります。

sts = pipe.wait()

結果を収集し、is Noneテストの必要性を取り除きます。( を使用したことがある、および/または既に呼び出し.wait()ている場合でも、安全に呼び出すことができます。).communicate().wait()

以下"".join(...)を使用することで、わずかに効率的に実行できます。

output = pipe.stdout.read()

とはいえ、それは私にとって完全な出力を取得します。おそらく、改行のみを使用するものから読んでいて'\r'、Python はユニバーサル改行サポートなしで構築されていますか? ( \r-for-newline を生成するものを実行しても、実際の改行で区切られたすべての行が取得されます。)

于 2012-04-18T03:09:19.620 に答える