En este apunte ultra rápido estoy investigando cómo revisar si un sitio web esta en linea usando Bash.
La idea central es conocer si una página web se encuentra sin conexión o no.
Tal vez estoy intentando visitar ese sitio y no tengo respuesta. Puede ser que necesito iniciar una descarga o realizar alguna tarea de mantenimiento, y me va a servir conocer cuando el sitio va a volver a estar disponible.
Para realizar esto voy a valerme de el lenguaje de programación Bash, mi sistema operativo Linux y el comando Ping.
Ping hacia el otro lado
El objetivo de este breve código va a ser ejecutar cada dos minutos el comando Ping.
Y el comando va a repetirse cada dos minutos hasta que el sitio web que estoy testeando se encuentre en linea.
Según el manual de instrucciones:
NAME
manual de ping
ping – send ICMP ECHO_REQUEST to network hosts
Bueno… eso es algo confuso.
Si bien entiendo, Ping comprueba la comunicación entre dos equipos. En un ultra resumen, se envía un “mensaje” (un paquete de información) de un lado al otro, y se espera a que regrese la respuesta.
Sobre el tiempo que tarda en ir y volver el mensaje, entre otras cosas, se obtiene información del estado de la conectividad.
Dicho de otro modo, si no existe acuso de recibo del mensaje posiblemente no hay nadie del otro lado y el sitio que testeamos no funciona. Y si la respuesta tarda más de lo razonable en llegar, existe algún problema distinto a diagnosticar.
Esto quiere decir que con este comando:
ping -c 1 www.ejemplo.com
Me alcanza para cómo se encuentra la conectividad entre el sitio “ejemplo.com” y mi equipo. La opción “-c 1” hace que Ping envíe solamente un paquete, puedo modificar el “1” por la cantidad de paquetes que deseo enviar para hacer la prueba.
Sin embargo quiero todavía agregarle un poco más de funcionalidad.
El código
Me interesa hacer que el comando Ping se ejecute cada dos minutos o hasta que reciba una respuesta de que se puede comunicar con el sitio que estoy testeando.
Aunque se podría utilizar al revés, y hacer que se ejecute cada cierto intervalo de tiempo siempre que tenga una respuesta positiva. De ese modo, cuando el programa me avise que se terminó, voy a poder darme cuenta que ese sitio web se encuentra fuera de linea.
Comparto primero el código del programa, por si te interesa empezar a utilizarlo o por si querés revisarlo. Luego voy a repasarlo más en profundidad.
#!/bin/bash # Programa para revisar si un sitio web se encuentra en linea o no usando Ping cada tres minutos function ping_website { local website="$1" local count="$2" if ping -c $2 $1 &> /dev/null; then echo "$website se encuentra disponible" return 0 else echo "$website no se encuentra disponible" return 1 fi } INTERVAL=180 # tres minutos while ! ping_website $1 $2; do sleep $INTERVAL done
Cómo funciona
El programa está dividido en dos partes.
En un primer momento, se encuentra el bloque de código dedicado a utilizar el comando Ping:
function ping_website { local website="$1" local count="$2" if ping -c $2 $1 &> /dev/null; then echo "$website se encuentra disponible" return 0 else echo "$website no se encuentra disponible" return 1 fi }
Lo que hace esta función es probar ping en base a dos variables que voy a pasar al invocar el programa. Esas variables son $1 (que luego voy a pasar como la dirección del sitio) y $2 (que va a ir en luga de la cantidad de paquetes que quiero enviar).
Si puede comunicarse, devuelve una respuesta de salida 0. Y al no poder comunicarse, la respuesta de salida es 1.
Luego sigue la parte que repite en código en intervalos:
INTERVAL=180 # tres minutos while ! ping_website $1 $2; do sleep $INTERVAL done
Esto consiste en un loop, que por medio del comando “sleep” se repite a intervalos de 180 segundos. El loop se mantiene mientras que la función de una respuesta de 1, es decir que no encuentra respuesta con el sitio revisado.
Ahora, al momento de llamar al script, lo hago de esta forma:
./programa.sh sitioprueba.com 1
De ese modo le paso las dos variables que el programa se encuentra esperando.
Versión 0.2 del código
En los comentarios José Luis sugiere dos mejoras para el programa.
Una de esas mejoras es incluir una lista de sitios web directamente en el script, para los casos en los que tenemos que revisar múltiples páginas.
La otra es automatizar el código para que pueda ejecutarse cada día, o en diferentes horas, a modo de mejorar su funcionalidad.
Esta es la nueva aplicación:
#!/bin/bash # revisar sitios web en linea usando Ping ver0.2 WEBSITES=("ejemplo01.com" "sitio02.com" "website03.net") ping_website () { local website="$1" local datetime="$(date +"%Y-%m-%d %H:%M:%S")" if ping -q -c 1 -W 5 "$website" > /dev/null; then echo "$datetime $website se encuentra disponible" else echo "$datetime $website NO se encuentra disponible" fi } for website in "${WEBSITES[@]}"; do ping_website "$website" done
El primer cambio es que ahora la lista de los sitios se encuentra dentro del código, por lo que no necesitamos pasar la variable al invocarlo:
WEBSITES=("ejemplo01.com" "sitio02.com" "website03.net")
Lo siguiente es que en la función recolectamos el horario en el que se revisa la disponibilidad de los sitios, para agregarlo al dato de salida:
local datetime="$(date +"%Y-%m-%d %H:%M:%S")"
Y otra mejora es que ahora el comando Ping espera solamente 5 segundos a recibir respuesta luego de enviar el paquete:
if ping -q -c 1 -W 5 "$website" > /dev/null; then
Ahora si queremos que el programa se ejecute automáticamente cada cierto intervalo de tiempo tenemos que agregarlo al crontab.
Y necesitamos redirigir su resultado hacia un nuevo archivo, ya que no va a poder mostrarlo en la terminal.
Por ejemplo si queremos que se ejecute una vez al día, entiendo que la entrada al crontab puede quedar como:
@daily nuestro_programa.sh >> /camino/resutado.log 2>&1
En este caso “resultado.log” es el archivo de texto que creamos por fuera del código para recibir la salida y los errores de nuestro programa al ser ejecutado por cron.
Conclusión
Este apunte rápido es para analizar cómo saber si un sitio web esta en linea usando Bash.
Lo hago más que nada como para mantener la constancia de seguir aprendiendo cosas nuevas, pero espero que el material te sirva de utilidad. Siempre es posible expandir esto para agregarle nuevas herramientas.
Si encontraste algún error o tenés un comentario, me gustaría leer tu opinión.
La seguimos en el próximo apunte.
José Luis
Saludos Nuevamente !
Sería interesante, una opción que testeara una lista de dominios, cada hora o cada día de manera automática, para las personas que tenemos varios dominios que administrar…
Gustavo
¡Gracias por el aporte, José Luis! Ya actualicé la entrada con esa idea para darle nuevas mejoras al código.
Andres Dobie
Saludos !!!
Quiero dejar un pequeño aporte por si a alguien le sirve/interesa.
El problema con este script es que asumimos que el servidor web tiene habilitado ICMP, pero por regla general se desactiva ese protocolo en servidores productivos y por ende no nos servirá de nada realizar PING.
En su reemplazo existe el comando wget que podemos utilizar para el mismo fin adaptándolo a nuestras necesidades.
Ej:
#!/bin/bash
wget -S –spider http://10…/console/login/LoginForm.jsp” &> Salida-10.txt
salida=”$(grep “HTTP/1.1″ Salida-10.txt)”
echo
if [[ “${salida}” == *”200″* ]] || [[ “${salida}” == *”302″* ]]; then
echo ‘OK – http://10…/console/login/LoginForm.jsp’
else
echo ‘NOK – http://10…/console/login/LoginForm.jsp’
fi
echo
Este Script funciona chequeando la salida del comando wget y evaluando si nos da la info correcta (HTTP/1.1) obviamente cambiando la URL que nos interesa chequear, también se puede mejorar con muchas mas cosas pero acá el punto es que si el servidor WEB no tiene ICMP activado igualmente sabremos si la pagina X esta en linea o no.
Saludos y espero que a alguien le sirva el dato.