Я ищу быстрый и простой способ для правильного тестирования, если данный порт TCP открыт на удаленном сервере, из сценария Shell.
Мне удалось сделать это с помощью команды telnet, и она прекрасно работает, когда порт открыт, но, похоже, не истекает время ожидания, когда это не так, и просто висит там ...
Вот пример:
l_TELNET=`echo "quit" | telnet $SERVER $PORT | grep "Escape character is"`
if [ "$?" -ne 0 ]; then
echo "Connection to $SERVER on port $PORT failed"
exit 1
else
echo "Connection to $SERVER on port $PORT succeeded"
exit 0
fi
Мне либо нужен лучший способ, либо способ заставить telnet прервать тайм-аут, например, если он не подключится менее чем за 8 секунд, и вернуть то, что я могу перехватить в Shell (код возврата или строку в stdout).
Я знаю метод Perl, который использует модуль IO :: Socket :: INET и написал успешный скрипт, который тестирует порт, но хотел бы по возможности избегать использования Perl.
Примечание: это то, что мой сервер работает (откуда мне нужно запустить это)
SunOS 5.10 Generic_139556-08 i86pc i386 i86pc
Ответы:
Как указал Б.Роудс,
nc
сделаем всю работу. Более компактный способ его использования:Этот способ
nc
будет проверять только, открыт ли порт, выход с 0 при успехе, 1 при ошибке.Для быстрой интерактивной проверки (с таймаутом 5 секунд):
источник
-G#
чтобы установить тайм-аут соединения отдельно от / в дополнение к-w#
тайм-ауту, который в основном функционирует как тайм-аут чтения.-z
возможность. Возможно, вы захотите рассмотреть вопрос: unix.stackexchange.com/questions/393762/…Это достаточно легко сделать с
-z
и-w TIMEOUT
опциямиnc
, но не все системыnc
установлены. Если у вас достаточно свежая версия bash, это будет работать:Здесь происходит то
timeout
, что подкоманда будет запускаться и уничтожать ее, если она не завершится в течение указанного времени (1 секунда в приведенном выше примере). В этом случаеbash
подкоманда использует специальную обработку / dev / tcp, чтобы попытаться открыть соединение с указанным сервером и портом. Если выbash
можете открыть соединение в течение тайм-аута,cat
просто закройте его немедленно (так как оно читает из/dev/null
) и выйдите с кодом состояния,0
который будет распространяться до,bash
а затемtimeout
. Если полученbash
сбой соединения до истечения указанного времени ожидания,bash
произойдет выход с кодом выхода 1, которыйtimeout
также вернется. И если bash не может установить соединение и истекает указанное время ожидания, тоtimeout
убьетbash
и выйдет со статусом 124.источник
/dev/tcp
доступны на других системах , чем Linux? А как насчет Mac в частности?timeout
также не существует во FreeBSD, и на моем старом Ubuntu-пакете это устанавливаемый пакет, но по умолчанию его там нет. Было бы здорово, если бы был способ сделать это только в bash, без сторонних инструментов, таких как timeout или netcat.timeout
представляется , быть частью GNU Coreutils, и может быть установлен на Маках с доморощенного:brew install coreutils
. Затем он будет доступен какgtimeout
.bash-2.04-devel
, хотя поддержка имен хостов могла быть добавлена вbash-2.05-alpha1
.TOC:
timeout
nc
Используя bash и
timeout
:Обратите внимание, что он
timeout
должен присутствовать в RHEL 6+ или альтернативно находится в GNU coreutils 8.22. В MacOS установите его используяbrew install coreutils
и используйте какgtimeout
.Команда:
При параметризации хоста и порта обязательно указывайте их как
${HOST}
и${PORT}
выше. Не указывайте их просто как$HOST
и$PORT
, т.е. без скобок; это не сработает в этом случае.Пример:
Успех:
Неудача:
Если вы должны сохранить статус выхода
bash
,Использование
nc
:Обратите внимание, что
nc
на RHEL 7 устанавливается обратная несовместимая версия .Команда:
Обратите внимание, что приведенная ниже команда уникальна в том смысле, что она идентична для RHEL 6 и 7. Отличаются только установка и вывод.
RHEL 6 (nc-1,84):
Монтаж:
Примеры:
Успех: Неудача:Если имя хоста соответствует нескольким IP-адресам, вышеприведенная неудачная команда будет циклически проходить через многие или все из них. Например:
RHEL 7 (nmap-ncat-6.40):
Монтаж:
Примеры:
Успех: Неудача:Если имя хоста соответствует нескольким IP-адресам, вышеприведенная неудачная команда будет циклически проходить через многие или все из них. Например:
Примечания:
-v
(--verbose
) Аргумент иecho $?
команда, конечно , только для иллюстрации.источник
timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
это отличный момент!2>&1
к не эхо-статусresult_test=$(nc -w 2 $ip_addreess 80 </dev/null 2>&1 ; echo $?)
С помощью этого
netcat
вы можете проверить, открыт ли порт следующим образом:Возвращаемое значение
nc
будет успешным, если был открыт порт TCP, и ошибкой (обычно код возврата 1), если не удалось установить соединение TCP.Некоторые версии
nc
будут зависать при попытке этого, потому что они не закрывают отправляющую половину своего сокета даже после получения конца файла/dev/null
. На моем собственном ноутбуке Ubuntu (18.04)netcat-openbsd
установленная мной версия netcat предлагает обходной путь:-N
для получения немедленного результата необходима опция:источник
nc
которые не поддерживают-w
флаг.-z
поддержки - работает на RHEL / CentOS 7, например-w
он необходим, в противном случае команда при использовании в сценарии может зависать более десяти секунд. Я написал ответ, который включает в себя-w
.nc host port -w 2 && echo it works
nc -vz localhost 3306
. Это дает более подробный вывод. Пробовал только на Mac.В Bash использование файлов псевдоустройств для соединений TCP / UDP просто. Вот сценарий:
Тестирование:
Вот одна строка (синтаксис Bash):
Обратите внимание, что некоторые серверы могут быть защищены брандмауэром от SYN-атак, поэтому может возникнуть тайм-аут соединения TCP (~ 75 сек). Чтобы обойти проблему тайм-аута, попробуйте:
См .: Как уменьшить время ожидания системного вызова TCP connect ()?
источник
telnet canyouseeme.org 81
тоже зависает. Это контролируется вашими пределами тайм-аута, которые, вероятно, жестко закодированы в bash. См .: уменьшить время ожидания системного вызова TCP connect () .$SERVER
и$PORT
с фигурными скобками, по крайней мере, как${SERVER}
и${PORT}
.Мне нужно было более гибкое решение для работы с несколькими git-репозиториями, поэтому я написал следующий sh-код, основанный на 1 и 2 . Вы можете использовать свой адрес сервера вместо gitlab.com и ваш порт вместо 22.
источник
Если вы используете ksh или bash, они оба поддерживают перенаправление ввода-вывода в / из сокета с помощью конструкции / dev / tcp / IP / PORT . В этом Korn оболочки примера я перенаправлять не-оп - х ( : ) не Std-в из сокета:
Оболочка печатает ошибку, если сокет не открыт:
Поэтому вы можете использовать это как тест в условии if :
No-op находится в подоболочке, поэтому я могу выбросить std-err, если перенаправление std-in завершится неудачно.
Я часто использую / dev / tcp для проверки доступности ресурса по HTTP:
Этот однострочник открывает файловый дескриптор 9 для чтения и записи в сокет, печатает HTTP GET в сокет и использует его
cat
для чтения из сокета.источник
</dev/tcp/canyouseeme.org/80
и тогда</dev/tcp/canyouseeme.org/81
.Хотя это старый вопрос, я только что рассмотрел его вариант, но ни одно из решений здесь не применимо, поэтому я нашел другое и добавляю его для потомков. Да, я знаю, что ОП сказал, что они знали об этой опции, и она им не подходила, но для любого, кто последует после этого, она может оказаться полезной.
В моем случае я хочу проверить наличие локальной
apt-cacher-ng
службы изdocker
сборки. Это означает, что абсолютно ничего нельзя установить до теста. Нетnc
,nmap
,expect
,telnet
илиpython
.perl
однако присутствует вместе с основными библиотеками, поэтому я использовал это:источник
проверить порты используя bash
пример
порт 22 открыт
Код
источник
В некоторых случаях, когда такие инструменты, как curl, telnet, nc o nmap недоступны, у вас все еще есть шанс с помощью wget
источник
Если вы хотите использовать,
nc
но не поддерживает версию-z
, попробуйте использовать--send-only
:и с таймаутом:
и без поиска DNS, если это IP:
Он возвращает коды в
-z
зависимости от того, может ли он подключиться или нет.источник
Я предполагаю, что уже слишком поздно для ответа, и это может быть не очень хорошим, но здесь вы идете ...
Как насчет того, чтобы поместить его в цикл while с таймером? Я скорее Perl, чем Solaris, но в зависимости от используемой вами оболочки, вы сможете сделать что-то вроде:
А затем просто добавьте флаг в цикл while, чтобы, если время ожидания истекло до завершения, вы могли указать в качестве причины сбоя время ожидания.
Я подозреваю, что у telnet также есть переключатель тайм-аута, но я думаю, что вышесказанное сработает.
источник
Мне нужен был короткий скрипт, который запускался в cron и не выводил. Я решаю свои проблемы с помощью Nmap
Для его запуска Вам следует установить nmap, поскольку он не является установленным по умолчанию пакетом.
источник
nmap
grepable вывод также может быть полезен-oG -
для отправки его на стандартный вывод. (grep потребовалось бы немного модифицировать)Это использует telnet за кулисами, и, кажется, отлично работает на Mac / Linux. Он не использует netcat из-за различий между версиями в linux / mac, и это работает с установкой Mac по умолчанию.
Пример:
is_port_open.sh
источник
Основываясь на ответе, получившем наибольшее количество голосов, здесь есть функция ожидания открытия двух портов, а также время ожидания. Обратите внимание на два порта, которые должны быть открыты, 8890 и 1111, а также max_attempts (1 в секунду).
источник
nmap-ncat для проверки локального порта, который еще не используется
источник