ver script saber puertos puerto programacion pasar parametros para esta ejemplos comando abrir abiertos abierto shell tcp port solaris telnet

saber - Probar desde el script de shell si el puerto TCP remoto está abierto



ver puertos abiertos linux netstat (16)

comprobar puertos utilizando bash

Ejemplo

$ ./test_port_bash.sh 192.168.7.7 22

el puerto 22 esta abierto

Código

HOST=$1 PORT=$2 exec 3> /dev/tcp/${HOST}/${PORT} if [ $? -eq 0 ];then echo "the port $2 is open";else echo "the port $2 is closed";fi

Estoy buscando un método rápido y sencillo para probar correctamente si un puerto TCP determinado está abierto en un servidor remoto, desde un script de Shell.

Me las arreglé para hacerlo con el comando telnet, y funciona bien cuando se abre el puerto, pero parece que no se agota cuando no lo está y simplemente se cuelga allí ...

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

O bien necesito una forma mejor, o una forma de forzar el tiempo de espera de telnet si no se conecta en menos de 8 segundos, por ejemplo, y devolver algo que pueda detectar en Shell (código de retorno o cadena en la salida estándar).

Conozco el método Perl, que utiliza el módulo IO :: Socket :: INET y escribió un script exitoso que prueba un puerto, pero preferirí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


nmap-ncat para probar el puerto local que aún no está en uso

availabletobindon() { port="$1" nc -w 2 -i 1 localhost "$port" 2>&1 | grep -v -q ''Idle timeout expired'' return "$?" }


TOC:

  • Usando bash y timeout
    • Mando
    • Ejemplos
  • Utilizando nc
    • Mando
    • RHEL 6 (nc-1.84)
      • Instalación
      • Ejemplos
    • RHEL 7 (nmap-ncat-6.40)
      • Instalación
      • Ejemplos
  • Observaciones

Usando bash y timeout :

Tenga en cuenta que el timeout debe estar presente con RHEL 6+, o alternativamente se encuentra en GNU coreutils 8.22. En MacOS, instálalo usando brew install coreutils y gtimeout como gtimeout .

Mando:

$ timeout $TIMEOUT_SECONDS bash -c "</dev/tcp/${HOST}/${PORT}"; echo $?

Si está parametrizando el host y el puerto, asegúrese de especificarlos como ${HOST} y ${PORT} como se muestra arriba. No los especifique simplemente como $HOST y $PORT , es decir, sin llaves; No funcionará en este caso.

Ejemplo:

Éxito:

$ timeout 2 bash -c "</dev/tcp/canyouseeme.org/80"; echo $? 0

Fracaso:

$ timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $? 124

Si debe preservar el estado de salida de bash ,

$ timeout --preserve-status 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $? 143

Utilizando nc :

Tenga en cuenta que una versión incompatible con versiones anteriores de nc se instala en RHEL 7.

Mando:

Tenga en cuenta que el siguiente comando es único, ya que es idéntico para RHEL 6 y 7. Solo la instalación y la salida son diferentes.

$ nc -w $TIMEOUT_SECONDS -v $HOST $PORT </dev/null; echo $?

RHEL 6 (nc-1.84):

Instalación:

$ sudo yum install nc

Ejemplos:

Éxito:

$ nc -w 2 -v canyouseeme.org 80 </dev/null; echo $? Connection to canyouseeme.org 80 port [tcp/http] succeeded! 0 Fracaso:

$ nc -w 2 -v canyouseeme.org 81 </dev/null; echo $? nc: connect to canyouseeme.org port 81 (tcp) timed out: Operation now in progress 1

Si el nombre de host se asigna a varias direcciones IP, el comando que falla arriba se desplazará a través de muchos o todos ellos. Por ejemplo:

$ nc -w 2 -v microsoft.com 81 </dev/null; echo $? nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress 1

RHEL 7 (nmap-ncat-6.40):

Instalación:

$ sudo yum install nmap-ncat

Ejemplos:

Éxito:

