コマンドモジュールはPython2.6以降非推奨になっているため、コマンドの戻りコードと出力のタプルを返すcommands.getstatusoutputを置き換える最良の方法を検討しています。サブプロセスモジュールはかなり明白ですが、getstatusoutputを直接置き換えることはできません。考えられる解決策は、 getstatusoutputに関する関連する質問で説明されていますが、元の関数(LOCが10未満)を書き直すことは検討していませんが、もっと簡単な方法があるかどうかを知りたいと思います。
3 に答える
commands.getstatusoutput
悪いAPIだったので、直接の置き換えはありません。stderrとstdoutを組み合わせて、それらを個別に取得するオプションを提供しません。
使用する必要がある便利なAPIはsubprocess.check_output
、コマンドが失敗した場合に例外をスローするためです。
それ以外の場合は、1回の呼び出しで出力とステータスを取得する方法を提供しない、多少の欠陥のように見えますsubprocess
が、回避するのは簡単です。リンクされた質問に対する答えは次のようになります。
def get_status_output(*args, **kwargs):
p = subprocess.Popen(*args, **kwargs)
stdout, stderr = p.communicate()
return p.returncode, stdout, stderr
必要に応じstdout
て、stderr
一緒に使用しますstderr=subprocess.STDOUT
。
getstatusoutputが戻ってきました(python 3.1から):)参照:http ://docs.python.org/3.3/library/subprocess.html#legacy-shell-invocation-functions
タイトルからの質問に答えるには:これが非同期ベースのgetstatusoutput()
実装です-これは、より厳密にインターフェースに従うように変更されたドキュメントのコード例ですsubprocess.getstatusoutput()
:
import asyncio
import locale
from asyncio.subprocess import PIPE, STDOUT
@asyncio.coroutine
def getstatusoutput(cmd):
proc = yield from asyncio.create_subprocess_shell(cmd,
stdout=PIPE, stderr=STDOUT)
try:
stdout, _ = yield from proc.communicate()
except:
try:
proc.kill()
except ProcessLookupError: # process is already dead
pass
raise
finally:
exitcode = yield from proc.wait()
# return text
output = stdout.decode(locale.getpreferredencoding(False))
# universal newlines mode
output = output.replace("\r\n", "\n").replace("\r", "\n")
if output[-1:] == "\n": # remove a trailing newline
output = output[:-1]
return (exitcode, output)
WindowsとUnixの両方で動作します。それを実行するには(同じ例から):
import os
from contextlib import closing
if os.name == 'nt': # Windows
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
else:
loop = asyncio.get_event_loop()
with closing(loop):
coro = getstatusoutput('python -m platform')
exitcode, stdout = loop.run_until_complete(coro)
if exitcode == 0:
print("Platform:", stdout)
else:
print("Python failed with exit code %s: %s" % (exitcode, stdout))