У меня есть сценарий 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"
хотя ему удалось успешно отправить данные («сообщение»). Мне не удалось получить ответ, присвоенный переменной. При попытке запустить команду в терминале вывод пуст.
Может ли кто-нибудь дать мне какое-то решение? Спасибо.
Кроме того: если вам действительно нужно поведение -e в echo -e "$message", используйте вместо него printf '%b\n' "$message", чтобы избежать сюрпризов. Даже если ваша оболочка на 100% наверняка будет bash, echo -e иногда может печатать -e на выходе вместо изменения поведения при обработке escape-последовательностей; в более строго POSIX-совместимых оболочках это будет происходить в 100% случаев.
telnet предназначен для интерактивности. Используйте nc, ncat, netcat или любой другой инструмент из этого семейства. Если вам нужен диалог, то socat моя рекомендация.





Вместо 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<&-
Однако у этого метода есть несколько недостатков:
Если ожидается, что ответ будет занимать несколько строк, вам придется использовать цикл while read вместо одной read.
Если для получения ответа требуется больше времени, чем указанный таймаут (здесь -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>
Надеюсь это поможет :)
Telnet сложно автоматизировать. Посмотрите, сможете ли вы переключиться на
ncи др.