Wie kann man anhand eines Shell-Skripts überprüfen, ob ein bestimmter Port auf einem Computer geöffnet ist, und eine darauf basierende Aktion ausführen?

23

Ich führe das folgende Shell-Skript auf einem Computer aus, auf dem der C ++ - Anwendungsserver auf Port 8080 ausgeführt wird, und im Shell-Skript führe ich eine URL aus und speichere die Antwort von dieser URL in der Variablen DATA.

Angenommen, derselbe App-Server ist inaktiv und kann die URL nicht ausführen. Anschließend wird die URL Retrying Again30 Sekunden lang gedruckt und in den Energiesparmodus versetzt. Anschließend wird die gleiche URL erneut ausgeführt.

#!/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"

Und hier HOSTNAMEist der lokale Hostname des Servers, auf dem ich mein obiges Shell-Skript ausführe.

Problemstellung:-

Was ich jetzt versuche zu tun, ist, wenn der Server ausfällt, dann wird es gedruckt, Retrying Againso dass ich danach überprüfen möchte, ob der Port 8080geöffnet ist $HOSTNAMEoder nicht. Wenn dies nicht der Fall ist, bedeutet dies, dass der Server inaktiv ist. Daher möchte ich den Server durch Ausführen dieses Befehls neu starten und dann 30 Sekunden lang in den Ruhezustand versetzen, wie oben im Shell-Skript gezeigt.

/opt/app/test/start_stop.sh start

Ist dies hier in meinem obigen Shell-Skript möglich?

Ich führe dieses Shell-Skript unter Ubuntu 12.04 aus.

David
quelle

Antworten:

23

Mit dem Programm lsofkönnen Sie überprüfen, welche Prozesse welche Ressourcen verwenden, z. B. Dateien oder Ports.

So zeigen Sie, welche Prozesse auf Port 8080 empfangsbereit sind:

lsof -Pi :8080 -sTCP:LISTEN

In Ihrem Fall möchten Sie testen, ob ein Prozess 8080 überwacht - der Rückgabewert dieses Befehls gibt genau dies an. Es gibt auch die PID des Prozesses aus.

lsof -Pi :8080 -sTCP:LISTEN -t

Wenn Sie nur den Test ohne Ausgabe benötigen, leiten Sie ihn weiter an /dev/null:

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


Wenn Sie lokal mehrere Hostnamen mit mehreren IP-Adressen verwenden, geben Sie den Hostnamen ebenfalls wie folgt an
lsof -Pi @someLocalName:8080 -sTCP:LISTEN

Volker Siegel
quelle
Danke Volker. Ich habe es versucht lsof -i :8080 -sTCP:LISTENund ich netstat -tulpn | grep :8080bekomme nichts auf die Konsole, aber wenn ich es versuche, bekomme ich meinen Prozess, der auf Port 8080 läuft, warum ist es so?
David
Was ist die Ausgabe von netstat -tulpn | grep :8080?
Volker Siegel
Das bekomme ich mit 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
Seltsam, wenn ich ähnliche Dinge versuche, funktioniert es. Könnte mit IPv6 zusammenhängen ... hmmm.
Volker Siegel
Ist es mit aufgeführt lsof -iTCP -sTCP:LISTEN | grep 8080?
Volker Siegel
15

Einfachster Weg in der Bash. Testen Sie, ob Ihr Port offen ist.

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

Ersetzen Sie das Echo durch das, was Sie möchten.

Oder du kannst nc benutzen.

nc -vz 127.0.0.1 8080

Kehrt zurück:

Verbindung zu 127.0.0.1 8080-Port [tcp / *] erfolgreich

RJ
quelle
1
ncist eine großartige Lösung für meinen Anwendungsfall; danke für den Vorschlag
Jon
1

Es ncist nicht nur ncfür eine schnelle Befehlszeilenabfrage nützlich, auf die Antwort von RJ einzugehen, welche Notizen auch nützlich sind

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

Es kann jedoch auch ohne -v verwendet werden, wenn die für den Menschen lesbare Sache nicht das ist, was Sie suchen - z. B. zur Verwendung in einem Skript (der Exit-Code gibt an, ob der Port offen oder geschlossen ist).

 nc -z 127.0.0.1 8080

 echo $?             
1
thomp45793
quelle