Comment vérifier si un port particulier est ouvert sur une machine à partir d'un script shell et effectuer une action en fonction de cela?

24

J'exécute mon script shell ci-dessous sur une machine sur laquelle le serveur d'applications c ++ s'exécute sur le port 8080 et dans le script shell j'exécute une URL et stocke la réponse provenant de cette URL dans la variable DATA.

Mais supposons que si le même serveur d'applications est en panne, il ne pourra pas exécuter l'URL, puis il imprimera Retrying Againet dormira pendant 30 secondes, puis exécutera à nouveau la même 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"

Et voici HOSTNAMEle nom d'hôte local du serveur sur lequel j'exécute mon script shell ci-dessus.

Énoncé du problème: -

Maintenant, ce que j'essaie de faire, c'est que si le serveur est en panne, il s'imprimera Retrying Againdonc après cela, je veux vérifier si le port 8080est ouvert $HOSTNAMEou non. Sinon, cela signifie que le serveur est en panne, donc je veux redémarrer le serveur en exécutant cette commande, puis dormir pendant 30 secondes comme indiqué ci-dessus dans le script shell.

/opt/app/test/start_stop.sh start

Est-ce possible de le faire ici dans mon script shell ci-dessus?

J'exécute ce script shell sur Ubuntu 12.04.

David
la source

Réponses:

23

Le programme lsofvous permet de vérifier quels processus utilisent quelles ressources, comme des fichiers ou des ports.

Pour afficher les processus qui écoutent sur le port 8080:

lsof -Pi :8080 -sTCP:LISTEN

Dans votre cas, vous voulez tester si un processus écoute sur 8080 - la valeur de retour de cette commande vous l'indique exactement. Il imprime également le pid du processus.

lsof -Pi :8080 -sTCP:LISTEN -t

Si vous avez juste besoin du test, sans sortie, redirigez-le vers /dev/null:

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


Si vous utilisez plusieurs noms d'hôtes avec plusieurs adresses IP localement, spécifiez également le nom d'hôte comme
lsof -Pi @someLocalName:8080 -sTCP:LISTEN

Volker Siegel
la source
Merci Volker. J'ai essayé ceci lsof -i :8080 -sTCP:LISTENet je n'obtiens rien sur la console mais si j'essaye netstat -tulpn | grep :8080alors j'obtiens mon processus qui s'exécute sur le port 8080 pourquoi est-ce ainsi?
david
Quelle est la sortie de netstat -tulpn | grep :8080?
Volker Siegel
C'est ce que j'obtiens avec 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
Étrange, si j'essaye des choses similaires ça marche. Peut être lié à IPv6 ... hmmm.
Volker Siegel
Est-il répertorié avec lsof -iTCP -sTCP:LISTEN | grep 8080?
Volker Siegel
16

Manière la plus simple en bash. Testez si votre port est ouvert.

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

Remplacez l'écho par ce que vous voulez.

Ou vous pouvez utiliser nc.

nc -vz 127.0.0.1 8080

Résultats:

Connexion au port 8080 127.0.0.1 [tcp / *] réussie

RJ
la source
1
ncest une excellente solution pour mon cas d'utilisation; merci d'avoir suggéré
Jon
1

Élaborer sur la réponse de RJ quelles notes ncsont également utiles ... Non seulement est ncutile pour une requête rapide en ligne de commande

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

mais il peut être utilisé sans -v si la lisibilité humaine n'est pas ce que vous recherchez - par exemple, pour une utilisation dans un script (le code de sortie indiquera si le port est ouvert ou fermé).

 nc -z 127.0.0.1 8080

 echo $?             
1
thomp45793
la source