Je recherche une méthode simple et rapide pour tester correctement si un port TCP donné est ouvert sur un serveur distant, à partir d'un script Shell.
J'ai réussi à le faire avec la commande telnet, et cela fonctionne bien lorsque le port est ouvert, mais il ne semble pas expirer lorsqu'il ne l'est pas et se bloque simplement là ...
Voici un exemple:
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
J'ai besoin d'un meilleur moyen, ou d'un moyen de forcer telnet à expirer s'il ne se connecte pas en moins de 8 secondes par exemple, et de renvoyer quelque chose que je peux attraper dans Shell (code de retour ou chaîne dans stdout).
Je connais la méthode Perl, qui utilise le module IO :: Socket :: INET et a écrit un script réussi qui teste un port, mais je préfère éviter d'utiliser Perl si possible.
Remarque: c'est ce que mon serveur exécute (d'où je dois l'exécuter)
SunOS 5.10 Generic_139556-08 i86pc i386 i86pc
Réponses:
Comme l'a souligné B. Rhodes,
nc
fera le travail. Une façon plus compacte de l'utiliser:De cette façon
nc
, ne vérifiera que si le port est ouvert, en sortant avec 0 en cas de succès, 1 en cas d'échec.Pour une vérification interactive rapide (avec un délai de 5 secondes):
la source
-G#
pour définir un délai de connexion distinct de / en plus du-w#
délai, qui fonctionne essentiellement comme un délai de lecture.-z
option. Vous voudrez peut-être considérer: unix.stackexchange.com/questions/393762/…C'est assez facile à faire avec les options
-z
et , mais tous les systèmes ne sont pas installés. Si vous avez une version suffisamment récente de bash, cela fonctionnera:-w TIMEOUT
nc
nc
Ce qui se passe ici, c'est qu'il
timeout
exécutera la sous-commande et la tuera si elle ne se termine pas dans le délai spécifié (1 seconde dans l'exemple ci-dessus). Dans ce cas,bash
la sous-commande utilise sa gestion spéciale / dev / tcp pour essayer d'ouvrir une connexion au serveur et au port spécifiés. Sibash
peut ouvrir la connexion dans le délai d'attente, lacat
fermera immédiatement immédiatement (car il lit à partir de/dev/null
) et quittera avec un code d'état0
qui se propagera à traversbash
puistimeout
. Sibash
obtient un échec de connexion avant le délai spécifié, puisbash
quittera avec un code de sortie de 1 quitimeout
reviendra également. Et si bash n'est pas en mesure d'établir une connexion et que le délai spécifié expire, alorstimeout
va tuerbash
et quitter avec un statut de 124.la source
/dev/tcp
disponible sur des systèmes autres que Linux? Et les Mac en particulier?timeout
n'existe pas non plus dans FreeBSD, et sur mon ancienne boîte Ubuntu, c'est un paquet installable, mais il n'est pas là par défaut. Ce serait génial s'il y avait un moyen de le faire en bash seul, sans outils tiers comme timeout ou netcat.timeout
semble faire partie de coreutils GNU, et peuvent être installés sur macs avec homebrew:brew install coreutils
. Il sera ensuite disponible en tant quegtimeout
.bash-2.04-devel
, bien que la prise en charge des noms d'hôtes ait pu être ajoutéebash-2.05-alpha1
.COT:
timeout
nc
Utilisation de bash et
timeout
:Notez que
timeout
devrait être présent avec RHEL 6+, ou se trouve alternativement dans GNU coreutils 8.22. Sur MacOS, installez-le en utilisantbrew install coreutils
et utilisez-le en tant quegtimeout
.Commander:
Si vous paramétrez l'hôte et le port, assurez-vous de les spécifier tels quels
${HOST}
et${PORT}
comme ci-dessus. Ne les spécifiez pas simplement comme$HOST
et$PORT
, c'est-à-dire sans les accolades; cela ne fonctionnera pas dans ce cas.Exemple:
Succès:
Échec:
Si vous devez conserver le statut de sortie de
bash
,En utilisant
nc
:Notez qu'une version incompatible en amont de
nc
est installée sur RHEL 7.Commander:
Notez que la commande ci-dessous est unique en ce qu'elle est identique pour RHEL 6 et 7. Ce sont juste l'installation et la sortie qui sont différentes.
RHEL 6 (nc-1.84):
Installation:
Exemples:
Succès: Échec:Si le nom d'hôte est mappé sur plusieurs adresses IP, la commande défaillante ci-dessus fera défiler la plupart ou la totalité d'entre elles. Par exemple:
RHEL 7 (nmap-ncat-6.40):
Installation:
Exemples:
Succès: Échec:Si le nom d'hôte est mappé sur plusieurs adresses IP, la commande défaillante ci-dessus fera défiler la plupart ou la totalité d'entre elles. Par exemple:
Remarques:
L' argument
-v
(--verbose
) et laecho $?
commande sont bien sûr à titre d'illustration uniquement.la source
timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
est un excellent point!2>&1
au statut non échoresult_test=$(nc -w 2 $ip_addreess 80 </dev/null 2>&1 ; echo $?)
Avec
netcat
vous pouvez vérifier si un port est ouvert comme ceci:La valeur de retour de
nc
sera succès si le port TCP a été ouvert et échec (généralement le code retour 1) s'il n'a pas pu établir la connexion TCP.Certaines versions de
nc
se bloquent lorsque vous essayez ceci, car elles ne ferment pas la moitié d'envoi de leur socket même après avoir reçu la fin du fichier de/dev/null
. Sur mon propre ordinateur portable Ubuntu (18.04), lanetcat-openbsd
version de netcat que j'ai installée propose une solution: l'-N
option est nécessaire pour obtenir un résultat immédiat:la source
nc
qui ne prennent pas en charge le-w
drapeau.-z
support - fonctionne sur RHEL / CentOS 7, par exemple-w
est nécessaire, faute de quoi la commande utilisée dans un script peut se bloquer pendant plus de dix secondes. J'ai écrit une réponse qui comprend-w
.nc host port -w 2 && echo it works
nc -vz localhost 3306
. Il donne une sortie plus détaillée. Je l'ai essayé sur mac uniquement.Dans Bash, l'utilisation de fichiers pseudo-périphériques pour les connexions TCP / UDP est simple. Voici le script:
Essai:
Voici une ligne (syntaxe Bash):
Notez que certains serveurs peuvent être protégés par un pare-feu contre les attaques par inondation SYN, vous pouvez donc rencontrer un délai de connexion TCP (~ 75 secondes). Pour contourner le problème de délai d'attente, essayez:
Voir: Comment réduire le délai d'expiration des appels système TCP connect ()?
la source
telnet canyouseeme.org 81
se bloque également. Ceci est contrôlé par vos délais d'expiration qui sont probablement codés en dur dans bash. Voir: diminuer le délai d'expiration de l'appel système TCP connect () .$SERVER
et$PORT
avec des accolades, au moins comme${SERVER}
et${PORT}
.J'avais besoin d'une solution plus flexible pour travailler sur plusieurs référentiels git, j'ai donc écrit le code sh suivant basé sur 1 et 2 . Vous pouvez utiliser votre adresse de serveur au lieu de gitlab.com et votre port en remplacement de 22.
la source
Si vous utilisez ksh ou bash, ils prennent tous les deux en charge la redirection IO vers / depuis un socket en utilisant la construction / dev / tcp / IP / PORT . Dans ce shell Korn exemple , je suis pas redirigez-op de ( : ) std-in d'une prise:
Le shell affiche une erreur si le socket n'est pas ouvert:
Vous pouvez donc l'utiliser comme test dans une condition if :
Le no-op est dans un sous-shell donc je peux jeter std-err si la redirection std-in échoue.
J'utilise souvent / dev / tcp pour vérifier la disponibilité d'une ressource sur HTTP:
Cette ligne unique ouvre le descripteur de fichier 9 pour la lecture et l'écriture dans le socket, imprime le HTTP GET sur le socket et utilise
cat
pour lire à partir du socket.la source
</dev/tcp/canyouseeme.org/80
et ensuite</dev/tcp/canyouseeme.org/81
.Bien qu'il s'agisse d'une vieille question, je viens d'en traiter une variante, mais aucune des solutions ici n'était applicable, alors j'en ai trouvé une autre et je l'ajoute pour la postérité. Oui, je sais que le PO a dit qu'il était au courant de cette option et qu'elle ne lui convenait pas, mais pour toute personne qui suivrait, cela pourrait s'avérer utile.
Dans mon cas, je veux tester la disponibilité d'un
apt-cacher-ng
service local à partir d'unedocker
build. Cela signifie que rien ne peut être installé avant le test. Nonnc
,nmap
,expect
,telnet
oupython
.perl
cependant est présent, avec les bibliothèques de base, donc j'ai utilisé ceci:la source
vérifier les ports à l'aide de bash
Exemple
le port 22 est ouvert
Code
la source
Dans certains cas où des outils comme curl, telnet, nc o nmap ne sont pas disponibles, vous avez encore une chance avec wget
la source
Si vous souhaitez utiliser
nc
mais ne disposez pas d'une version qui prend en charge-z
, essayez d'utiliser--send-only
:et avec timeout:
et sans recherche DNS s'il s'agit d'une IP:
Il renvoie les codes en fonction de la
-z
possibilité de se connecter ou non.la source
Je suppose qu'il est trop tard pour une réponse, et ce n'est peut-être pas une bonne réponse, mais c'est parti ...
Qu'en est-il de le mettre à l'intérieur d'une boucle while avec une minuterie dessus? Je suis plus du genre Perl que Solaris, mais selon le shell que vous utilisez, vous devriez pouvoir faire quelque chose comme:
Et puis ajoutez simplement un indicateur dans la boucle while, de sorte que s'il expire avant la fin, vous pouvez citer le délai d'expiration comme raison de l'échec.
Je soupçonne que le telnet a également un commutateur de temporisation, mais juste au-dessus de ma tête, je pense que ce qui précède fonctionnera.
la source
J'avais besoin d'un script court qui a été exécuté dans cron et n'a pas de sortie. Je résous mes problèmes en utilisant nmap
Pour l'exécuter Vous devez installer nmap car il ne s'agit pas d'un package installé par défaut.
la source
nmap
La sortie de grepable pourrait également être utile-oG -
pour l'envoyer à stdout. (le grep aurait besoin d'un peu de modification)Cela utilise telnet dans les coulisses et semble bien fonctionner sur mac / linux. Il n'utilise pas netcat en raison des différences entre les versions sur linux / mac, et cela fonctionne avec une installation mac par défaut.
Exemple:
is_port_open.sh
la source
S'appuyant sur la réponse la plus votée, voici une fonction permettant d'attendre l'ouverture de deux ports, avec un délai d'attente également. Notez les deux ports qui doivent être ouverts, 8890 et 1111, ainsi que les max_attempts (1 par seconde).
la source
nmap-ncat pour tester le port local qui n'est pas déjà utilisé
la source