Apuntes mientras aprendo sobre software y computadoras.

Linux

Cómo saber si un sitio web esta en linea usando Bash

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
ping – send ICMP ECHO_REQUEST to network hosts

manual de ping

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.

Recursos:

2 Comments

  1. 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.

Leave a Reply