#ruby
#ruby
Вопрос:
Я испытываю некоторое забавное поведение с telnet. Ниже приведен мой код:
#!/usr/bin/env ruby
require 'net/telnet'
ipaddress = "182.201.120.218"
j = Net::Telnet::new("Host" => '127.0.0.1',
"Port" => 2605,
"Output_log" => "output.log",
"Dump_log" => "dump.log",
"Prompt" => /[#>]/ ,
"Telnetmode" => true,
"Timeout" => 10,
)
response = j.cmd("show ip bgp 182.201.120.218n")
puts response
Это результат, который я получаю, пытаясь запустить его несколько раз (не волнуйтесь, там нет конфиденциальной информации, все очищено):
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au> show ip bgp 182.255.120.248
BGP routing table entry for 182.235.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
[root@dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
Как вы можете видеть выше, telnet отказывается выполнять команду show ip bgp 182.201.120.218n
, даже если сеанс telnet был установлен / подключен. Наконец, это удалось в 6-м запуске, но 7-й сбой и т. Д. Если я запускаю его еще один случайный раз, он снова работает, только для сбоя. Ручная telnet всегда успешна, иначе :
[root@dummyserver]# telnet 127.0.0.1 2605
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
dummyserver.com.au>show ip bgp 182.255.120.248
BGP routing table entry for 182.255.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
dummyserver.com.au>
Выходной журнал показывает следующее:
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> show ip bgp 182.255.120.248
BGP routing table entry for 182.255.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
dummyserver.com.au>
dummyserver.com.au>
dummyserver.com.au>
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au>
Я ломаю голову, пытаясь понять, почему telnet ведет себя таким образом, когда у обычного telnet нет проблем.
Версия Rvm : # rvm version rvm 1.29.10 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
Работает на Redhat 7.8
Если у кого-нибудь есть какие-либо идеи или вы хотели бы предоставить более подробную информацию, дайте мне знать. Я в тупике:( (Если вам интересно — я пытаюсь запросить информацию о маршруте BGP из Quagga / zebra, используя telnet для запуска команд без требуемых учетных данных. Я мог бы сделать это легко и без проблем с Perl, но мы должны перенести скрипты на Ruby по внутренним причинам).
Ответ №1:
С помощью вашей :Prompt
спецификации вы сообщаете клиенту telnet, что приглашение telnet сервера — это любая строка, содержащая символ #
или >
.
Клиент telnet считывает все полученные выходные данные сервера до тех пор, пока не увидит строку, похожую на приглашение. Теперь в вашем случае ваша первая строка вывода show ip bgp
команды уже содержит #
символ, соответствующий вашей спецификации запроса.
При этом вы теперь сталкиваетесь с состоянием гонки. Вы увидите некоторый вывод, если сервер отправит больше первой строки в первом TCP-пакете своего ответа, что приведет к тому, что клиент telnet прочитает весь этот отправленный вывод. Если сервер отправляет каждую строку отдельно в одном пакете, клиент telnet завершает работу быстрее, поскольку он уже видит указанное приглашение.
Чтобы исправить это, возможно, уже достаточно указать более строгий :Prompt
, например /[$%#>] z/n
, как показано в примере на https://github.com/ruby/net-telnet#usage
Комментарии:
1. Спасибо за это, Хольгер! Это имеет смысл. Я изменил свое приглашение, чтобы оно
/[$%#>] z/n
соответствовало рекомендациям. Но, к сожалению, telnet по-прежнему ведет себя так же. Есть еще идеи? Я экспериментируюwaitfor
прямо сейчас, но пока безуспешно.
Ответ №2:
Хорошо, не уверен, что это лучший способ, но, похоже, я решил его путем добавления waitfor
. Полный код :
#!/usr/bin/env ruby
require 'net/telnet'
ipaddress = "182.255.120.248"
j = Net::Telnet::new("Host" => '127.0.0.1',
"Port" => 2605,
"Output_log" => "output.log", # default: nil (no output)
"Dump_log" => "dump.log", # default: nil (no output)
"Prompt" => /[$%#>] z/n ,
"Telnetmode" => true, # default: true
"Timeout" => 10, # default: 10
)
j.waitfor(/[># ]$/) {
response = j.cmd("show ip bgp 182.255.120.248")
puts response
}