subprocess.run()を使う

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考

nnpo.hatenablog.com

この記事のbhnet.py(Netcatの置き換え)のところで、

公式ドキュメントにはrun関数を使うことが推奨されていたけれど、使い方が分からなかったので保留。

と言っていて大分放置していましたね。

output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)

のところを

output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
output = output.stdout

とすると上と下で同じ結果になります(たぶん)。

subprocess.runについてまとめます。

17.5. subprocess — サブプロセス管理 — Python 3.5.2 ドキュメント

公式ドキュメントに、

サブプロセスを起動する推奨手段は、すべての用法を扱える run() 関数を使用することです。

とあるので、やはり、python3.5以上ならば、run()関数を使うべきみたいですね。

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)

引数に関しては、

http://docs.python.jp/3/library/subprocess.html#frequently-used-arguments

ここを見ると分かりやすいです。

今回の例で言えば、commandが文字列です。

この文字列をシェル(コマンドプロンプト)上で実行したいので、shell=Trueと指定しています。

標準出力を取得したいので、stdout=subprocess.PIPEを指定します。

stderr=subprocess.STDOUTと指定することで、標準エラー出力がstdout と同じファイルハンドルに出力されます……と説明されているけれど、理解が五割程度です。

コマンドが実行されると、run()関数はCompletedProcessインスタンスを返します。

http://docs.python.jp/3/library/subprocess.html#subprocess.CompletedProcess

ここでは標準出力をクライアント側に送りたいので、output.stdoutで標準出力を得ます。

こんな感じです。