Python 3のsubprocessモジュールを使用したタイムアウト設定方法
Pythonのsubprocessモジュールは、外部プログラムやコマンドを実行するための強力なツールです。特に、シェルコマンドをPythonスクリプト内で実行する際に便利です。しかし、外部プロセスが予期せず長時間実行されることを防ぐために、タイムアウトを設定することが重要です。この記事では、Python 3でsubprocessモジュールを使用して、タイムアウトを設定する方法を詳しく解説します。
subprocess.run()のタイムアウトオプション
Python 3.5以降、subprocessモジュールのrun()関数には、タイムアウトを設定するためのオプションが追加されました。このオプションを使用することで、指定した時間内にプロセスが終了しない場合にTimeoutExpired例外を発生させることができます。
import subprocess try: result = subprocess.run(['sleep', '5'], timeout=3) except subprocess.TimeoutExpired: print("プロセスがタイムアウトしました")
この例では、’sleep 5’というコマンドを3秒のタイムアウトで実行しようとしています。プロセスが3秒以内に終了しないため、TimeoutExpired例外が発生し、「プロセスがタイムアウトしました」と出力されます。
subprocess.Popen()でのタイムアウトの実装
subprocess.run()ではなく、Popenオブジェクトを使用してプロセスを実行したい場合もあります。この場合、タイムアウトを実現するためには、手動でプロセスの監視を行う必要があります。
import subprocess import time process = subprocess.Popen(['sleep', '5']) try: process.wait(timeout=3) except subprocess.TimeoutExpired: process.kill() print("プロセスがタイムアウトし、終了されました")
この例では、Popenオブジェクトを使用してプロセスを開始し、wait()メソッドで3秒のタイムアウトを設定しています。プロセスがタイムアウトすると、kill()メソッドでプロセスを強制終了し、「プロセスがタイムアウトし、終了されました」と出力されます。
タイムアウトを使用した実用的な例
次に、タイムアウトを使用して、長時間実行される可能性のある外部コマンドを安全に実行する実用的な例を示します。
import subprocess def execute_command_with_timeout(command, timeout): try: result = subprocess.run(command, timeout=timeout, capture_output=True, text=True) return result.stdout except subprocess.TimeoutExpired: return "コマンドがタイムアウトしました" output = execute_command_with_timeout(['ping', '-c', '4', 'localhost'], timeout=2) print(output)
この関数は、指定したコマンドを実行し、タイムアウトが発生した場合にメッセージを返します。’ping’コマンドを2秒のタイムアウトで実行しようとしていますが、通常の実行時間を超えるため、タイムアウトメッセージが出力されます。
まとめ
subprocessモジュールを使用する際には、タイムアウトを設定することで、スクリプトの安定性と安全性を向上させることができます。run()関数のtimeoutオプションを活用するのが最も簡単な方法ですが、Popenオブジェクトを使用する場合には、手動でプロセスを監視する必要があります。これらの方法を活用して、外部プロセスの実行をより効率的に管理しましょう。
Python 3のsubprocessモジュールは、外部プロセスを実行するための機能を提供します。このモジュールを使用すると、Pythonスクリプトから別のプログラムを実行し、そのプログラムの出力を取得することができます。
タイムアウト付きでsubprocessを使用する場合、外部プロセスが指定された時間内に完了しない場合に、プロセスを強制的に終了させることができます。これにより、プロセスが無限ループに陥ったり、応答しなくなったりすることを防ぐことができます。
タイムアウトを設定するには、subprocess.run()やsubprocess.Popen()などの関数を使用し、timeoutパラメータにタイムアウト時間を指定します。タイムアウトが発生した場合、TimeoutExpired例外が発生します。
例えば、以下のようにしてsubprocessをタイムアウト付きで使用することができます:
import subprocess
try:
result = subprocess.run([“ls”, “-l”], timeout=5, check=True)
print(result.stdout)
except subprocess.TimeoutExpired:
print(“タイムアウトしました。”)