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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2998閲覧

pythonのtelnetlibでL3スイッチを操作できない

sumou_sumou

総合スコア1

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/08 10:21

編集2021/03/09 05:49

前提・実現したいこと

Allied Telesis製のL3スイッチに対してpythonのtelnetlibで操作を試みています。

telnetlibのサンプルを参考に、単純なコマンドを実行して結果を出力してみたところ、read_all()にコマンドの結果が出力されませんでした。
途中経過をread_eager()を使用して出力してみましたが何も表示されないため、正常にコマンドを送信できていないのだと思われます。

何が原因かが全くつかめない状況です。
調査方法など、問題を解消できるヒントをいただけないでしょうか。

発生している問題・エラーメッセージ

スクリプトを実行した結果は以下の通りです。
修正後

shell

1$ python3 telnet.py 2Login: 3Login Success 4b'' 5b'' 6exit

該当のソースコード

python

1# -*- coding:utf-8 -*- 2import getpass 3import sys 4import telnetlib 5 6HOST = "xxx.xxx.xxx.xxx" 7#user = input("Enter your remote account: ") 8#password = getpass.getpass() 9user = b"adminuser" 10password = b"dummypassword" 11 12tn = telnetlib.Telnet(HOST) 13 14tn.read_until(b"login: ") 15print("Login:") 16 17tn.write(user + b"\n") 18if password: 19 tn.read_until(b"Password: ") 20 tn.write(password + b"\n") 21 print("Login Success") 22 23tn.read_until(b'>') 24 25#ページ送り無効 26tn.write(b"terminal length 0\n") 27print(tn.read_eager()) 28 29tn.read_until(b">") 30 31 32#特権モードへ 33tn.write(b"enable\n") 34 35tn.read_until(b"#") 36 37#tn.write(b"show wireless ap status\n") 38tn.write(b"show virsion\n") 39print(tn.read_eager()) 40 41tn.read_until(b"#") 42tn.write(b"exit\n") 43 44print(tn.read_all().decode("ascii")) 45 46tn.close()

ご指摘を受けてソースを修正しました。
・tn.read_eager() が出力されるように修正した
・デバッグ用のメッセージ部分を削除した

ご指摘修正前の出力結果

shell

1~/python$ python3 -V 2Python 3.6.9 3 4~/python$ python3 telnet.py 5Login: 6Login Success 7プロンプト------------------ > 8コマンド実行---------------- terminal length 0 9特権モード------------------ enable 10プロンプト------------------ # 11コマンド実行---------------- show version 12コマンド実行 ----------------------- exit 13reslut----------------------------------------------- 14exit

ご指摘修正前のソース

python

1# -*- coding:utf-8 -*- 2import getpass 3import sys 4import telnetlib 5 6HOST = "xxx.xxx.xxx.xxx" 7#user = input("Enter your remote account: ") 8#password = getpass.getpass() 9user = b"adminuser" 10password = b"dummypassword" 11 12tn = telnetlib.Telnet(HOST) 13 14tn.read_until(b"login: ") 15print("Login:") 16 17tn.write(user + b"\n") 18if password: 19 tn.read_until(b"Password: ") 20 tn.write(password + b"\n") 21 print("Login Success") 22 23tn.read_until(b'>') # コマンドを実行する直前まで読み飛ばす 24print("プロンプト------------------ >") 25 26#ページ送り無効 27tn.write(b"terminal length 0\n") 28tn.read_eager() 29 30tn.read_until(b'>') 31print("コマンド実行---------------- terminal length 0") 32 33 34#特権モードへ 35tn.write(b"enable\n") 36print("特権モード------------------ enable") 37 38tn.read_until(b"#") 39print("プロンプト------------------ #") 40 41#tn.write(b"show wireless ap status\n") 42tn.write(b"show virsion\n") 43tn.read_eager() 44print("コマンド実行---------------- show version") 45 46tn.read_until(b'#') 47tn.write(b"exit\n") 48print("コマンド実行 ----------------------- exit") 49 50#result = tn.read_all().decode("ascii") 51print("reslut-----------------------------------------------") 52print(tn.read_all().decode('ascii')) 53 54tn.close()

試したこと

Windows からTeraTearm や 今回操作しているクライアントPCからTelnetクライアントで接続し、該当のコマンドを操作してみましたが、問題なく操作できました。
操作しているスイッチ固有の問題ではないかと考えていますが、検索して近い事象は見当たりませんでした。

補足情報(FW/ツールのバージョンなど)

Ubuntu 18.04.5 LTS
Python 3.6.9

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

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

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

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

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

guest

回答2

0

アドバイスをいただいた結果、pexpectに挑戦してみたところうまくいきました。

python

1import pexpect 2import sys 3 4child = pexpect.spawn("telnet xxx.xxx.xxx.xxx") 5child .logfile_read = sys.stdout.buffer 6 7print("-------------") 8#ログイン 9child .expect("login: ") 10child .send("adminuser\n") 11child .expect("Password: ") 12child .send("dummypassword\n") 13child .expect(">") 14 15#ページ送り無効 16child .send("terminal length 0\n") 17child .expect(">") 18 19#管理者モードへ 20child .send("enable\n") 21child .expect("#") 22 23child .send("show version\n") 24child .expect("#") 25 26child .send("disable\n") 27child .expect(">") 28 29#終了 30child .send("exit\n") 31child .expect(pexpect.EOF) 32print("-------------") 33print("終了")

