Pythonでtelnet接続してみる

クライアント端末からサーバーと接続するとき、sshを使うことが多いと思います。
しかし、私の職場では、まだまだtelnetで接続するサーバーが多数を占めています。
TeraTerm のマクロでtelnet接続、コマンド実行して必要な情報を取得、表示していますが、
Pythonで接続できれば応用がきくので、実験してみました。

telnet接続プログラムの例は 20.14. telnetlib — Telnet クライアント — Python 2.7ja1 documentation にあります。

実験の準備

クライアントPCは Windows 7。サーバは Ubuntu Server 12.04 を使いました。telent を使うためには、telnetd をインストールします。

$ sudo apt-get install telnetd

インストールできたら、putty や poderosa などの接続プログラムを使い、 telnet 接続の動作確認しておきます。

プログラムと実行結果

import telnetlib

HOST = "192.168.11.201"  # your server
user = "bty"             # your username
password = "*****"       # your password

tn = telnetlib.Telnet(HOST)

tn.read_until("login: ")
tn.write(user + "\n")
if password:
    tn.read_until("Password: ")
    tn.write(password + "\n")

tn.write("ls\n")
tn.write("exit\n")

print tn.read_all()

実行結果は以下のとおり。

ls -al
exit
Last login: Fri May  3 20:46:09 JST 2013 from 192.168.11.19 on pts/1
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/

  System information as of Fri May  3 20:46:23 JST 2013

  System load:  0.25              Processes:           66
  Usage of /:   18.7% of 5.98GB   Users logged in:     1
  Memory usage: 2%                IP address for eth0: 192.168.11.201
  Swap usage:   0%

  Graph this data and manage this system at https://landscape.canonical.com/

bty@ub01:~$ ls -al
蜷郁ィ・44
drwxr-xr-x 5 bty  bty  4096  1譛・16 22:00 .
drwxr-xr-x 3 root root 4096  1譛・16 16:24 ..
-rw------- 1 bty  bty  1454  5譛・ 3 20:46 .bash_history
-rw-r--r-- 1 bty  bty   220  1譛・16 16:24 .bash_logout
-rw-r--r-- 1 bty  bty  3574  1譛・16 16:35 .bashrc
drwx------ 2 bty  bty  4096  1譛・16 16:26 .cache
drwx------ 3 bty  bty  4096  5譛・ 3 19:07 .emacs.d
-rw------- 1 bty  bty    35  1譛・16 16:28 .lesshst
-rw-r--r-- 1 bty  bty   675  1譛・16 16:24 .profile
-rw------- 1 bty  bty  3897  1譛・16 22:00 .viminfo
drwxrwxr-x 3 bty  bty  4096  1譛・16 17:48 my
bty@ub01:~$ exit
繝ュ繧ー繧「繧ヲ繝・

結果をみると、文字が化けており、文字に色を付けるためのエスケープシーケンスがそのまま表示されています。

修正プログラムと実行結果

文字化け対策

サーバーの文字コードは utf-8 なので、windows で表示できるように cp932(Shift_jis)に変換します。

エスケープシーケンス対策

正規表現を使ってエスケープシーケンス文字列を除去します。

文字に色を付けるには、たとえば  のように、

ESCキャラクタ、[、任意の文字列、[、0m

の順番に続いた文字列です。

Pythonの正規表現では r’\x1b\[.*?m\[?’と表現できます。

\x1b
キャラクターのエスケープにマッチ
\[
キャラクタ-の ‘[‘にマッチ
.<
任意のキャラクターにマッチ
?
先行する正規表現の、0または一回の繰り返しにマッチ。 ab?は、’a’ または
‘ab’にマッチ

.*? の表現はちょっとわかりにくい。たとえば、文字列 <H1>title</H1> に対して、
<.*> と <.*?> がマッチする文字列は以下のようになる。

正規表現   マッチする文字列  
<.*> <H1>title</H1> 最長一致
<.*?> <H1> 最短一致

修正したプログラム

# -*- coding: utf-8 -*-

import re
import telnetlib

HOST = "192.168.11.201"  # your server
user = "bty"             # your user name
password = "*****"       # your password

tn = telnetlib.Telnet(HOST)

tn.read_until("login: ")
tn.write(user + "\n")
if password:
    tn.read_until("Password: ")
    tn.write(password + "\n")

tn.write("ls -al\n")
tn.write("exit\n")

result = tn.read_all()

#エスケープシーケンスの除去
r = re.compile(r'\x1b\[.*?m\[?')
result1 = re.sub(r,'',result)

#文字コードutf-8をcp932に変換
result2 = result1.decode('utf-8').encode('cp932')

print result2

結果は以下のとおり。

ls -al
exit
Last login: Fri May  3 22:10:48 JST 2013 from 192.168.11.19 on pts/1
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/

  System information as of Fri May  3 22:16:12 JST 2013

  System load:  0.08              Processes:           66
  Usage of /:   18.7% of 5.98GB   Users logged in:     1
  Memory usage: 2%                IP address for eth0: 192.168.11.201
  Swap usage:   0%

  Graph this data and manage this system at https://landscape.canonical.com/

bty@ub01:~$ ls -al
合計 44
drwxr-xr-x 5 bty  bty  4096  1月 16 22:00 .
drwxr-xr-x 3 root root 4096  1月 16 16:24 ..
-rw------- 1 bty  bty  1478  5月  3 22:10 .bash_history
-rw-r--r-- 1 bty  bty   220  1月 16 16:24 .bash_logout
-rw-r--r-- 1 bty  bty  3574  1月 16 16:35 .bashrc
drwx------ 2 bty  bty  4096  1月 16 16:26 .cache
drwx------ 3 bty  bty  4096  5月  3 19:07 .emacs.d
-rw------- 1 bty  bty    35  1月 16 16:28 .lesshst
-rw-r--r-- 1 bty  bty   675  1月 16 16:24 .profile
-rw------- 1 bty  bty  3897  1月 16 22:00 .viminfo
drwxrwxr-x 3 bty  bty  4096  1月 16 17:48 my
bty@ub01:~$ exit
ログアウト

参考

20.14. telnetlib — Telnet クライアント — Python 2.7ja1 documentation

正規表現 HOWTO — Python 2.7ja1 documentation