今回は、みんな大好きPythonでシステムコマンドを実行して、結果を出力する方法を解説します。
システムコマンドと言いますが、Terminal上で使えるコマンドすべてをPythonで実行する方法です。
jqを利用してSpeedtestのjsonからdownloadとuploadだけを取得する方法
https://qiita.com/Bob_Alice/items/83c0686f56012b300780
#Pythonのライブラリ「subprocess」を使う
まずは、Pythonのライブラリ「subprocess」を利用することで簡単にシステムコマンドを実行できます。
利用方法はめちゃめちゃ簡単で、Pythonで
result = subprocess.run(['コマンド','そのコマンドの引数'], stdout=subprocess.PIPE)
とすると、
result.returncode
にそのコマンドのステータスコード(成功OR失敗)が入って、
result.stdout
に標準出力の結果が代入されます。
#引数が複数あるときはどうすればいいんだ
引数が複数あるときには、なんかいろいろやり方があるらしいですが、セキュリティ的に問題があるらしいです。
今回、私の用途では利用するコマンドとその引数は決まっていたため、それを実行するためのシェルスクリプトを作っておきました。
シェルスクリプトといっても、難しいものではなく、ただただ利用したいコマンドと引数を記載したファイルを拡張子.sh で保存しておくだけです。
今回は、用意したjsonファイルからjqコマンドを利用して特定の値を出力する以下のコマンドを実行するのが目的でした。
cat result.json | jq ".download.bandwidth"
そのため、「get_download_bandwidth_from_result.sh」というファイルにこのコマンドを記載して保存しておきました。
すると以下のPythonコードとなりました。
import subprocess
result = subprocess.run(['sh','get_download_bandwidth_from_result.sh'], stdout=subprocess.PIPE)
print(result.returncode)
print(result.stdout)
出力結果
b'33052461\n'
#文字をデコードしないといけない
ただ、subprocessで標準出力を受け取るとエンコードされたバイトとなってしまいます。
これを通常の表示にするためにデコードをする必要があります。
subprocessについてより深く(3系,更新版)
https://qiita.com/HidKamiya/items/e192a55371a2961ca8a4
そこで
result.stdout.decode().strip().split('\n')
とすることで、デコースできました。
ただ、デコースした結果はリストとして格納されてしまっているため、単一の変数として扱うためにはそのリストの最初(0番目)の変数ということを指定する必要があります。
output = result.stdout.decode().strip().split('\n')[0]
とすることで、変数outputにデコース後の最初の数字が入りました。
最終的に以下のPythonのコードとなりました。
import subprocess
result = subprocess.run(['sh','get_download_bandwidth_from_result.sh'], stdout=subprocess.PIPE)
print(result.returncode)
print(result.stdout)
print(result.stdout.decode().strip().split('\n'))
これで完璧。
おわおわり。
#追記
subprocess.run() は Python3.5以降じゃないと利用できないため注意
https://ja.ojit.com/so/python/232121