.png)
私は、telnetlib (Python) を使用して、AS/400 サーバーと通信するための telnet クライアント (ポート 23) を作成します。telnet コマンドを使用した通信は問題ありませんが、telnetlib を使用するとメッセージが表示されません。
これが私のコードです:
import getpass
import sys
import telnetlib
HOST = raw_input("HOST : ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
try:
tn = telnetlib.Telnet(HOST)
tn.read_until("User..... ")
tn.write(user + "\r")
tn.read_until("Password..... ")
tn.write(password + "\r")
print tn.read_all()
except:
print "Error"
ありがとう。
答え1
IBM は名前を変更する習慣があります。おそらく、あなたが話しているマシンは、OS/400 を実行する AS/400 ではないでしょう。IBM は 2000 年以降、AS/400 を出荷していません。製品ラインは iSeries システムに置き換えられ (または、見方によっては名前が変更されました)、その後 System i、i5 になりましたが、OS は OS/400 のままでした。ハードウェア製品ラインは pSeries システムと統合され、Power Systems になりました。OS は i5/OS になり、最新のリリース 7.1 では正式に「IBM i」となっています。次のハードウェア世代である Pure Systems でも、IBM i OS を実行できます。したがって、サーバーは実際には System i または Power System である可能性がありますが、IT スタッフはそれらを AS/400 と呼び続け、AS/400 であると考えている場合さえあります。グループとして、この製品ラインの系統は、IBM のミッドレンジ システムと呼ばれることがよくあります。
IBM ミッドレンジ システムは、当初 IBM モデル 5250 端末を採用していました。その後のモデルでも、5250 プロトコルと呼ばれるプロトコルが使用されていました。これは、IBM メインフレームで使用されている 3270 プロトコルといくつかの点で似ています。これはブロック指向のプロトコルで、通常は一度に画面全体を送信し、文字の元の色に基づいて口語的に「グリーン スクリーン」と呼ばれることがよくあります。サーバーが VTxxx telnet を使用するように構成されている可能性はありますが、おそらく可能性は低いでしょう。ただし、TN5250 はほぼ確実にサポートされています。代わりに、それを使用して接続してみてください。
答え2
AS/400 接続を *nix telnet 接続のように扱うことはできません。read_until() を使用する代わりに、read_very_eager() を使用して画面全体 (カーソルを "User...." フィールドの先頭に配置する ANSI エスケープ シーケンスを含む) を取得し、次に手動でログインする場合に入力する内容を正確に write() してください。また、接続後にログイン画面を表示するには、最初に改行文字を入力する必要があることもわかりました。なぜそうなるのかはわかりませんが、私の場合はこれでうまくいきました。
import getpass
import sys
import telnetlib
HOST = raw_input("HOST : ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
try:
tn = telnetlib.Telnet(HOST)
tn.write('\n')
tn.read_very_eager()
tn.write(user)
tn.write('\t') # tab into the next field
tn.write(password)
tn.write('\r') # 'enter' key
except:
print "Error"
最後にもう 1 つ: AS/400 は画面の最後に EOF 文字を送信しないので、read_all() はハングして戻らなくなることに注意してください。read_until() を使用することもできますが、サーバーから返されるデータは分割され、ANSI エスケープ シーケンスが満載である可能性があるため、必要なデータが見つかる保証はありません。明らかな解決策は、read_very_eager() を while ループに配置し、read_very_eager() が空の文字列を返したときに終了するようにすることです。ただし、これには独自の問題があり、サーバーは、次のフル スクリーンに移動する前に、さまざまなステータス メッセージやその他の部分的なスクリーンを返す可能性があります。唯一の完全な解決策は、サーバーから返されるデータを継続的に解析し、現在のスクリーンがどのようになっているかを追跡するか (つまり、ターミナル エミュレーションとスクリーン スクレイピング)、書き込みと読み取りの間に time.sleep() コマンドを追加することです。
答え3
以下は、あなたの質問にコメントで私が尋ねようとしていた質問です。そして、あなたがクロスポスト質問は Stack Overflow へ。クロスポストしないでください。
そこであなたが投稿したペーストビンコメントで。それが私のコメントを回答に変更するきっかけとなりました。
貼り付けボックスでは、AS/400 のプロンプトにピリオドの間にスペースが表示されます。質問のコードでは、ドットの間にスペースがありません。そこにスペースを入れると、コードが機能する可能性があります。
後世のために(この種の情報を事前に提供することで、適切な回答をより早く得られる可能性が高くなります):
AS/400 に正しい行末を送信していますか?
AS/400 はどの OS を実行していますか?
AS/400 の Telnet ログイン プロンプトには、本当にすべてのドットとその後にスペースが続くのでしょうか?
ウェルカムバナーなどが表示されることを期待していますか?
の前にコマンドを送信するとどうなりますかread_all
?
AS/400 のログには何が記録されていますか?
答え4
Python Expect(pexpect
)モジュールを試してください。パスマス.pyスクリプトを例として示します。これは pexpect モジュールにも含まれている必要があります。
これは未テストスクリプトの修正:
import getpass
import pexpect
import sys
HOST = raw_input("HOST : ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
try:
tn = pexpect.spawn('telnet %s'%(HOST))
tn.logfile = file ("LOG.TXT","wb")
i = tn.expect([pexpect.TIMEOUT, '[Uu]ser..... '])
if i == 0: # Timeout
print 'ERROR!'
print 'telnet could not login. Here is what telnet said:'
print tn.before, tn.after
sys.exit (1)
tn.sendline(user)
tn.expect (['[Pp]assword..... '])
tn.sendline(password)
except:
print "Error"