【Python】Windowsコマンドプロンプトのコマンドを実行する方法(subprocessモジュール)

時計 2021.01.15 / 時計

【Python】Windowsコマンドプロンプトのコマンドを実行する方法(subprocessモジュール)

本記事ではPythonWindowsコマンドプロンプトのコマンドを実行する方法を解説していきます。

コマンドを実行することで様々な情報を取得することや、ファイル操作、ネットワーク管理をすることができますよね。

Pythonだけでは取得できない情報や操作も、コマンドプロンプトのコマンドを実行することで可能になることがあります。

Pythonスクリプトからコマンドを実行できるようになって、様々なアプリケーションを作成できるようになりましょう。

本記事を通して以下の知識を学べます。

学べる知識
  • Windowsコマンドプロンプトについて
  • Pythonでコマンドを実行する方法
  • Windows Build-inコマンドの実行方法

コマンドプロンプト

コマンドプロンプトとは

コマンドプロンプト(command prompt)とは、コマンド(命令文)を用いてファイル操作やWindows情報の取得、ネットワーク管理を行うためのツールです。

CUI(Character User Interface)なので、マウス操作は必要とせず、キーボードのみでコマンドを入力して操作します。

Windowsにおけるコマンドプロンプトは、UnixやMacではターミナルと呼ばれるツールです。

コマンドについて

コマンドは非常に多くの種類があります。
ネットワーク系コマンド(ipconfig、ping、nslookupなど)やファイル操作系コマンド(ls、dir、cdなど)、パソコン情報取得系(ver、wmicなど)といった種類があります。

WindowsのコマンドとLinux系のコマンドは同じものもあれば、異なるコマンドもたくさんありますので注意してください。

パソコンのハードウェア情報やシステム構成情報を取得するコマンドについては以下記事を参考にしてください。

Pythonでのコマンド実行方法

Pythonからコマンドを実行する方法は、osモジュールを使う方法とsubprocessモジュールを使う方法の2つがあります。

osモジュールではos.system()を使用して、コマンドを実行します。
しかし以下の理由からos.system()を使用することはお勧めしません。

  • Unix系コマンドの実行しかできない(Windowsコマンドが実行できない)
  • subprocessモジュールでも同様のことができ、subprocessの使用が推奨されている

os.system()でのコマンド実行方法についても解説していますが、必要ない方は飛ばしてください。

Windowsコマンドプロンプトのコマンド実行はsubprocessモジュールを使うことをお勧めしています。

subprocessモジュールではWindows built-inコマンドの実行ができますので非常に便利です。

osモジュール

os.system()

os.system()ではUnix系コマンドを実行できます。

os.system('コマンド')

osモジュールを使用するにはスクリプトの先頭でインポートする必要があります。
lsコマンドを使用するプログラムを以下に記します。

import os

os.system('ls')

しかし上述しているように、現在はsubprocessモジュールがありますので、subprocessモジュールを使用するのが良いです。

subprocessモジュール

subprocessモジュールとは

subprocessモジュールはPythonスクリプトから他のプログラム(アプリケーション)を起動するために使用されます。

標準モジュールなのでpipで別途インストールする必要はないです。

subprocessモジュールについては以下記事をご参照ください。

subprocessモジュールでWindowsコマンドプロンプトのコマンドを実行するメソッドは以下5つあります。

  • subprocess.call()
  • subprocess.check_call()
  • subprocess.check_output()
  • subprocess.run()
  • subprocess.Popen()

Windows Build in コマンドの実行

subprocessモジュールの各メソッドは、コマンドの後にオプションを指定することができます。

オプションにshell=Trueを指定することでWindows built-inコマンド(echo、wmic、dirなど)が実行できるようになります。

subprocess.check_output('echo %computername%', shell=True)

shell=Trueにより、コマンドをコマンドプロンプトから実行する形になります。

shell=False(デフォルト)では「指定されたファイルは見つかりません」というエラーが表示されます。
このエラーが表示されたらshell=Trueにしなければならないと思ってください。

