subprocessとは¶
pythonでコマンド(MacにおけるターミナルやWindowsにコマンドプロンプトで実行するもの)を実行するためのパッケージです.詳しく説明してくれているサイトもなかったのでいろいろ試してみました.
公式ドキュメントはこちら↓
基本的な使い方¶
先にpythonの実行環境を示します.
import sys
print(sys.version)
使い方としては,subprocess.run('command')
または,subprocess.run(['command', 'option1', 'option2'])
などのように書きます.
たとえば,macの実行環境を出力するsw_vers
コマンドをpythonから呼び出したいとします.(sw_vers
コマンドに関しては以下のサイト参照)
import subprocess
subprocess.run('sw_vers')
以上のようにして,そのコマンドの文字列を与えることで実行することができます.
しかし以上のコードでは,確かに実行されているのですが,これでは結果がどこにも見れません.
結果の出力先をstdout
という引数に指定することで出力することができます.
結果を標準出力したい場合¶
標準出力とはターミナル(コマンドプロンプト)上に表示させる,ということです.
それをしたいとき,stdout
に,subprocess.PIPE
を指定します.こうすることでその文字列をpythonの変数で受け取ることもできます.
たとえば,以下のようにします.
process = subprocess.run('sw_vers', stdout = subprocess.PIPE)
print(process.stdout.decode()) # バイトで得られるのでdecode()した.
デフォルトではstdout
はbyteで得られてしまうのでこれを任意の文字コードで出力するためには,以上のようにdecode
してあげるか,引数encoding
を指定します.
process = subprocess.run('sw_vers', stdout = subprocess.PIPE, encoding = 'utf_8_sig')
print(process.stdout) # バイトで得られるのでdecode()した.
また,先に示した通りcommandの他にoptionを与えることができます.
たとえばsw_vers
を実行する際のオプションとしてProductVersionだけを取得するoptionである-productVersion
というものがあります.これを実行するためには以下のようにリストで与えます.
product_version = subprocess.run(['sw_vers', '-productVersion'], stdout = subprocess.PIPE, encoding = 'utf_8_sig').stdout
print(product_version)
やりがちなミスとしてリストではなく,そのまま引数として加えるというミスをやりがちです.その場合エラーコードは以下のようになるので参考にしてください.
subprocess.run('sw_vers', '-productVersion', stdout = subprocess.PIPE, encoding = 'utf_8_sig')
結果をファイルとして書き出したい場合¶
その場合は,ファイルオブジェクトを渡します.
たとえばこのmacの実行条件をoutput.txtというファイルに書き出したいと思った場合以下のように書くことができます.
with open('output.txt', mode = 'w') as f:
subprocess.run('sw_vers', stdout = f, encoding = 'utf_8_sig')
ファイルオブジェクトの取り扱い方法はいくつかあるのですが,一番簡便なのはこの書き方だと個人的には思っているのでこちらのやり方で紹介しています.
その他のやり方が興味がある人は是非調べてみてください.参考になるかもしれないサイト↓
より実践的な実行例¶
以上のやり方を応用すればanacondaの仮想環境を書き出したりすることができ,再現性を確保するために一役買うことができるかもしれません.
以下のコードで実行できます.
with open('env.yml', mode = 'w') as f:
subprocess.run(['conda', 'env', 'export'], stdout = f, encoding = 'utf_8_sig')
逆に個別のanacondaの仮想環境を作ったりできますので,使用方法はたくさんあるかも?です.
ちなみにですが,本来ターミナル上でanacondaの仮想環境を書き出す場合
conda env export > env.yml
とするので,
subprocess.run(['conda', 'env', 'export', '>', 'env.yml'])
で行けそうな感じがしますが,ファイルが生成されないので無理そうです.
ちなみにsubprocess.run
コマンドを実行したときに返ってくるインスタンスCompletedProcess
のreturncode
の値が0のときは何も問題がなく終了したことを示すので,それ以外の値だったときは何かしら問題が起きているので参考にすると良いかもしれないです.
anacondaの仮想環境情報の書き出しはこちらを参考に↓.
まとめ¶
- コマンドのみの実行:
subprocess.run('command')
←文字列で渡す - オプションをつける場合:
subprocess.run(['command', 'option1', 'option2', ...])
←リストで渡す - 出力させたい場合
- 標準出力:
subprocess.run('command', stdout = subprocess.PIPE)
- ファイル出力:
subprocess.run('command', stdout = f)
←f
はファイルオブジェクト
- 標準出力:
0 件のコメント:
コメントを投稿