Как получить вывод Telnet в переменную?

У меня есть сценарий Bash, который отправляет значение с помощью telnet и получает некоторые данные обратно. Как я могу поместить полученные данные в переменную?

Вручную, когда я запускаю команды, я получаю следующие результаты.

$telnet 192.168.11 12345
>> 5 :234568
>>Adjust:False,offset 0

Первая строка — это мои вводимые данные, а вторая строка — полученный ответ. Я хочу присвоить этот ответ переменной. В сценарии bash я пытался использовать:

    response=$(echo -e "$message" | telnet "$TELNET_SERVER" "$TELNET_PORT" 2>&1)
    echo "Response from server: $response"

хотя ему удалось успешно отправить данные («сообщение»). Мне не удалось получить ответ, присвоенный переменной. При попытке запустить команду в терминале вывод пуст.

Может ли кто-нибудь дать мне какое-то решение? Спасибо.

Telnet сложно автоматизировать. Посмотрите, сможете ли вы переключиться на nc и др.

tripleee 15.05.2024 18:22

Кроме того: если вам действительно нужно поведение -e в echo -e "$message", используйте вместо него printf '%b\n' "$message", чтобы избежать сюрпризов. Даже если ваша оболочка на 100% наверняка будет bash, echo -e иногда может печатать -e на выходе вместо изменения поведения при обработке escape-последовательностей; в более строго POSIX-совместимых оболочках это будет происходить в 100% случаев.

Charles Duffy 15.05.2024 23:18
telnet предназначен для интерактивности. Используйте nc, ncat, netcat или любой другой инструмент из этого семейства. Если вам нужен диалог, то socat моя рекомендация.
Wiimm 16.05.2024 10:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
94
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вместо telnet вы можете использовать стек TCP/IP bash:

#!/bin/bash

TELNET_SERVER=192.168.1.1    # shall be an IP address (not a DNS)
TELNET_PORT=5000
message='5 :234568'

exec 3<>/dev/tcp/"$TELNET_SERVER"/"$TELNET_PORT"

echo -e "$message" >&3

IFS= read -r -u3 -t1 response

exec 3<&-

Однако у этого метода есть несколько недостатков:

  1. Если ожидается, что ответ будет занимать несколько строк, вам придется использовать цикл while read вместо одной read.

  2. Если для получения ответа требуется больше времени, чем указанный таймаут (здесь -t 1 секунда), то чтение будет прервано. Я должен сказать, что указание таймаута абсолютно необходимо; без него read мог бы висеть бесконечно.

См. редактирование ниже.

Похоже, вы просто пытаетесь проверить, открыт ли порт на хосте, или убедиться, что брандмауэр открыт через telnet. На первый взгляд кажется, что ваши попытки ожидали закрытия открытого соединения Telnet. Попробуйте это с принудительным закрытием в случае успеха, как в моих примерах ниже.

Вот что я проверил, и это работает. Вы получите разные результаты для неудач и успехов. Вот мои тесты с переменным содержимым:

Успех (проверка открытия порта через telnet):

# telnet_output=$(echo close | telnet localhost 80)
Connection closed by foreign host.
# echo $telnet_output
 Escape character is '^]'.

Сбой (порт не открыт):

# telnet_output=$(echo close | telnet localhost 6969)
telnet: connect to address ::1: Connection refused
telnet: connect to address 127.0.0.1: Connection refused
# echo $telnet_output
 Trying 127.0.0.1...

====== РЕДАКТИРОВАТЬ, Фактический ответ (надеюсь) ======

Извините, я неправильно прочитал ваше сообщение, кажется, вы на самом деле отправляете команду и хотите получить ДЕЙСТВИТЕЛЬНЫЙ ответ, вот что сработало для меня:

Успех. Подключитесь к telnet, отправьте команду, сохраните ответ в переменной, эхо-ответ:

# telnet_output=$({ echo "GET / HTTP/1.1"; echo "Host: localhost"; echo; sleep 1; } | telnet localhost 80)
Connection closed by foreign host.
# echo $telnet_output
 HTTP/1.1 302 Found Date: Wed, 15 May 2024 20:03:01 GMT Server: Apache Location: http://localhost/xxxx/Login.do Content-Length: 213 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>302 Found</title> </head><body> <h1>Found</h1> <p>The document has moved <a href = "http://localhost/xxxx/Login.do">here</a>.</p> </body></html>

Надеюсь это поможет :)

Другие вопросы по теме