以下実行結果です。

shell

1$ python3 telnet.py 2------------- 3Trying xxx.xxx.xxx.xxx... 4Connected to xxx.xxx.xxx.xxx. 5Escape character is '^]'. 6NAGOYA-x8106 login: adminuser 7Password: 8Last login: Wed Mar 17 19:54:05 JST 2021 from 10.10.50.181 9 10AlliedWare Plus (TM) 5.4.5 12/17/15 03:26:06 11 12 13中略 14 15 16SWITCH-NAME#disable 17SWITCH-NAME>exit 18Connection closed by foreign host. 19<class 'pexpect.exceptions.EOF'> 20Done! 21-------------

投稿2021/03/17 11:01

sumou_sumou

総合スコア1

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

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

0

ベストアンサー

tn.read_eager()de出力を読込んでますが、結果をどこでも出力していないからじゃないかと思います。

試してみてないですが、

python

1res = tn.read_eager().decode('ascii') 2print(res)

のような感じです。 read_eager でなく他の、read_xxx で試してみる必要があるかもしれません。

投稿2021/03/08 12:16

編集2021/03/08 12:18
TakaiY

総合スコア12765

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

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

sumou_sumou

2021/03/09 05:50

ご指摘ありがとうございます。うっかりしていました。 ただ、一番の問題はread_allした結果がコマンドの実行結果が表示されず、『exit』としか表示されていないことなのです。 ご指摘いただいた部分を修正し、余計なメッセージを全部消した結果は次の通りです。 途中経過も b''が出力されているところから、必要なコマンドを正しく送信できていないという事でしょうか。 ・tn.read_eager() が出力されるように修正した ・デバッグ用のメッセージ部分を削除した ↓↓↓出力結果↓↓↓ ~/python$ python3 telnet.py Login: Login Success b'' b'' exit
TakaiY

2021/03/09 06:19

read_eager() はその時点までに出力されているものを取得して表示するものです。その時点で何も出力されていなければ、待たずに空を返します。 なので、コマンド実行直後にはまだ結果が出ていないのかもしれません。 スリープを入れるとか、タイムアウト付きのread_xxx を使うなどしてみるとどうでしょうか。
sumou_sumou

2021/03/10 03:46

スリープを入れたところ、read_eager()で値が表示されました。 コマンド入力後のプロンプトが 『switch_name>』もしくは『switch_name#』になるため、read_until()を入れていたのですが、正しく拾えていないようでした。 read_until()が正しく動作しないのは困りものですが、とりあえず目的は果たせたので、解決済みといたします。 ありがとうございました。
TakaiY

2021/03/10 04:17

read_until() を使った場合のコードを提示いただければ、何かアドバイスできるかもしれません。
sumou_sumou

2021/03/12 09:51

ありがとうございます。実際に試してみたコードは次の通りです。 sleepを入れることで、ログインまでは正常動作しているようなのでsleepは入れたままになっています。 『terminal length 0』を送った後のread_untile()で停止しました。 Ubuntuのターミナルでスクリプトを実行しているのですが、ターミナルのカーソルが点滅から点灯に変わったので、異常動作しているのではないかと思います。 ↓↓↓該当のソース↓↓↓ import telnetlib import time import re import csv HOST = "XX.XX.XX.XX" user = b"adminuser" password = b"dummypassword" #スリープ def wait(waittime: int): time.sleep(waittime) #ホストに接続 tn = telnetlib.Telnet(HOST) tn.read_until(b"login: ") print("Login:") wait(5) tn.write(user + b"\n") if password: tn.read_until(b"Password: ") tn.write(password + b"\n") print("Login Success") wait(5) #ページ送り無効 tn.write(b"terminal length 0\n") tn.read_until(b">") #以下いずれの場合もダメでした #tn.read_until(b"SWITCH-name001>") #tn.read_until(b".+>") #tn.read_until(b"[A-Za-z0-9-]+>") #管理者モードへ tn.write(b"enable\n") tn.read_until(b"[A-Za-z0-9-]+>") tn.write(b"show wireless ap status\n") result = tn.read_until(b"[A-Za-z0-9-]+#").decode(encoding='utf-8') tn.write(b"exit\n") tn.close() print(result)
TakaiY

2021/03/12 10:40

止っているということですが、そこまでの動作が想定どおりなのを確認するのがいいのではないかと思います。 パスワードを投入してログインに成功しているでしょうか? そのタイミングでread_eager()をして取得できた文字列を確認してみるのはどうでしょう。 リモートとの対話的通信では、想定している応答がちゃんと来ているか確認しながら進めるのが大切だと思います。 また、いまさらですが、こういう対話形式の処理をするのであれば、pexpectというモジュールがもう少し高機能なので使いやすいと思います。 また、pythonにこだわらないのであれば、本家のexpect(https://core.tcl-lang.org/expect/index)がより使いやすいです。tclがベースなので慣れないと使いにくいかもしれませんが。
sumou_sumou

2021/03/17 11:09

返信が遅くなり申し訳ございません。 色々と試行錯誤しておりました。 read_eager()で出力する限りは、terminal length 0 を投げ終わるところまではうまくいっているように見受けられました。 質問には直接関係がないと思い記載しなかったのですが、最終的に社内使用するWEBアプリのバックエンドとして考えていました。 expectですとそのあたりのやり取りが面倒だったので、Pythonで作りたかったという理由があります。 pexpectで書き直してみたところ、うまく動作しました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問