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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Cisco IOS

Cisco IOSは、シスコシステムズ社が提供しているOSです。同社のほとんどのルーターやスイッチに使用されており、特徴のあるコマンドラインインターフェースをもちます。実行操作に制限があるユーザーモードと特権モードのセキュリティレベルがあります。

Python

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

Cisco

シスコ(Cisco Systems,Inc.)は、アメリカ合衆国に本社を置く、世界最大のコンピュータネットワーク機器開発会社及び同社の製品

Q&A

解決済

2回答

2382閲覧

Pythonのtelnetlibで情報取得し、ファイルに書き出すと改行が余分にできてしまう

退会済みユーザー

退会済みユーザー

総合スコア0

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Cisco IOS

Cisco IOSは、シスコシステムズ社が提供しているOSです。同社のほとんどのルーターやスイッチに使用されており、特徴のあるコマンドラインインターフェースをもちます。実行操作に制限があるユーザーモードと特権モードのセキュリティレベルがあります。

Python

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

Cisco

シスコ(Cisco Systems,Inc.)は、アメリカ合衆国に本社を置く、世界最大のコンピュータネットワーク機器開発会社及び同社の製品

0グッド

0クリップ

投稿2020/10/17 16:24

編集2020/10/17 16:28

前提・実現したいこと

pythonのtelnetlibを使用してCiscoのCSR1000vからshow runを取得しようとしているのですが、windows10で実行すると下記出力結果のように改行が一つ余分にできてしまいます。余分な改行をなくすにはどうすればよいでしょうか。

改行が余分に含まれる出力ファイルの一部

以下、出力されたファイルの一部。

show running-config

Building configuration...

Current configuration : 1108 bytes

!

! Last configuration change at 23:03:32 UTC Sat Oct 17 2020

!

version 15.4

service timestamps debug datetime msec

service timestamps log datetime msec

no platform punt-keepalive disable-kernel-core

platform console virtual

!

使用したソースコード

python

1# coding:utf-8 2 3import telnetlib 4 5def main(): 6 result = telnet("x.x.x.x") 7 writeFile("x.x.x.x", result) 8 9def writeFile(client, text): 10 with open("test" + '.txt', mode='w') as wf: 11 wf.writelines(text) 12 wf.close() 13 14def telnet(clientIp): 15 tn = telnetlib.Telnet(clientIp) 16 17 tn.read_until(b'Username:') 18 tn.write(b'cisco' + b'\n') 19 20 tn.read_until(b'Password:') 21 tn.write(b'cisco' + b'\n') 22 tn.read_until(b'>') 23 24 tn.write(b'enable' + b'\n') 25 26 tn.read_until(b'Password:') 27 tn.write(b'cisco' + b'\n') 28 29 tn.read_until(b'#') 30 tn.write(b'terminal length 0' + b'\n') 31 tn.write(b'show running-config' + b'\n') 32 33 tn.read_until(b'#') 34 35 result = tn.read_until(b"FIN\n", timeout = 1).decode('ascii', errors="replace") 36 return result 37 38 tn.close() 39 40if __name__ == '__main__': 41 main()

試したこと

WindowsのWSL(Ubuntu)で上記コードを実行し、出力されたファイルの改行はwindows側でみても、WSL上でcatでみても正常な改行のファイルが出力されます。

利用環境

windows 10
python 3.6.3
csr1000v IOS XE 03.11.04.S

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

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

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

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

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

toast-uz

2020/10/17 23:38

生のWindows10で問題が出て、WSL上では問題が出ていない、という理解でよいでしょうか?
toast-uz

2020/10/18 00:01 編集

「改行が余分に含まれる出力ファイル」は、どうやって出力結果を見たのでしょうか?メモ帳?
otn

2020/10/18 00:22

> windows10で実行すると下記出力結果のように改行が一つ余分にできてしまいます。 と、 > WindowsのWSL(Ubuntu)で上記コードを実行し、出力されたファイルの改行はwindows側でみても、WSL上でcatでみても正常な改行のファイルが出力されます。 の関係が分かりません。 どういう確認の仕方をしたらどうだったのかを具体的に書いてください。
退会済みユーザー

退会済みユーザー

2020/10/18 02:19 編集

コメントいただきありがとうございます。 toast-uzさん >生のWindows10で問題が出て、WSL上では問題が出ていない、という理解でよいでしょうか?  →そうです。 >「改行が余分に含まれる出力ファイル」は、どうやって出力結果を見たのでしょうか?メモ帳?  →windows標準のメモ帳、sublimetextで確認しました。   WSL上でpythonコードを実行して得たファイルはWSL(Ubuntu)上のcatコマンドでも、windows上のメモ帳、sublimetextでも余分な改行がなく正常に表示されています。 otnさん >どういう確認の仕方をしたらどうだったのかを具体的に書いてください。  →windows10での実行はエクスプローラでpythonコードをダブルクリックして実行しています。出力ファイルの確認はWindows付属のメモ帳、Sublimetextで余分な改行が含まれることを確認しました。   WSL(Ubuntu)上での実行はコマンドプロンプト上でbashコマンドでWSLに入り、「python ファイル名」で実行しています。出力ファイルの確認はWSL上でのcatコマンド、windows付属のメモ帳、sublimetextで余分な改行が含まれないことを確認しました。   補足ですが、WSL上で作成したファイルはWindows側で確認することができ、Windows側で作成したファイルもWSL上で確認できます。
dodox86

2020/10/18 02:19

> result = tn.read_until(b"FIN\n", timeout = 1).decode('ascii', errors="replace") のresultの時点で、バイナリレベルでresultの値がどうなっているか確認してみたらどうでしょうか。telnetサーバー間との通信の生データあるいはライブラリの扱いで、改行コード(CRやLF)がどのようになってしまっているか確認した方が良いと思います。現状ではどこで改行が余分に付与されてしまっているか不確かです。
guest

回答2

0

質問者様とのやりとりで、本質的なところがもっとわかりました。既にベストをいただいたので、別解とします。

def telnet(clientIp):
return resultの前に
result = result.replace('\r\n', '\n')

と入れて、ファイル書き込みのところは元のままにするとよいでしょう。

理由

  • telnetの電文は仕様により、改行はCR+LFで表されます。

参考: telnetがテキストデータを送る際の改行コードは、windowsだろうが、Mac、Linuxだろうが、
常にNVT ASCIIの改行コード(CR+LF:0x0D0A)です

  • telnetlibは、そのCRLFをそのまま結果として返す仕様のようです。よって、resultの中の改行はCR+LFとなっています。
  • ところが、本来、プログラム中の改行コードはLF('\n')のみです。よってCRは改行ではなく単独の文字としてみなされます。
  • Linux仕様のテキストファイルは改行コードはLFなので、CRはそのまま、LFもそのまま出力します。結果としてCR+LFが改行位置に入ります。
  • しかしWindows仕様のテキストファイルは改行コードはCR+LFなので、CRはそのまま、LFはCR+LFとして出力します。結果としてCR+CR+LFが改行位置に入ります。
  • 最近のエディタは優秀なので、Linux・Windowsのテキストファイルを自動判別して自然に見せるようになっていて、CRであろうがLFであろうがCR+LFであろうが1回の改行として判別します。ところが、CR+CR+LFは想定外で、CR+(CR+LF)の2つの改行として判別してしまいます。これが質問者様に発生した状況です。
  • 上記の対策としてLinuxの改行仕様でテキストファイルを書き込みするようにしていただきました。しかし、本質的にはプログラム中でCR+LFを改行コードに持つ文字列を処理するところから修正が必要です。そのため、telnet終了後に得られた文字列の改行コードを一括変換する、という今回の対策をオススメします。これにより、プログラム中では、正しい文字列として処理でき、なおかつテキストファイル出力は、環境にあわせてできるようになります。

投稿2020/10/18 03:57

編集2020/10/18 03:58
toast-uz

