IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

Pythonでネットワーク自動化をしよう

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第17回 subprocessライブラリ(2)Popen (小澤昌樹) 2023年12月

1.はじめに

みなさん、こんにちは。

ネットワーク自動化に役立つPythonのモジュールやライブラリの一つとして、subprocess ライブラリを紹介しました。subprocess ライブラリを使うと、Pythonスクリプトから外部プロセスを実行し、そのプロセスの入出力を制御できます。

前回は、その subprocess ライブラリの run 関数を紹介しました。run 関数は、Pythonのスクリプトから外部プロセスを実行し、そのプロセスの結果を取得するものです。外部プロセスの実行をシンプルに扱うように設計されており、プロセスの実行、終了コードの確認、標準出力およびエラー出力の取得などを一括して行えます。subprocess.run では外部プロセスを同期的に実行するため、プロセスが終了するまで次の処理に進むことはできません。

今回は、subprocess ライブラリを使用した非同期処理について説明します。プロセスの終了を待たずに複数のプロセスを同時に実行する方法です。

2. subprocessライブラリでの非同期処理

非同期処理は、複数のプロセスを同時に実行し、待機せずに他のタスクを実行できるため、効率的なネットワーク自動化に不可欠です。非同期処理を実現するには、subprocess ライブラリのsubprocess.Popen クラスを使用します。このクラスを使うことで、複数のプロセスを非同期に実行できます。非同期処理を行う基本的な手順は以下です。

  1. subprocess.Popen を使用して、コンストラクタにコマンドと引数を指定してプロセスを起動します。各プロセスはバックグラウンドで実行されます。
  2. 各プロセスの完了を待つか、プロセスが完了するたびに処理を行うループを設定します。
  3. プロセスが完了したら、その結果を取得して必要な処理を行います。

以下は、実際のプログラム例です。この例では、subprocess.Popen を使用して3つの異なるコマンドを非同期に実行しています。各プロセスの完了を待つために、communicate メソッドを使用し、それぞれのプロセスの終了コードを確認しています。


import subprocess
# コマンドをリストで指定 commands = [ ["command1", "arg1", "arg2"], ["command2", "arg1"], ["command3"] ]
# プロセスを格納するリスト processes = []
# 1. 各コマンドを非同期で実行 for cmd in commands: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) processes.append(process)
# 2. 各プロセスの完了を待つ for process in processes: stdout, stderr = process.communicate() if process.returncode == 0: print(f"成功: {stdout.decode()}") else: print(f"エラー: {stderr.decode()}")

このプログラムについてもう少し解説しましょう。

  1. 各コマンドを非同期で実行
    subprocess.Popen は、指定されたコマンド(変数:cmd)を実行する新しいプロセスを開始します。ここで cmd は、実行したいコマンドとその引数を含むリストです。例えば、["ls", "-l"] は "ls -l" コマンドを実行します。 stdout=subprocess.PIPEstderr=subprocess.PIPE は、プロセスの標準出力および標準エラー出力をキャプチャし、それを後で取得できるようにするための設定です。これにより、プロセスの出力を取得できるようになります。
    processes はプロセスを格納するためのリストで各プロセスの完了を判断するために、このあとで使われます。append メソッドは、リストの末尾に要素を追加するメソッドです。

  2. 各プロセスの完了を待つ
    リストに格納されたプロセスを一つ一つ取り出し、communicate メソッドを呼び出します。communicate メソッドは、外部プロセスが完了するまでブロックします。つまり、このメソッドが呼ばれると、プログラムの実行がその行で一時停止し、プロセスが終了するまで処理が戻りません。そのプロセスが終了したら処理が続行されるので、returncode 属性を見ることで、そのプロセスが正常に終了したか、エラーで終了したかを判断できます。終了コードが 0 である場合は正常終了を示し、0以外の終了コードは、何らかのエラーが発生したことを示します。ただし、終了コードの具体的な値や意味は、実行された外部プロセスによって異なります。
3. まとめ

今回は、subprocess ライブラリの Popen を紹介しました。

Popenとrunの違いは以下です。

  1. Popen
    • Popen を使用すると、外部プロセスを生成し、その標準入力、標準出力、標準エラーなどとやり取りすることができます。
    • Popen オブジェクトは、生成されたプロセスであり、非同期でプロセスの実行を監視したり、制御したりできます。
  2. run
    • run は単純な外部プロセスの実行を行います。通常、単純でブロッキングな使い方ができ、外部プロセスの起動から終了までを待ちます。
    • run 関数は Popen オブジェクトを作成し、そのプロセスを実行して終了まで待機するといったシンプルな方法を提供しています。

どちらを選択すべきかは、用途によります。もし外部プロセスを非同期で実行し、その標準入出力を制御したり、何度も非同期で実行したりする必要がある場合は、Popen を使用すればよいでしょう。一方で、シンプルに外部コマンドを実行して結果を取得したいだけであれば、run 関数が使いやすいかもしれません。

次回は、telnetlibライブラリを紹介します。次回もお楽しみに。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes