.png)
Ich verwende Telnetlib – Python – um einen Telnet-Client – Port 23 – zu erstellen und mit einem AS/400-Server zu kommunizieren. Die Kommunikation mit dem Telnet-Befehl ist kein Problem, aber mit Telnetlib erhalte ich keine Meldung.
Hier ist mein Code:
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"
Danke.
Antwort1
IBM hat es sich zur Gewohnheit gemacht, Namen zu ändern. Es ist wahrscheinlich, dass die Maschine, von der Sie sprechen, nicht wirklich eine AS/400 ist, auf der OS/400 lief. IBM hat seit 2000 keine mehr ausgeliefert. Die Produktlinie wurde durch die iSeries-Systeme ersetzt (oder umbenannt, je nach Sichtweise), die später zu System i und dann zu i5 wurden, aber das Betriebssystem war immer noch OS/400. Die Hardware-Produktlinie wurde mit den pSeries-Systemen zusammengeführt und wurde zu Power Systems. Das Betriebssystem wurde zu i5/OS und ist jetzt, unter der neuesten Version 7.1, offiziell „IBM i“. Die nächste Hardware-Generation, Pure Systems, kann auch IBM i OS ausführen. Es ist also wahrscheinlich, dass Ihr Server tatsächlich ein System i oder ein Power System ist, aber das IT-Personal nennt sie oft weiterhin AS/400 und denkt sogar, sie seien AS/400. Als Gruppe wird dieser Stammbaum der Produktlinien oft als IBMs Midrange-Systeme bezeichnet.
IBM-Mittelklassesysteme verwendeten ursprünglich Terminals des Modells IBM 5250. Nachfolgende Modelle verwendeten noch das sogenannte 5250-Protokoll, das in gewisser Weise dem 3270-Protokoll ähnelt, das bei IBM-Großrechnern verwendet wird. Es handelt sich um ein blockorientiertes Protokoll, das im Allgemeinen jeweils einen ganzen Bildschirm überträgt und umgangssprachlich oft „Green Screen“ genannt wird, basierend auf der Originalfarbe der Zeichen. Ihr Server ist möglicherweise für die Verwendung von VTxxx-Telnet konfiguriert, aber das ist wahrscheinlich eher unwahrscheinlich. Aber die Unterstützung von TN5250 ist fast sicher. Versuchen Sie stattdessen, eine Verbindung damit herzustellen.
Antwort2
Sie können die AS/400-Verbindung nicht wie eine *nix-Telnet-Verbindung behandeln. Versuchen Sie, statt read_until() read_very_eager() zu verwenden, um den gesamten Bildschirm anzuzeigen (einschließlich ANSI-Escape-Sequenzen, die den Cursor an den Anfang des Felds „Benutzer ...“ positionieren), und schreiben Sie dann mit write() genau das, was Sie eingeben würden, wenn Sie sich manuell anmelden würden. Ich habe auch festgestellt, dass Sie zuerst ein Zeilenumbruchzeichen schreiben müssen, damit der Anmeldebildschirm nach der Verbindung angezeigt wird. Ich habe keine Ahnung, warum das so ist, aber bei mir hat es funktioniert.
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"
Eine letzte Sache: Bedenken Sie, dass AS/400 am Ende des Bildschirms kein EOF-Zeichen sendet, sodass read_all() einfach hängen bleibt und nie zurückkehrt. Sie könnten versuchen, read_until() zu verwenden, aber da die vom Server zurückgegebenen Daten möglicherweise zerstückelt und voller ANSI-Escape-Sequenzen sind, gibt es keine Garantie, dass Sie finden, was Sie suchen. Die offensichtliche Lösung scheint darin zu bestehen, read_very_eager() in eine while-Schleife zu setzen, die beendet wird, wenn read_very_eager() eine leere Zeichenfolge zurückgibt. Dies hat jedoch seine eigenen Probleme, da der Server verschiedene Statusmeldungen oder andere Teilbildschirme zurückgeben kann, bevor er zum nächsten Vollbildschirm übergeht. Die einzige vollständige Lösung besteht wahrscheinlich darin, die vom Server zurückgegebenen Daten kontinuierlich zu analysieren und zu verfolgen, wie der aktuelle Bildschirm aussieht (d. h. Terminalemulation und Screen Scraping) oder einfach einige time.sleep()-Befehle zwischen Schreiben und Lesen einzufügen.
Antwort3
Nachfolgend finden Sie die Fragen, die ich in einem Kommentar zu Ihrer Frage stellen wollte. Dann bemerkte ich, dass Siekreuzgepostetdie Frage an Stack Overflow. Bitte keine Crossposts.
Dort habe ich festgestellt, dass Sie eineBehälter einfügenin einem Kommentar. Das veranlasste mich, meinen Kommentar in eine Antwort umzuwandeln.
In Ihrem Paste Bin zeigen die Eingabeaufforderungen des AS/400 Leerzeichen zwischen den Punkten an. Im Code in Ihrer Frage gibt es keine Leerzeichen zwischen den Punkten. Es ist wahrscheinlich, dass Ihr Code funktioniert, wenn Sie dort Leerzeichen einfügen.
Für die Nachwelt (wenn Sie diese Art von Informationen im Voraus angeben, ist es wahrscheinlicher, dass Sie schneller eine gute Antwort erhalten):
Sind Sie sicher, dass Sie die richtigen Zeilenenden an AS/400 senden?
Welches Betriebssystem läuft auf dem AS/400?
Enthalten die AS/400-Telnet-Anmeldeaufforderungen wirklich all diese Punkte, gefolgt von einem Leerzeichen?
Erwarten Sie ein Willkommensbanner oder ähnliches?
Was passiert, wenn Sie vor dem einen Befehl senden read_all
?
Was sagen die Protokolle auf dem AS/400?
Antwort4
Probieren Sie das Python Expect ( pexpect
) Modul aus. Folgen Sie denpassmass.pySkript als Beispiel. Es sollte auch im pexpect-Modul enthalten sein.
Hier ist einungetestetÜberarbeitung Ihres Skripts:
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"