総合スコア3266

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

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

退会済みユーザー

退会済みユーザー

2020/10/18 12:57

詳細に説明いただきありがとうございます。 return resultの前に下記コードを入れた場合にも、問題なく改行が表示され、hexdumpで見てもWindowsでは改行が\r\nとなり、WSLで実行すると\nになることが確認できました。 result = result.replace('\r\n', '\n') もともとtelnetlibで取得した文字列の改行コードが\r\nであることが問題であるみたいなので、Telnet取得後に文字列の改行コードを変換するようにします。 ありがとうございました。理解が深まりました。
guest

0

ベストアンサー

質問者様に確認中の部分はありますが、概ねこれが回答だろうという目星はつけましたので、回答します。

with open("test" + '.txt', mode='w') as wf:

with open("test" + '.txt', mode='w', newline='\n') as wf:
に書き換えてみてください。

Windowsは(文字コードに加え)改行コードの扱いが異なるため、テキストファイルの読み書きには非互換が発生します。上記コードの変更により、改行コードの扱いをLinux系とあわせることが可能です。
参考: Windows上で実行したPythonの出力ファイルの改行コードが変わる

ただし、この改行コードの扱いはWindowsネイティブのものですので、メモ帳等のツールで出力ファイルを参照した場合に、改行が二重に見えてしまう、というのは不思議です。質問者様に確認の方法をお聞きしているのは、そのためです。
(Windows仕様で出力したテキストファイルを、macのメモ帳的アプリで見ると、改行が二重に見えます。一方、macのターミナルでcatで見ると、二重には見えません。各ツールがWindows仕様の改行に対応しているかどうかで、見え方が異なります。)

投稿2020/10/18 00:37

toast-uz

総合スコア3266

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

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

退会済みユーザー

退会済みユーザー

2020/10/18 02:35

ありがとうございます!解決しました! コメントで頂いた通りにコードを書き換えたところ改行が正常に表示できることが確認できました。 dodox86さんにアドバイス頂いた通りにバイナリで確認したところ、修正したコードの出力結果と修正前の出力結果で改行コードの部分に違いがありました。  修正前:0d 0d 0a  修正後:0d 0a 参考にWSL上でhexdumpを取得した一部を載せます。 修正後の出力結果のhexdump -------------------------------------------------- $ hexdump -C test.txt 00000000 0d 0a 0d 0a 55 73 65 72 20 41 63 63 65 73 73 20 |....User Access | 00000010 56 65 72 69 66 69 63 61 74 69 6f 6e 0d 0a 0d 0a |Verification....| 00000020 55 73 65 72 6e 61 6d 65 3a 20 63 69 73 63 6f 0d |Username: cisco.| 00000030 0a 50 61 73 73 77 6f 72 64 3a 20 0d 0a 63 73 72 |.Password: ..csr| 修正前の出力結果のhexdump -------------------------------------------------- $ hexdump -C test.txt 00000000 0d 0d 0a 0d 0d 0a 55 73 65 72 20 41 63 63 65 73 |......User Acces| 00000010 73 20 56 65 72 69 66 69 63 61 74 69 6f 6e 0d 0d |s Verification..| 00000020 0a 0d 0d 0a 55 73 65 72 6e 61 6d 65 3a 20 63 69 |....Username: ci| 00000030 73 63 6f 0d 0d 0a 50 61 73 73 77 6f 72 64 3a 20 |sco...Password: | 00000040 0d 0d 0a 63 73 72 31 3e 65 6e 61 62 6c 65 0d 0d |...csr1>enable..| 00000050 0a 50 61 73 73 77 6f 72 64 3a 20 0d 0d 0a 63 73 |.Password: ...cs| 00000060 72 31 23 74 65 72 6d 69 6e 61 6c 20 6c 65 6e 67 |r1#terminal leng|
toast-uz

2020/10/18 03:39

よくわかりました。もう少し原理的に対策がわかりましたが、ベストをいただきましたので、別解として回答追加します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問