subprocess.call()

subprocess.call()はコマンドをただ単に実行するだけのメソッドです。

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)

返り値は終了ステータス(0が正常終了)です。
call()では実行したコマンドによる出力を取得することはできません。

lsコマンドをスクリプトで実行するプログラムを以下に記します。

import subprocess

subprocess.call('ls')

subprocess.check_call()

subprocess.check_call()はcall()とは違い、コマンドが失敗した場合の処理をexcept文で例外処理ができます。

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)

コマンドが正常に終了すれば返り値0を、異常終了すればCalledProcessErrorを返します。
check_call()では実行したコマンドによる出力を取得することはできません。

以下にsubprocess.check_call()を使用した、tryとexcept文で処理を行うプログラムを記します。

import subprocess

try:
    subprocess.check_call("ls")
except:
    print("失敗")

subprocess.check_output()

subprocess.check_output()はコマンドを実行して、かつコマンドによる標準出力を返します。

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None)

標準出力はエンコードされたバイトで返されますので、デコードする必要があります。

subprocess.check_output('echo %computername%', shell=True).decode()

check_call()と同様に、コマンドが異常終了すればCalledProcessErrorを返します。

import subprocess

try:
    print(subprocess.check_output('echo %computername%', shell=True).decode())

except:
    print('失敗')

subprocess.run()について

subprocess.run()は上記で説明した3つのsubprocessメソッドが統合されたメソッドです。
上記3つのメソッドの用法がrun()でできます。

そのためsubprocess.run()はPython3.5以降から使用を推奨されています。

基本的にコマンドの実行はrun()メソッドで行えばいいです。

import subprocess

try:
    print(subprocess.run(['ver'], shell=True, stdout=subprocess.PIPE , stderr=subprocess.STDOUT))

except:
    print('失敗')
出力

CompletedProcess(args=['ver'], returncode=0, stdout=b'\r\nMicrosoft Windows [Version 10.0.19042.685]\r\n')

subprocess.run()の返り値は今までのメソッドとは異なります。
CompletedProcessインスタンスを返します。

上記出力より、run()による返り値CompletedProcessで一通りの結果を取得できることがわかります。

run()のオプション引数にstdout=subprocess.PIPEを指定することで標準出力を取得でき、stderr=subprocess.STDOUTで標準エラー出力が取得できます。

CompletedProcessから標準出力を取り出す場合は、以下のようにstdoutを指定します。

import subprocess

stdout = subprocess.run(['ver'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout
print(stdout)
出力

b'\r\nMicrosoft Windows [Version 10.0.19042.685]\r\n'

標準出力はエンコードされたバイトで返されますので、デコードする必要があります。

stdout.decode()

その他の結果も同様の方法で取り出すことができます。

指定 説明
stdout 標準出力
stderr 標準エラー出力
returncode 終了ステータス(正常終了は0 )

subprocess.run()では以下のように指定するコマンドはパラメータごとに分割してリストで渡します。

subprocess.run(['wmic', 'csproduct', 'get', 'identifyingnumber'], check=True, shell=True, stdout=subprocess.PIPE)

以上のようにrun()ではコマンドを指定して使用します。

subprocess.Popen()について

subprocess.Popen()でもrun()と同様にコマンドを実行できます。
ですがrun()とPopen()では処理に違いがあります。

Popen()の特徴として、Popen()で起動したプログラムの終了を待たないことです。
つまりPopen()で起動したプログラムの終了結果を待たずに次の処理を行うことができます。

run()とPopen()のどちらを使うかは、作成するプログラムによって決めてください。

まとめ

本記事の「【Python】Windowsコマンドプロンプトのコマンドを実行する方法」はいかがでしたか。

いろいろな方法を解説してきましたが、基本的にはsubprocess.run()またはsubprocess.Popen()のどちらかを使用すればいいです。

ぜひコマンドをPythonで使えるようになって、アプリケーション作成に活かしてください。