Estoy buscando un método rápido y sencillo para comprobar correctamente si un determinado puerto TCP está abierto en un servidor remoto, desde dentro de un script de Shell.
He conseguido hacerlo con el comando telnet, y funciona bien cuando el puerto está abierto, pero parece que no se agota el tiempo de espera cuando no lo está y se queda colgado...
Aquí'hay una muestra:
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
Necesito una forma mejor, o una forma de forzar a telnet a que se agote el tiempo de espera si no se conecta en menos de 8 segundos, por ejemplo, y que devuelva algo que pueda capturar en Shell (código de retorno, o cadena en stdout).
Conozco el método de Perl, que usa el módulo IO::Socket::INET y escribí un script exitoso que prueba un puerto, pero me gustaría evitar usar Perl si es posible.
Nota: Esto es lo que mi servidor está ejecutando (desde donde necesito ejecutar esto)
SunOS 5.10 Generic_139556-08 i86pc i386 i86pc
Como señala B. Rhodes, nc
hará el trabajo. Una forma más compacta de utilizarlo:
nc -z <host> <port>
De esta manera nc
sólo comprobará si el puerto está abierto, saliendo con 0 en caso de éxito, 1 en caso de fallo.
Para una comprobación interactiva rápida (con un tiempo de espera de 5 segundos):
nc -z -v -w5 <host> <port>
Con netcat
se puede comprobar si un puerto está abierto así:
nc my.example.com 80 < /dev/null
El valor de retorno de nc
será éxito si el puerto TCP fue abierto, y fracaso (típicamente el código de retorno 1) si no pudo hacer la conexión TCP.
Algunas versiones de nc
se colgarán cuando intentes esto, porque no cierran la mitad emisora de su socket incluso después de recibir el fin de archivo de /dev/null
. En mi propio portátil Ubuntu (18.04), la versión netcat-openbsd
de netcat que he instalado ofrece una solución: la opción -N
es necesaria para obtener un resultado inmediato:
nc -N my.example.com 80 < /dev/null
Supongo que es demasiado tarde para una respuesta, y puede que ésta no sea buena, pero aquí tienes...
¿Qué hay de ponerlo dentro de un bucle while con un temporizador de algún tipo. Yo soy más de Perl que de Solaris, pero dependiendo del intérprete de comandos que utilices, deberías ser capaz de hacer algo así:
TIME = 'date +%s' + 15
while TIME != `date +%s'
do whatever
Y luego simplemente añadir una bandera en el bucle while, de modo que si el tiempo de espera antes de completar, usted puede citar el tiempo de espera como la razón del fracaso.
Sospecho que el telnet tiene un interruptor de tiempo de espera también, pero sólo de la parte superior de mi cabeza, creo que lo anterior va a funcionar.