$ nc -w 2 -v canyouseeme.org 80 </dev/null; echo $? Ncat: Version 6.40 ( http://nmap.org/ncat ) Ncat: Connected to 52.202.215.126:80. Ncat: 0 bytes sent, 0 bytes received in 0.22 seconds. 0 Fracaso:

$ nc -w 2 -v canyouseeme.org 81 </dev/null; echo $? Ncat: Version 6.40 ( http://nmap.org/ncat ) Ncat: Connection timed out. 1

Si el nombre de host se asigna a varias direcciones IP, el comando que falla arriba se desplazará a través de muchos o todos ellos. Por ejemplo:

$ nc -w 2 -v microsoft.com 81 </dev/null; echo $? Ncat: Version 6.40 ( http://nmap.org/ncat ) Ncat: Connection to 104.43.195.251 failed: Connection timed out. Ncat: Trying next address... Ncat: Connection to 23.100.122.175 failed: Connection timed out. Ncat: Trying next address... Ncat: Connection to 23.96.52.53 failed: Connection timed out. Ncat: Trying next address... Ncat: Connection to 191.239.213.197 failed: Connection timed out. Ncat: Trying next address... Ncat: Connection timed out. 1

Observaciones:

El argumento -v ( --verbose ) y el echo $? Los comandos son, por supuesto, sólo para ilustración.


Como señaló B. Rhodes, nc hará el trabajo. Una forma más compacta de usarlo:

nc -z <host> <port>

De esa manera, nc solo verificará si el puerto está abierto, saliendo con 0 en caso de éxito, 1 en caso de fallo.

Para una verificación interactiva rápida (con un tiempo de espera de 5 segundos):

nc -z -v -w5 <host> <port>


Con netcat puedes verificar si un puerto está abierto así:

nc my.example.com 80 < /dev/null

El valor de retorno de nc será exitoso si se abrió el puerto TCP, y falla (normalmente el código de retorno 1) si no pudo establecer la conexión TCP.


En Bash, usar archivos de pseudodispositivo para conexiones TCP / UDP es sencillo. Aquí está el guión:

#!/usr/bin/env bash SERVER=example.com PORT=80 </dev/tcp/$SERVER/$PORT 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

Pruebas:

$ ./test.sh Connection to example.com on port 80 succeeded

Aquí hay una sola línea (sintaxis Bash):

</dev/tcp/localhost/11211 && echo Port open. || echo Port closed.

Tenga en cuenta que algunos servidores pueden estar protegidos por firewall contra los ataques de inundación SYN, por lo que puede experimentar un tiempo de espera de conexión TCP (~ 75secs). Para solucionar el problema del tiempo de espera, intente:

timeout 1 bash -c "</dev/tcp/.com/81" && echo Port open. || echo Port closed.

Consulte: ¿Cómo disminuir el tiempo de espera de las llamadas al sistema TCP ()?


En algunos casos en los que las herramientas como curl, telnet, nc o nmap no están disponibles, todavía tiene una oportunidad con wget

if [[ $(wget -q -t 1 --spider --dns-timeout 3 --connect-timeout 10 host:port; echo $?) -eq 0 ]]; then echo "OK"; else echo "FAIL"; fi


Es bastante fácil hacerlo con las opciones -z y -w TIMEOUT para nc , pero no todos los sistemas tienen nc instalado. Si tienes una versión suficientemente reciente de bash, esto funcionará:

# Connection successful: $ timeout 1 bash -c ''cat < /dev/null > /dev/tcp/google.com/80'' $ echo $? 0 # Connection failure prior to the timeout $ timeout 1 bash -c ''cat < /dev/null > /dev/tcp/sfsfdfdff.com/80'' bash: sfsfdfdff.com: Name or service not known bash: /dev/tcp/sfsfdfdff.com/80: Invalid argument $ echo $? 1 # Connection not established by the timeout $ timeout 1 bash -c ''cat < /dev/null > /dev/tcp/google.com/81'' $ echo $? 124

Lo que sucede aquí es que el timeout ejecutará el subcomando y lo eliminará si no sale dentro del tiempo de espera especificado (1 segundo en el ejemplo anterior). En este caso, bash es el subcomando y usa su manejo especial / dev / tcp para intentar abrir una conexión al servidor y al puerto especificado. Si bash puede abrir la conexión dentro del tiempo de espera, cat cerrará inmediatamente (ya que está leyendo desde /dev/null ) y saldrá con un código de estado de 0 que se propagará a través de bash y luego se timeout . Si bash obtiene una falla de conexión antes del tiempo límite especificado, bash saldrá con un código de salida de 1, que también se devolverá. Y si bash no puede establecer una conexión y el tiempo de espera especificado caduca, el timeout anulará a bash y saldrá con un estado de 124.


Esto usa telnet detrás de escena y parece funcionar bien en mac / linux. No usa netcat debido a las diferencias entre las versiones en linux / mac, y esto funciona con una instalación mac predeterminada.

Ejemplo:

$ is_port_open.sh 80 google.com OPEN $ is_port_open.sh 8080 google.com CLOSED

is_port_open.sh

PORT=$1 HOST=$2 TIMEOUT_IN_SEC=${3:-1} VALUE_IF_OPEN=${4:-"OPEN"} VALUE_IF_CLOSED=${5:-"CLOSED"} function eztern() { if [ "$1" == "$2" ] then echo $3 else echo $4 fi } # cross platform timeout util to support mac mostly # https://gist.github.com/jaytaylor/6527607 function eztimeout() { perl -e ''alarm shift; exec @ARGV'' "$@"; } function testPort() { OPTS="" # find out if port is open using telnet # by saving telnet output to temporary file # and looking for "Escape character" response # from telnet FILENAME="/tmp/__port_check_$(uuidgen)" RESULT=$(eztimeout $TIMEOUT_IN_SEC telnet $HOST $PORT &> $FILENAME; cat $FILENAME | tail -n1) rm -f $FILENAME; SUCCESS=$(eztern "$RESULT" "Escape character is ''^]''." "$VALUE_IF_OPEN" "$VALUE_IF_CLOSED") echo "$SUCCESS" } testPort


Necesitaba un script corto que se ejecutó en cron y no tiene salida. Resuelvo mis problemas usando nmap

open=`nmap -p $PORT $SERVER | grep "$PORT" | grep open` if [ -z "$open" ]; then echo "Connection to $SERVER on port $PORT failed" exit 1 else echo "Connection to $SERVER on port $PORT succeeded" exit 0 fi

Para ejecutarlo, debe instalar nmap porque no es un paquete instalado por defecto.


Necesitaba una solución más flexible para trabajar en múltiples repositorios de git, por lo que escribí el siguiente código sh basado en 1 y 2 . Puede usar la dirección de su servidor en lugar de gitlab.com y su puerto en lugar de 22.

SERVER=gitlab.com PORT=22 nc -z -v -w5 $SERVER $PORT result1=$? #Do whatever you want if [ "$result1" != 0 ]; then echo ''port 22 is closed'' else echo ''port 22 is open'' fi


Si bien era una pregunta antigua, acabo de abordar una variante, pero ninguna de las soluciones aquí eran aplicables, así que encontré otra, y la estoy agregando para la posteridad. Sí, ya sé que el OP dijo que estaban al tanto de esta opción y que no les convenía, pero para cualquiera que los siga después podría ser útil.

En mi caso, quiero probar la disponibilidad de un servicio local apt-cacher-ng de una compilación de docker . Eso significa que no se puede instalar absolutamente nada antes de la prueba. No nc , nmap , expect , telnet o python . Sin embargo, perl está presente, junto con las bibliotecas principales, así que usé esto:

perl -MIO::Socket::INET -e ''exit(! defined( IO::Socket::INET->new("172.17.42.1:3142")))''


Si desea usar nc pero no tiene una versión que admita -z , intente usar --send-only :

nc --send-only <IP> <PORT> </dev/null

y con timeout:

nc -w 1 --send-only <IP> <PORT> </dev/null

y sin búsqueda de DNS si es una IP:

nc -n -w 1 --send-only <IP> <PORT> </dev/null

Devuelve los códigos como el -z función de si puede conectarse o no.


Si está utilizando ksh o bash , ambos admiten la redirección de E / S a / desde un socket mediante la construcción / dev / tcp / IP / PORT . En este ejemplo de shell Korn estoy redireccionando st-in de no-op (:) desde un socket:

W$ python -m SimpleHTTPServer & [1] 16833 Serving HTTP on 0.0.0.0 port 8000 ... W$ : </dev/tcp/127.0.0.1/8000

El shell imprime un error si el socket no está abierto:

W$ : </dev/tcp/127.0.0.1/8001 ksh: /dev/tcp/127.0.0.1/8001: cannot open [Connection refused]

Por lo tanto, puede usar esto como prueba en una condición if :

SERVER=127.0.0.1 PORT=8000 if (: < /dev/tcp/$SERVER/$PORT) 2>/dev/null then print succeeded else print failed fi

El no-op está en una subshell, así que puedo tirar std-err si la redirección std-in falla.

A menudo utilizo / dev / tcp para verificar la disponibilidad de un recurso a través de HTTP:

W$ print arghhh > grr.html W$ python -m SimpleHTTPServer & [1] 16863 Serving HTTP on 0.0.0.0 port 8000 ... W$ (print -u9 ''GET /grr.html HTTP/1.0/n'';cat <&9) 9<>/dev/tcp/127.0.0.1/8000 HTTP/1.0 200 OK Server: SimpleHTTP/0.6 Python/2.6.1 Date: Thu, 14 Feb 2013 12:56:29 GMT Content-type: text/html Content-Length: 7 Last-Modified: Thu, 14 Feb 2013 12:55:44 GMT arghhh W$

Este one-liner abre el descriptor de archivos 9 para leer y escribir en el socket, imprime el HTTP GET en el socket y usa cat para leer desde el socket.


Sobre la base de la respuesta más votada, aquí está una función para esperar a que se abran dos puertos, con un tiempo de espera también. Tenga en cuenta los dos puertos que deben estar abiertos, 8890 y 1111, así como los max_attempts (1 por segundo).

function wait_for_server_to_boot() { echo "Waiting for server to boot up..." attempts=0 max_attempts=30 while ( nc 127.0.0.1 8890 < /dev/null || nc 127.0.0.1 1111 < /dev/null ) && [[ $attempts < $max_attempts ]] ; do attempts=$((attempts+1)) sleep 1; echo "waiting... (${attempts}/${max_attempts})" done }


Supongo que es demasiado tarde para una respuesta, y puede que esta no sea una buena, pero aquí tienes ...

¿Qué hay de ponerlo dentro de un bucle while con un temporizador de algún tipo? Soy más un tipo de Perl que Solaris, pero dependiendo del shell que estés usando, deberías poder hacer algo como:

TIME = ''date +%s'' + 15 while TIME != `date +%s'' do whatever

Y luego simplemente agregue una bandera en el bucle while, de modo que si se agota antes de completar, puede citar el tiempo de espera como motivo del error.

Sospecho que el telnet también tiene un interruptor de tiempo de espera, pero justo en la parte superior de mi cabeza, creo que lo anterior funcionará.