Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
今回はPythonのプログラムからWindowsのコマンドプロンプトを使えるsubprocessモジュールの基本的な使い方を説明します。
今回はWindowsのコマンドプロンプトを使う例の解説ですが、MacやLinuxのコマンドを使うこともできます。
Contents
参考リンク:Python公式ドキュメント、subprocess — サブプロセス管理¶
PythonプログラムからWindowsのコマンドプロンプト機能を呼び出すのに、一番簡単な方法は、subprocessモジュールが提供するrunメソッドを使うことです。
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)¶
このような形で使うことになります。なにやら「(args~」以下がややこしいことになっていますが、runメソッドの引数が、
などというようにたくさん存在しているだけです。これらを全て設定する必要はなく、必要に応じていろいろ引数の設定を変更することになります。
ただし、第1引数argsは、コマンドプロンプトで実行するコマンドそのものを受けるため、それは基本的に必須です。
それではさっそくsubprocess.runの使い方を簡単な例で見ていきましょう。
今回の例は、Cドライブ>Users>hogehoge>PythonSampleフォルダ内の、ファイルとフォルダの一覧を表示させるものです。
まずはPythonではなく、コマンドプロンプトそのものを使ってそれを行ってみましょう。
コマンドプロンプトでは、フォルダ内部のファイルやフォルダの情報を取得するコマンドとして、
dir フォルダへのパス
とします。そこで今回はコマンドプロンプトに、
dir C:\Users\hogehoge\PythonSample
と入力して実行します。フォルダへのパスはみなさんの環境に合わせていろいろ変えてください。これで対象フォルダ内部のファイアルなどの一覧がコマンドプロンプト上で表示されたと思います。
では次にPythonのプログラムの中でコマンドプロンプトを通じてそれを実現してみましょう。まずVS Codeでもなんでもいいので、テキトーに「subprocess_test.py」というような名前のPythonファイルを新規作成します。
次に下のようなコードを書きます。
import subprocess
subprocess.run("dir C:\\Users\\hogehoge\\PythonSample", shell=True, check=True)
runメソッドは、
を設定しています。
これを実行すると、同じようにPythonSampleフォルダ内部のフォルダやファイルの一覧が表示されるでしょう。
まずrunメソッドの公式説明の第1引数argsについては、
のどちらかでなければなりません。
上の使用例では文字列、
"dir C:\\Users\\hogehoge\\PythonSample"
にしてあります。
なお、コマンドを連結して、2つの処理を連続して行いたい場合は、たとえばですが、
command = "cd C:/Users/yasumitsu/Dropbox & dir"
というように、「&」記号を使って、コマンドを連結できます。
また、文字列ではなくシーケンス型オブジェクト使って、例えば今回はリストを使って書く場合は、
#コマンドプロンプトでは、「cd C:/~」のようにコマンドの後に空白を置くが、シーケンスにする場合は空白をいれない。
command_list = ["cd", "C:/Users/yasumitsu/Dropbox", "&dir"
このように書けます。
ここでは、公式解説の「Windows における引数シーケンスから文字列への変換¶」の項目で、
Windows では、 args シーケンスは以下の (MS C ランタイムで使われる規則に対応する) 規則を使って解析できる文字列に変換されます:
- 引数は、スペースかタブのどちらかの空白で分けられます。
- ダブルクオーテーションマークで囲まれた文字列は、空白が含まれていたとしても 1 つの引数として解釈されます。クオートされた文字列は引数に埋め込めます。
- バックスラッシュに続くダブルクオーテーションマークは、リテラルのダブルクオーテーションマークと解釈されます。
- バックスラッシュは、ダブルクオーテーションが続かない限り、リテラルとして解釈されます。
- 複数のバックスラッシュにダブルクオーテーションマークが続くなら、バックスラッシュ 2 つで 1 つのバックスラッシュ文字と解釈されます。バックスラッシュの数が奇数なら、最後のバックスラッシュは規則 3 に従って続くダブルクオーテーションマークをエスケープします。
というような処理がおこなわれ、シーケンス型から文字列へ変化されます。
ここで少し注意しなければならないのが、コマンドプロンプト特有の問題というかWindows環境特有の問題というべきか、円記号「¥」の処理です。
Pythonでは「¥」は特殊な文字扱いになりますので、さらに「¥」をつけて「¥¥」とすることでエラーが出るのを回避しています。
上でコマンドプロンプトそのものを使う場合では、そのようなことはせず、「¥」を1つだけ使っていることと比較してください。
この点については、過去記事「Pythonの特殊記号「¥」(バックスラッシュ’\’)とエスケープシーケンスについての解説」で説明していますので読んでみてください。
今回のコード例の第2引数shell=Trueの部分については、公式の次の説明を参考にしましょう。
Windows で
shell=True
とすると、COMSPEC
環境変数がデフォルトシェルを指定します。Windows でshell=True
を指定する必要があるのは、実行したいコマンドがシェルに組み込みの場合だけです (例えば dir や copy)。バッチファイルやコンソールベースの実行ファイルを実行するためにshell=True
は必要ありません。
ここで、「COMSPEC
環境変数がデフォルトシェルを指定します」とありますが、普通はWindowsの場合はコマンドプロンプトまたはWindows Powershellになるでしょう。
特にWindows11だとデフォルトシェルがWindows Powershellです。しかし私の場合はコマンドプロンプトです。
そこで、まずshell=Trueとすることで私の環境ではコマンドプロンプトを使うように設定されるという意味です。
次に今回コマンドとして使用する「dir」コマンドは、実はコマンドプロンプト特有のコマンドで、MacのシェルやLinuxのシェルには存在しません。
そこで、「Windows で shell=True
を指定する必要があるのは、実行したいコマンドがシェルに組み込みの場合だけです (例えば dir や copy」という記述がキーポイントとなります。
今回使う「dir」コマンドはまさにそれです。
第3引数のcheck=Trueについては、次の公式説明を見てください。
check に真を指定した場合、プロセスが非ゼロの終了コードで終了すると CalledProcessError 例外が送出されます。
普通Pythonプログラムから指定したコマンドを実行させてそれが成功し完了すると、「ゼロ」が返されます。しかし、エラーが出たときはゼロ以外が返されます。そこで、ゼロ以外ならばCalledProcessError 例外が返ってくるようにしている、という設定です。Falseにするとその例外が返ってきません。
例外が返ってくるほうがいろいろ都合が良いことも多いでしょう。その例外が返ってきたときに、じゃあ次どうするという処理を書けますから。