.png)
Я использую telnetlib - Python - для создания клиента telnet - порт 23 - для связи с сервером AS/400. Связь с командой 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 привыкла менять названия. Скорее всего, машина, о которой вы говорите, на самом деле не AS/400, на которой работала OS/400. IBM не поставляла их с 2000 года. Линейка продуктов была заменена (или переименована, в зависимости от вашей точки зрения) на системы iSeries, которые позже стали System i, затем i5, но ОС по-прежнему была OS/400. Линейка аппаратных продуктов была объединена с системами pSeries и стала Power Systems. ОС стала i5/OS, и теперь в последней версии 7.1 она официально называется «IBM i». Следующее поколение оборудования, Pure Systems, также может работать под управлением IBM i OS. Так что скорее всего, ваш сервер на самом деле System i или Power System, но ИТ-персонал часто продолжает называть их AS/400, даже думая о них как о AS/400. Как группа, это генеалогическое древо линеек продуктов часто называют системами среднего уровня IBM.
Системы среднего уровня IBM изначально использовали терминалы IBM модели 5250. Последующие модели по-прежнему использовали так называемый протокол 5250, который в некотором роде похож на протокол 3270, используемый в мэйнфреймах IBM. Это блочно-ориентированный протокол, обычно передающий весь экран за раз, и часто в разговорной речи называемый «зеленым экраном» на основе исходного цвета символов. Хотя ваш сервер, возможно, настроен на использование VTxxx telnet, это, вероятно, маловероятно. Но поддержка TN5250 почти наверняка. Попробуйте подключиться с помощью этого.
решение2
Вы не можете обрабатывать соединение AS/400 так же, как соединение *nix telnet. Вместо того, чтобы использовать read_until(), попробуйте использовать read_very_eager(), чтобы получить весь экран (включая escape-последовательности ANSI, которые помещают курсор в начало поля "User...."), а затем 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"
И последнее: помните, что AS/400 не отправит символ EOF в конце экрана, поэтому read_all() просто зависнет и никогда не вернется. Вы можете попробовать использовать read_until(), но поскольку данные, возвращаемые сервером, могут быть разбиты и полны escape-последовательностей ANSI, нет никакой гарантии, что вы найдете то, что вам нужно. Очевидное решение, похоже, поместить read_very_eager() в цикл while, завершающийся, когда read_very_eager() возвращает пустую строку. Однако это имеет свои собственные проблемы, поскольку сервер может возвращать различные сообщения о состоянии или другие частичные экраны, прежде чем перейти к следующему полному экрану. Единственное полное решение, скорее всего, будет непрерывно анализировать данные, возвращаемые сервером, и отслеживать, как выглядит текущий экран (т. е. эмуляция терминала и очистка экрана) или просто добавлять несколько команд time.sleep() между записью и чтением.
решение3
Ниже приведены вопросы, которые я собирался задать в комментарии, прикрепленном к вашему вопросу. Затем я заметил, что выперекрестно размещенныйвопрос к Stack Overflow. Пожалуйста, не делайте кросс-пост.
Там я обнаружил, что вы разместиликонтейнер для пастыв комментарии. Это заставило меня изменить свой комментарий на ответ.
В вашем контейнере для вставки подсказки AS/400 показывают пробелы между точками. В коде в вашем вопросе нет пробелов между точками. Вероятно, что добавление пробелов заставит ваш код работать.
Для будущих поколений (предоставление такой информации заранее увеличит вероятность получения хорошего ответа и сделает это быстрее):
Вы уверены, что отправляете правильные окончания строк на AS/400?
Какая ОС установлена на AS/400?
Действительно ли в приглашениях на вход в систему AS/400 Telnet присутствуют все эти точки, за которыми следует пробел?
Ожидаете ли вы увидеть приветственный баннер или что-то подобное?
Что произойдет, если вы отправите команду до read_all
?
Что говорят журналы AS/400?
решение4
Попробуйте модуль Python Expect ( pexpect
). Следуйте инструкциямpassmass.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"