Pythonでos.systemやsubprocessを使って外部コマンドを実行する方法

スポンサーリンク
スポンサーリンク

イントロダクション

この記事では、Pythonのシステムコマンドを使用してシェルコマンドを実行する方法について説明します。

それでは、Pythonのシステムコマンドの基礎から始めましょう。

Pythonシステムコマンドとは?

Pythonでいくつかのシステム管理タスクを実行するための機能を統合する必要があるかもしれません。

これには、ファイルの検索、シェルコマンドの実行、高度なファイル操作などが含まれます。

そして、そうするためには、システムとPythonインタプリタとの間のインターフェイスの方法が必要です。

Pythonを使ったコマンドラインの実行は、 os モジュール のシステムメソッドを使うことで簡単に行うことができます。

しかし、 subprocess モジュールの導入 (いくつかの古いモジュールを置き換えることを意図しています) により、コマンドラインへのアクセスはより簡単に使えるようになりました。

また、出力を操作したり、従来の方法の制限を回避することもできます。

Python でシェルコマンドを実行する

さて、Pythonのシステムコマンドについて知ることができました。

では、同じものをどのように実装するか見てみましょう。

1. os.system() メソッドの使用

先に述べたように、Python でシェルコマンドを実行するには、os モジュールのいくつかのメソッドを使用すると簡単に実行することができます

ここでは、広く使われている os.system() メソッドを使用します。

この関数は C の system() 関数を使って実装されているので、同じ制約があります。

このメソッドは、システムコマンドを文字列として入力し、終了コードを返します。

以下の例では、Pythonのコマンドラインを使用して、システムのPythonのバージョンを確認することを試みます。

import os
 
command = "python --version" #command to be executed
 
res = os.system(command)
#the method returns the exit status
 
print("Returned Value: ", res)

出力されます。

Python 3.7.4
Returned Value:  0

ここで、resには返された値(成功の場合は終了コード=0)が格納される。

この出力から明らかなように、コマンドは正常に実行され、期待通りのPythonのバージョンを取得することができました。

2. subprocess モジュールの使用法

subprocess` モジュールには、新しいプロセスを生成し、その入力/出力/エラーパイプに接続し、そのリターンコードを取得するための様々な便利なメソッドや関数が付属しています。

この記事では、使いやすく信頼性の高い call()check_output() メソッドについて説明します。

しかし、より詳細な情報については、いつでも公式のドキュメントを参照することができます

2.1. call() メソッド

それでは subprocess.call() メソッドについて説明します。

call()メソッドは文字列のリストとして、あるいはシェルの引数をTrue` に設定して渡されたコマンドライン引数を受け取ります。

そして、終了コードやステータスを返します。

以下のコードでは、シェルからPIPを使用してpandasをインストールすることを試みています。

import subprocess
 
command = "pip install pandas" #command to be executed
 
res = subprocess.call(command, shell = True)
#the method returns the exit code
 
print("Returned Value: ", res)

出力されます。

Collecting pandas
  Downloading pandas-1.0.3-cp37-cp37m-win32.whl (7.5 MB)
Requirement already satisfied: pytz>=2017.2 in c:userssnehappdatalocalprogramspythonpython37-32libsite-packages (from pandas) (2019.3)
Requirement already satisfied: numpy>=1.13.3 in c:userssnehappdatalocalprogramspythonpython37-32libsite-packages (from pandas) (1.18.1)
Requirement already satisfied: python-dateutil>=2.6.1 in c:userssnehappdatalocalprogramspythonpython37-32libsite-packages (from pandas) (2.8.1)
Requirement already satisfied: six>=1.5 in c:userssnehappdatalocalprogramspythonpython37-32libsite-packages (from python-dateutil>=2.6.1->pandas) (1.14.0)
Installing collected packages: pandas
Successfully installed pandas-1.0.3
Returned Value:  0

見ての通り、コマンドは正常に実行され、戻り値は zero です。

2.2. check_output() メソッド

上記のメソッドはシェルコマンドを正常に実行しますが、ユーザが出力を操作する自由は与えません。

そのため、サブプロセスの check_output() メソッドが登場します。

このメソッドは渡されたコマンドを実行しますが、終了ステータスを返すのではなく、今回は bytes オブジェクトを返します。

以下の例では、pymysqlモジュールを再度インストールしようとしています(すでにインストールされています)ので、詳しく見てみましょう。

import subprocess
 
command = "pip install pymysql" #command to be executed
 
res = subprocess.check_output(command) #system command
 
print("Return type: ", type(res)) #type of the value returned
 
print("Decoded string: ", res.decode("utf-8")) #decoded result

出力されます。

Return type:  <class 'bytes'>
Decoded string:  Requirement already satisfied: pymysql in c:userssnehappdatalocalprogramspythonpython37-32libsite-packages (0.9.3)

前の例と同様に、 res には check_output() メソッドから返されたオブジェクトが格納されています。

type(res)により、オブジェクトがbytes` 型であることが確認できます。

その後、デコードされた文字列を表示し、コマンドが正常に実行されたことを確認します。

まとめ

さて、今日は Python のシステムコマンド (os.system()) と subprocess モジュールを使ってシステムコマンドを実行する方法について学びました。

ここでは、さらにいくつかの Python 関連のコマンドを考えましたが、方法はこれらに限定されるものではないことに注意してください。

理解を深めるために、自分で上記の方法を使って他のコマンドを試してみることをお勧めします。

さらに質問がある場合は、以下のコメント欄からお気軽にどうぞ。

参考文献

  • Python subprocess ドキュメント
  • Python os ドキュメント
  • Python システムコマンド – os.system(), subprocess.call() – Journal Dev の記事。
タイトルとURLをコピーしました