Jak sprawdzić, czy dany port jest otwarty na komputerze ze skryptu powłoki i wykonać na tej podstawie akcję?

24

Korzystam z poniższego skryptu powłoki na komputerze, na którym działa serwer aplikacji c ++ na porcie 8080, aw skrypcie powłoki wykonuję adres URL i zapisuję odpowiedź pochodzącą z tego adresu URL w zmiennej DATA.

Załóżmy jednak, że jeśli ten sam serwer aplikacji nie działa, nie będzie w stanie wykonać adresu URL, a następnie wydrukuje się Retrying Againi przejdzie w tryb uśpienia przez 30 sekund, a następnie ponownie uruchom ten sam adres URL.

#!/bin/bash

HOSTNAME=$hostname
DATA=""
RETRY=15

echo $HOSTNAME

while [ $RETRY -gt 0 ]
do
    DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
    if [ $? -eq 0 ]
    then
        break
    else
        echo "Retrying Again" >&2

        # restart the server

        let RETRY-=1
        sleep 30
    fi
done

echo "Server is UP"

A oto HOSTNAMElokalna nazwa hosta serwera, na którym uruchamiam powyższy skrypt powłoki.

Opis problemu: -

Teraz próbuję zrobić, jeśli serwer jest wyłączony, to wydrukuje się, a następnie Retrying Againchcę sprawdzić, czy port 8080jest otwarty, $HOSTNAMEczy nie. Jeśli nie, oznacza to, że serwer jest wyłączony, więc chcę zrestartować serwer, wykonując to polecenie, a następnie zasnąć przez 30 sekund, jak pokazano powyżej w skrypcie powłoki.

/opt/app/test/start_stop.sh start

Czy można to zrobić tutaj w moim powyższym skrypcie powłoki?

Używam tego skryptu powłoki na Ubuntu 12.04.

David
źródło

Odpowiedzi:

23

Program lsofpozwala sprawdzić, które procesy wykorzystują zasoby, takie jak pliki lub porty.

Aby pokazać, które procesy nasłuchują na porcie 8080:

lsof -Pi :8080 -sTCP:LISTEN

W twoim przypadku chcesz przetestować, czy proces nasłuchuje na 8080 - zwraca to wartość tego polecenia. Drukuje również pid procesu.

lsof -Pi :8080 -sTCP:LISTEN -t

Jeśli potrzebujesz tylko testu, bez danych wyjściowych, przekieruj go do /dev/null:

if lsof -Pi :8080 -sTCP:LISTEN -t >/dev/null ; then
    echo "running"
else
    echo "not running"
fi


Jeśli używasz wielu nazw hostów z wieloma adresami IP lokalnie, podaj też nazwę hosta w podobny sposób
lsof -Pi @someLocalName:8080 -sTCP:LISTEN

Volker Siegel
źródło
Dzięki Volker. Próbowałem tego lsof -i :8080 -sTCP:LISTENi nie dostaję nic na konsolę, ale jeśli próbuję tego, netstat -tulpn | grep :8080to otrzymuję mój proces, który działa na porcie 8080, dlaczego tak jest?
David
Jaka jest wydajność netstat -tulpn | grep :8080?
Volker Siegel,
To właśnie otrzymuję dzięki netstat david@machineA:/home/david$ netstat -tulpn | grep :8080 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 27530/test_server
David
Dziwne, jeśli spróbuję podobnych rzeczy, to działa. Może być związany z IPv6 ... hmmm.
Volker Siegel,
Czy to jest wymienione lsof -iTCP -sTCP:LISTEN | grep 8080?
Volker Siegel,
16

Najprostszy sposób na bash. Sprawdź, czy twój port jest otwarty.

(echo >/dev/tcp/localhost/8080) &>/dev/null && echo "TCP port 8080 open" || echo "TCP port 8080 close"

Zastąp echo tym, co chcesz.

Lub możesz użyć nc.

nc -vz 127.0.0.1 8080

Zwroty:

Połączenie z portem 127.0.0.1 8080 [tcp / *] powiodło się

RJ
źródło
1
ncjest doskonałym rozwiązaniem dla mojego przypadku użycia; dzięki za sugestie
Jon
1

Opracowanie odpowiedzi RJ, które notatki ncsą również przydatne ... Przydaje się nie tylko ncw szybkim zapytaniu z wiersza poleceń

 nc -z -v -w5 127.0.0.1 8080
localhost [127.0.0.1] 8080 (http-alt) : Connection refused

ale można go użyć bez opcji -v, jeśli czytelność nie jest tym, czego szukasz - np. do użycia w skrypcie (kod wyjścia wskaże, czy port jest otwarty, czy zamknięty).

 nc -z 127.0.0.1 8080

 echo $?             
1
thomp45793
źródło