質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1967閲覧

pythonでparamikoを利用してネットワーク機器の設定変更を実施したいが、なぜこのコードで動作しないのか教えてほしい

yo_gu

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/03/30 05:26

実現したいこと

pythonで、paramikoでネットワーク機器にSSH接続後に設定変更を行いたい

前提

・ネットワーク機器(fortigate)にアクセスして設定変更を行いたい
・対話型インタプリタだと問題なく実行されるが、コードを記述したファイルから実行すると設定変更が反映されない
・設定変更のコマンド自体が正しい事は確認している

該当のソースコード

python3

1IP_ADDRESS = '192.168.1.1' 2USER_NAME = 'AAA' 3PASSWORD = 'BBB' 4 5# paramikoのインポート 6import paramiko 7 8# sshクライアントの作成 9client = paramiko.SSHClient() 10client.set_missing_host_key_policy(paramiko.WarningPolicy()) 11 12# 上記で設定したIPアドレス、ユーザー名、キーファイルを渡す 13client.connect(IP_ADDRESS, 14 username=USER_NAME, 15 password=PASSWORD, 16 timeout=5.0) 17 18# コマンド設定 19object_name = "test1" 20object = "192.168.1.1/24" 21 22command = f"config firewall address \nedit {object_name} \nset subnet {object} \nend" 23 24# コマンドの実行 25stdin, stdout, stderr = client.exec_command(command) 26

試したこと

・上記を対話型インタプリタで実行すると、問題なく設定変更が反映される
・上記をファイルから実行すると、設定変更が反映されない
・コードの最後にprint(stdout.read())を追加するとファイルから実行してもなぜか設定変更が反映される

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

exec_command()メソッドは、コマンドの実行を開始した直後に=終了を待たずに返ります。
もし、プログラムがそこで終了してしまっていると、即座にセッションが切れてしまうので、開始されたコマンドが強制的に終了してしまうのです。

対話型で実行している場合、メソッド実行後にもインタープリタは生きているので、セッションは切れません。

また、出力を得るために、stdout.read()を実行すると、コマンドの出力結果を待つことでコマンドが実行されるようになるということです。


ちなみに、paramikoはかなり低レベルのAPIでできているので、手動の作業の自動化が目的であれば、もう少し高レベルの pexpectを使ったり、ルータなどのみが対象であればnetmikoあたりを検討するのもいいと思います。
また、pythonプログラムでの制御が目的ということでなければ、ansibleを使うというのもありでしょう。

投稿2023/03/30 05:48

編集2023/03/30 07:39
TakaiY

総合スコア12726

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ChatGPTの回答

質問文は省略

設定変更が反映されない原因は、コマンドの実行後に接続が切断されてしまうためです。これは、exec_command() メソッドがコマンドの実行を非同期で行うためであり、コマンドの完了を待たずに接続を閉じてしまうためです。そのため、コマンドの完了を待つためには、stdout.read() を使用する必要があります。stdout.read() はコマンドの実行を同期的に行うため、コマンドが完了するまで待機し、その後接続を閉じるため、設定変更が反映されるようになります。

以下は、設定変更が反映されるように修正したコード例です。

Python

1IP_ADDRESS = '192.168.1.1' 2USER_NAME = 'AAA' 3PASSWORD = 'BBB' 4 5# paramikoのインポート 6import paramiko 7 8# sshクライアントの作成 9client = paramiko.SSHClient() 10client.set_missing_host_key_policy(paramiko.WarningPolicy()) 11 12# 上記で設定したIPアドレス、ユーザー名、キーファイルを渡す 13client.connect(IP_ADDRESS, 14 username=USER_NAME, 15 password=PASSWORD, 16 timeout=5.0) 17 18# コマンド設定 19object_name = "test1" 20object = "192.168.1.1/24" 21 22command = f"config firewall address \nedit {object_name} \nset subnet {object} \nend" 23 24# コマンドの実行 25stdin, stdout, stderr = client.exec_command(command) 26output = stdout.read() 27print(output) 28 29# 接続の終了 30client.close()

上記のコードでは、exec_command() メソッドの出力を stdout.read() で同期的に読み込むことで、コマンドの完了を待ち、設定変更が反映されるようにしています。また、接続を閉じるためには、client.close() を呼び出すことで正しく接続を終了できます。

投稿2023/03/30 05:32

can110

総合スコア38252

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2023/03/30 05:56

すごいなChatGPT
can110

2023/03/30 06:39

たまに「息をするように嘘を吐く」こともあるので注意は必要です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問