Szukam szybkiej i prostej metody prawidłowego testowania, czy dany port TCP jest otwarty na zdalnym serwerze z poziomu skryptu Shell.
Udało mi się to zrobić za pomocą polecenia telnet i działa dobrze, gdy port jest otwarty, ale wydaje się, że nie upłynął limit czasu, gdy nie jest i po prostu się tam zawiesza ...
Oto próbka:
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
Potrzebuję lepszego sposobu lub zmusić telnet do przekroczenia limitu czasu, jeśli nie połączy się on na przykład w czasie krótszym niż 8 sekund, i zwrócę coś, co mogę złapać w powłoce (kod powrotu lub ciąg znaków na standardowe wyjście).
Znam metodę Perla, która wykorzystuje moduł IO :: Socket :: INET i napisała udany skrypt, który testuje port, ale wolałby unikać używania Perla, jeśli to możliwe.
Uwaga: z tego działa mój serwer (z którego muszę to uruchomić)
SunOS 5.10 Generic_139556-08 i86pc i386 i86pc
Odpowiedzi:
Jak wskazał B. Rhodes,
nc
wykona zadanie. Bardziej kompaktowy sposób użycia:W ten sposób
nc
sprawdzi tylko, czy port jest otwarty, wychodząc z 0 w przypadku sukcesu, 1 w przypadku niepowodzenia.Aby szybko sprawdzić interaktywnie (z 5-sekundowym limitem czasu):
źródło
-G#
aby ustawić limit czasu połączenia oddzielnie od limitu / oprócz-w#
limitu czasu, który zasadniczo działa jako limit czasu odczytu.-z
opcję. Możesz rozważyć: unix.stackexchange.com/questions/393762/...Łatwo jest zrobić z opcjami
-z
i , ale nie wszystkie systemy mają zainstalowane. Jeśli masz wystarczająco najnowszą wersję bash, zadziała to:-w TIMEOUT
nc
nc
To, co się tutaj dzieje,
timeout
uruchomi podkomendę i zabije ją, jeśli nie zakończy działania w określonym czasie (1 sekunda w powyższym przykładzie). W tym przypadkubash
jest podkomenda i używa specjalnej obsługi / dev / tcp, aby spróbować otworzyć połączenie z serwerem i określonym portem. Jeślibash
można otworzyć połączenie w ramach limitu czasu,cat
po prostu zamknie je natychmiast (ponieważ odczytuje z/dev/null
) i zakończy działanie z kodem statusu,0
który będzie propagowany przez,bash
a następnietimeout
. Jeślibash
otrzyma awarię połączenia przed upływem określonego limitu czasu,bash
nastąpi zakończenie z kodem wyjścia 1, którytimeout
również zwróci. A jeśli bash nie będzie w stanie nawiązać połączenia i upłynie określony limit czasu, totimeout
zabijebash
i wyjdzie ze statusem 124.źródło
/dev/tcp
dostępny na systemach innych niż Linux? Co szczególnie z komputerami Mac?timeout
również nie istnieje we FreeBSD, a na moim starym Ubuntu jest to pakiet do zainstalowania, ale domyślnie go nie ma. Byłoby wspaniale, gdyby istniał sposób na zrobienie tego sam w bash, bez narzędzi innych firm, takich jak timeout czy netcat.timeout
wydaje się być częścią coreutils GNU i mogą być instalowane na komputerach Mac z homebrew:brew install coreutils
. Będzie wtedy dostępny jakogtimeout
.bash-2.04-devel
, chociaż może zostać dodana obsługa nazw hostówbash-2.05-alpha1
.Spis treści:
timeout
nc
Używanie bash i
timeout
:Zauważ, że
timeout
powinien być obecny z RHEL 6+ lub alternatywnie można go znaleźć w jądrach GNU 8.22. W systemie MacOS zainstaluj go, używającbrew install coreutils
i używaj go jakogtimeout
.Komenda:
Jeśli parametryzujesz host i port, pamiętaj, aby podać je tak jak
${HOST}
i${PORT}
powyżej. Nie określaj ich jedynie jako$HOST
i$PORT
, tj. Bez nawiasów klamrowych; w tym przypadku nie zadziała.Przykład:
Sukces:
Niepowodzenie:
Jeśli musisz zachować status wyjścia
bash
,Używanie
nc
:Zauważ, że wsteczna niekompatybilna wersja
nc
instalowana jest na RHEL 7.Komenda:
Zauważ, że poniższe polecenie jest unikalne, ponieważ jest identyczne zarówno dla RHEL 6, jak i 7. To tylko instalacja i wyjście są różne.
RHEL 6 (nc-1.84):
Instalacja:
Przykłady:
Sukces: Niepowodzenie:Jeśli nazwa hosta zostanie odwzorowana na wiele adresów IP, powyższe nieudane polecenie przejdzie przez wiele lub wszystkie z nich. Na przykład:
RHEL 7 (nmap-ncat-6.40):
Instalacja:
Przykłady:
Sukces: Niepowodzenie:Jeśli nazwa hosta zostanie odwzorowana na wiele adresów IP, powyższe nieudane polecenie przejdzie przez wiele lub wszystkie z nich. Na przykład:
Uwagi:
Argument
-v
(--verbose
) iecho $?
polecenie służą oczywiście wyłącznie do ilustracji.źródło
timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
jest świetny punkt!2>&1
do statusu „brak echa”result_test=$(nc -w 2 $ip_addreess 80 </dev/null 2>&1 ; echo $?)
Za pomocą
netcat
możesz sprawdzić, czy port jest otwarty w ten sposób:Zwracana wartość
nc
to sukces, jeśli port TCP został otwarty, a awaria (zazwyczaj kod powrotu 1), jeśli nie może nawiązać połączenia TCP.Niektóre wersje
nc
będą się zawieszać, gdy spróbujesz tego, ponieważ nie zamykają wysyłającej połowy swojego gniazda nawet po otrzymaniu od końca pliku/dev/null
. Na moim laptopie Ubuntu (18.04) zainstalowananetcat-openbsd
wersja programu netcat oferuje obejście:-N
opcja jest niezbędna, aby uzyskać natychmiastowy wynik:źródło
nc
, które nie obsługują-w
flagi.-z
wsparcia - działa na RHEL / CentOS 7, na przykład-w
jest konieczne, ponieważ w przeciwnym razie polecenie użyte w skrypcie może zawiesić się na ponad dziesięć sekund. Napisałem odpowiedź, która zawiera-w
.nc host port -w 2 && echo it works
nc -vz localhost 3306
. Daje bardziej pełny wynik. Wypróbowałem to tylko na komputerze Mac.W Bash korzystanie z plików pseudo-urządzeń dla połączeń TCP / UDP jest proste. Oto skrypt:
Testowanie:
Oto jednowierszowa (składnia Bash):
Należy pamiętać, że niektóre serwery mogą być chronione zaporą ogniową przed atakami SYN flood, dlatego może wystąpić limit czasu połączenia TCP (~ 75 sekund). Aby obejść problem z przekroczeniem limitu czasu, spróbuj:
Zobacz: Jak skrócić limit czasu połączenia systemowego TCP connect ()?
źródło
telnet canyouseeme.org 81
również się zawiesza. Jest to kontrolowane przez limity czasu, które prawdopodobnie są zakodowane na sztywno. Zobacz: zmniejsz limit czasu połączenia systemowego TCP connect () .$SERVER
i$PORT
nawiasy klamrowe, przynajmniej jako${SERVER}
i${PORT}
.Potrzebowałem bardziej elastycznego rozwiązania do pracy z wieloma repozytoriami git, więc napisałem następujący kod sh na podstawie 1 i 2 . Możesz użyć adresu serwera zamiast gitlab.com i swojego portu zamiast 22.
źródło
Jeśli używasz ksh lub bash , oba obsługują przekierowanie IO do / z gniazda za pomocą konstrukcji / dev / tcp / IP / PORT . W tym Korn przykład ja przekierowanie nie-OP ( : ) STD z gniazda:
Powłoka drukuje błąd, jeśli gniazdo nie jest otwarte:
Dlatego możesz użyć tego jako testu w warunku if :
Brak operacji jest w podpowłoce, więc mogę wyrzucić std-err, jeśli przekierowanie std-in zawiedzie.
Często używam / dev / tcp do sprawdzania dostępności zasobu przez HTTP:
Ten jednowierszowy otwiera deskryptor pliku 9 do odczytu i zapisu do gniazda, drukuje HTTP GET do gniazda i używa
cat
do odczytu z gniazda.źródło
</dev/tcp/canyouseeme.org/80
i wtedy</dev/tcp/canyouseeme.org/81
.Choć to stare pytanie, właśnie poradziłem sobie z jego wariantem, ale żadne z rozwiązań tutaj nie miało zastosowania, więc znalazłem inne i dodaję je dla potomności. Tak, wiem, że OP powiedział, że byli świadomi tej opcji i nie pasowało to do nich, ale dla każdego, kto po niej pójdzie, może się to przydać.
W moim przypadku chcę przetestować dostępność
apt-cacher-ng
usługi lokalnej zdocker
kompilacji. Oznacza to, że absolutnie nic nie można zainstalować przed testem. Nonc
,nmap
,expect
,telnet
lubpython
.perl
jednak jest obecny wraz z bibliotekami podstawowymi, więc użyłem tego:źródło
W niektórych przypadkach, gdy narzędzia takie jak curl, telnet, nc o nmap są niedostępne, nadal masz szansę z wget
źródło
sprawdź porty za pomocą bash
Przykład
port 22 jest otwarty
Kod
źródło
Jeśli chcesz używać,
nc
ale nie masz wersji obsługującej-z
, spróbuj użyć--send-only
:i po upływie limitu czasu:
i bez wyszukiwania DNS, jeśli jest to adres IP:
Zwraca kody jako
-z
oparte na tym, czy można się połączyć, czy nie.źródło
Domyślam się, że jest już za późno na odpowiedź, i to może nie być dobra, ale proszę bardzo ...
Co powiesz na umieszczenie go w pętli while z jakimś zegarem. Jestem bardziej facetem od Perla niż Solaris, ale w zależności od używanej powłoki powinieneś być w stanie zrobić coś takiego:
A następnie po prostu dodaj flagę w pętli while, aby jeśli upłynął limit czasu przed ukończeniem, możesz podać limit czasu jako przyczynę niepowodzenia.
Podejrzewam, że telnet ma również wyłącznik czasowy, ale myślę, że powyższe zadziała.
źródło
Potrzebowałem krótkiego skryptu, który został uruchomiony w cronie i nie ma danych wyjściowych. Rozwiązuję problemy za pomocą nmap
Aby go uruchomić powinieneś zainstalować nmap, ponieważ nie jest to domyślnie zainstalowany pakiet.
źródło
nmap
grepowalne wyjście może być również przydatne-oG -
do wysłania go na standardowe wyjście. (grep potrzebowałby trochę modyfikacji)To używa telnet za kulisami i wydaje się działać dobrze na Mac / Linux. Nie używa netcata ze względu na różnice między wersjami na Linux / Mac, i działa to z domyślną instalacją Mac.
Przykład:
is_port_open.sh
źródło
Opierając się na najczęściej głosowanej odpowiedzi, tutaj jest funkcja czekania na otwarcie dwóch portów, z limitem czasu. Zwróć uwagę na dwa porty, które muszą być otwarte, 8890 i 1111, a także na max_attempts (1 na sekundę).
źródło
nmap-ncat, aby przetestować port lokalny, który nie jest już używany
źródło