Bash: Las condiciones (if-then-else)

Hello 😀

En esta ocasión les mostraré cómo hacer un script con condición en Bash, lo cual traducido es:

Si se cumple X cosa que ustedes deseen, se hace Y acción, si no se cumple entonces se hace otra acción.

Simple la explicación no 😀

Ahora, he pensado durante unos minutos algún ejemplo para usar en este tutorial, se me ha ocurrido el siguiente dilema/problema/situación:

Estamos en la red de nuestra empresa, y deseamos saber si X ordenador está conectado a la red. Para ello hacemos un script que hará ping hacia ese ordenador, y si está en red (o sea, si devuelve el ping) nos dirá que SÍ, está en red, de lo contrario (o sea, que no esté en red) nos dirá que NO está en red.

Una vez hecho esto, ahora les explicaré cómo hacer un ciclo con condiciones 🙂

Eh aquí el código:

ping -c 1 DIRECCION-IP
if [ $? -ne 0 ]; then
echo "No está en red"
else
echo "Sí está en red"
fi

No se preocupen, les explico esto al detalle 😉

ping es el comando que usaremos, y nos dirá si esa PC está en red. Para decirle qué PC queremos comprobar si está o no en red, debemos cambiar DIRECCION-IP por obviamente, la dirección IP de la PC que deseamos comprobar.

Como ven, puse «-c 1«, lo cual nos es necesario. Cuando hacemos ping a un ordenador, esta acción no se detiene (el ping) hasta que nosotros mismos presionemos [Ctrl]+[C], por lo que poniendo «-c 1» le indicamos que haga solo una verificación (solo un intento de ping) y ningún otro, esto hará que se detenga al instante, o sea… comprobará si el ordenador está en red solo una vez.

Si tienen dudas con esto, sin pena… lo dicen y yo con MUCHO gusto se los explico de nuevo 😉

Ahora viene el ciclo, pues lo que acabo de explicar no es más que un comando/acción normal 😀

if [ $? -ne 0 ]; then
echo "No está en red"
else
echo "Sí está en red"
fi

Para que entiendan esto, les explicaré un detalle sumamente importante de Bash 🙂

Los más conocedores del tema me podrían tildar de equivocado o algo así, pero bueno, esto lo escribo para lo novatos o menos expertos, mientras ellos lo entiendan entonces genial 😉

Sucede que como en Bash es algo así como 0 y 1, o sea, o estás vivo o estás muerto, cuando se ejecuta un comando o acción: O se ejecutó bien sin problemas (1), o hubo algún problema o error (0).

Nosotros efectuamos X acción o comando, y esto que hicimos puede haberse efectuado bien o mal, puedo haber tenido error o no, y aquí es donde está el detalle 😉

Si lo que mandamos a hacer (en este caso: ping -c 1 DIRECCION-IP) no dió error y se efectuó bien, entonces devolverá el valor: 1 . En caso contrario, y que la acción (o sea, el ping) no fuese exitoso, devolverá valor 0.

 Y finalmente, lo que significa el código anterior es esto:

Si se devolvió valor 0 entonces

Pon en pantalla el texto: «No está en red»

De lo contrario (y que se devuelva NO 0, sino 1)

Pon en pantalla el texto: «Si está en red«

Esto que les acabo de explicar, nos servirá en un futuro para muchísimas cosas, pues es realmente útil poder decir que si X acción dió error, haga Y acción, y en caso de que X acción no haya dado error, que haga Z acción.

Sé que a algunos podría liaros un poco, por lo que he intentado explicarlo de varias formas diferentes, intentando que todos lo entiendan de una vía u otra. En caso de que alguien se quede con dudas, me lo hace saber.

Ahora, hagamos nuestro script 😀

Debemos seguir los pasos de este tutorial: Bash: Cómo hacer un script ejecutable

Luego copiemos el siguiente código en ese archivo (script.sh), y al final pongamos «exit» (sin las comillas):

ping -c 1 DIRECCION-IP
if [ $? -ne 0 ]; then
echo "No está en red"
else
echo "Sí está en red"
fi

Les debe quedar así (recuerden que deben haber cambiado DIRECCION-IP por la IP que desean):

Aquí pueden ver el script en ejecución:

%CODE1%

Como ven, al final nos dice «Sí está en red» 🙂

Lo importante aquí es que en realidad entiendan esto de las condiciones, por lo que les dejo otro código para volver a explicarlo, pero desde otro punto de vista.

read "texto"
if [ "$texto" = "3" ]; then
echo "Correcto"
else
echo "Incorrecto"
fi

Lo que esto significa es simple, les dejo línea a línea la explicación:

1ra línea: Lo que escribamos, ese será el valor de la variable «texto» (sin las comillas).

2da línea: Comprueba si el contenido de la variable (lo que acabamos de escribir) es 3.

3ra línea: En caso de ser 3, nos mostrará el texto «Correcto» (sin las comillas).

4ta línea: De lo contrario (o sea, en caso de que no hayamos escribo 3).

5ta línea: Nos mostrará el texto «Incorrecto» (sin las comillas).

6ta línea: Fin de la condición.

Como han podido darse cuenta, si ponemos echo y seguidamente entre comillas dobles («) un texto, esto hará que se muestre en la terminal ese texto. O sea, si ponemos:

echo "esto es una prueba"

Nos mostrará en la terminal el texto: esto es una prueba

Pero volviendo a este segundo ejemplo, les mostraré la utilidad (y ejecución) de este segundo script con algo MUY simple 😀 … el típico «cuánto es 1 + 2?«

Les dejo el código del script completo:

#!/bin/bash
# -*- ENCODING: UTF-8 -*-
echo "¿Cuánto es 1 + 2?"
read "texto"
if [ "$texto" = "3" ]; then
echo "Correcto"
else
echo "Incorrecto"
fi
exit

Les dejo aquí cómo funciona el script:

%CODE2%

Y bueno… nada más que agregar.

Esto es algo elemental, simple sí, pero aún así he intentado explicarlo lo mejor posible, pues no todos tienen alma de programador, y muchas veces necesitamos hacer scripts como estos (o similares), de cualquier forma espero que este artículo le sea de utilidad a alguien 🙂

Cualquier duda o pregunta, queja o sugerencia por favor, la dejan acá, con mucho gusto les respondo y así, todos aprendemos un poco más 😀

Saludos


Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.

  1.   Jhals dijo

    Eres un pro !!! *o*

    1.    KZKG^Gaara dijo

      Nah para nada 😀
      Si te sirvió y resulta interesante, me doy por satisfecho 😉

      Saludos amigo

  2.   proper dijo

    @KZKG^Gaara,
    hablando de programación en bash tengo una duda:
    ¿cuál es la diferencia entre declarar una variable así VAR=hola y declararla de esta otra forma VAR=${VAR:-hola} ?

    me explico:
    http://pastebin.com/a3cfWXeD

    saludos 😉

    1.    KZKG^Gaara dijo

      Hello 😀
      Bueno, no soy experto en Bash ni mucho menos… en realidad, no tengo ni idea LOL!!
      Como yo declaro las variables es así:
      : ${OPTFOLDER:="/opt/"}

      Pero porque siempre lo hice así, no sé cuál podría ser la diferencia honestamente 🙁

  3.   proper dijo

    @KZKG^Gaara
    bueno la pregunta la hice porque la verdad yo tampoco sabía, yo suelo escribir SlackBuilds y la verdad las variables declaradas como en VAR1 abundan en estos scripts. Una rápida búsqueda en google me ayudó a aclarar esta duda, la comparto con todos para que todos aprendamos:

    Script:
    http://pastebin.com/faAQb35w

    Explicación:
    Declarar variables de la forma VAR=${VAR:-valor_por_defecto} significa que la variable VAR tomará el valor valor_por_defecto si y solo si el valor es nulo o no existe.

    Ejemplo práctico:
    al ejecutar el script se pide ingresar un valor para ser almacenado en la variable VAR, si se ingresa algo mostrará lo ingresado. Si no ingresamos nada y presionamos enter estamos declarando a la variable VAR como nula, por tanto muestra valor_por_defecto.

    Saludos.

    1.    KZKG^Gaara dijo

      JAJA no sabía eso 😀
      Vale, muchas gracias amigo… a eso me refería con el final del artículo, no pretendo enseñar algo y listo nada más, sé que siempre aprenderé algo nuevo aquí 😀

      Saludos y gracias una vez más.

      1.    proper dijo

        tienes razón, uno aprende varias cosas aquí.

        saludos y felices fiestas!! 😀

  4.   Lucas Matias dijo

    Buenísimo y excelentemente explicado +1, el tiempo que te habrá llevado…
    pero valido el esfuerzo 😉

    1.    KZKG^Gaara dijo

      En realidad redacté el 80% en solo 1 día, me demoré tanto en publicarlo solamente porque mi internet no me dejaba.
      Gracias por tu comentario 😉

  5.   Hugo dijo

    Otra forma de hacerlo es usando DNS, ya que a veces las redes tienen bloqueado el protocolo ICMP:

    ( host -t a DIRECCION-IP > /dev/null 2>&1 ) && echo «Conectado a la red»

    Además notarán que en este ejemplo la comprobación del valor de retorno está implícita 😉

    1.    KZKG^Gaara dijo

      Tú como siempre amigo, con tips que desconozco por completo JAJAJA.
      Gracias, se agradece el comentario y jeje… otra cosilla nueva que aprendo 😀

  6.   Datux dijo

    Gracias

    🙂

  7.   Leproso_Ivan dijo

    A pesar de que han pasado varios días desde la publicación de este tema, me ha servido mucho, ahora que hice un script en bash.. Gracias Gaara..

  8.   Edgar Navarro dijo

    Doc. Gracias por la ayuda me dejaste las cosas claras.

    Solo una consulta, como hago para que cuando un equipo deje de hacer ping automaticamente el otro cambie de IP. Tengo esto.

    para cambiar la IP
    #!/bin/bash
    ping -c 10 192.168.1.50 # Si no hace ping automaticamente
    ifconfig eth0 192.168.1.50 netmask 255.255.255.0 broadcast 192.168.1.0
    ifconfig eth0 down
    ifconfig eth0 up

  9.   Abraham dijo

    porque al comparar con el if usas el signo de interrogación ? que diferencia hay entre poner el ? cualquier otra letra

    1.    KZKG^Gaara dijo

      $? significa ‘la salida u output anterior’, o sea, en caso de que el resultado del comando anterior… 🙂

      1.    Andrés dijo

        Hay otra forma de conseguir el mismo resultado, pasar el comando ping directamente como argumento a if:

        if ping -c 1 DIRECCION-IP; then
        echo «Sí está en la red»
        else
        echo «No está en la red»
        fi

        Lo que pasa es que if evalúa el valor de retorno del comando que pases como argumento, si retorna 0 es verdadero, cualquier otra cosa es falso. Los paréntesis de corchetes equivalen al comando test. Pero puedes pasar cualquier comando como argumento (siempre y cuando el comando retorne algún un valor).

  10.   Saludos dijo

    Hola como hago para ejecutar un script.sh con un usuario X en el script creo un usuario Y, y que el usuario Y siga ejecutando el script.sh

    Se puede hacer esto??

  11.   Kuktos dijo

    Muy interesante ¡Gracias!

  12.   Francisco dijo

    Gracias por el aporte, he estado una hora para entenderlo xD, pero lo entendi!!!!.

  13.   Eloy dijo

    Está muy bien el script. De forma aritmética también se podría hacer como ( $? == 0 ) si es igual a cero no está en red, en caso contrario sí está en red. Y si aun lo queremos hacer un poco más interactivo le podemos decir:
    echo -n Introduce la Ip:
    read ip
    ping -c 1 $ip

  14.   Dario dijo

    Hola, soy muy nuevo en esto, estoy tratando de hacer de que a traves de un read ingresar un numero de ticket (alfanumerico) y quiero que si lo que se ingresa tiene el formato correcto (ABC-123456) ejecute un comando «x» y no se como hacerlo, me podrian ayudar?

    echo «Ingrese ticket»
    read -p ticket

    if $ticket = «no idea (formato ABC-123456»); then cp file.txt $ticket; else echo «formato incorrecto, intente nuevamente»; read -p; fi.

    seguro esta horrible y se rian jaja, pero como dije estoy recien empezando con esto.

    Si me explique mal por favor diganme y trato de hacerlo mejor.

    Abrazo a todos.

  15.   Humberto Y dijo

    Excelente explicación, saludos

  16.   agil dijo

    Tengo una pequeña duda con if, else y demas.
    Yo quiero que un script compruebe que un archivo existe (uno de logs) y si no, que lo cree y posteriormente escriba en el. Pero si existe quiero que solo escriba en el.

    Lo que tengo es:

    fecha=`date -R`
    #Estaba probando variable date, que no se me actualiza entre que empieza un
    #proceso y termina, a veces puede pasar una hora y no sale la hora correcta.

    if [ -f /home/usuario/logs/prueba.log ];
    then
    touch /home/usuario/logs/prueba.log
    else
    echo «$fecha: Actualizado» >> /home/usuario/logs/prueba.log
    echo «———————————————-» >> /home/usuario/logs/prueba.log
    fi

    En teoría debería estar bien, pero la realidad es qeu no se actualiza si ya existe el fichero al que se hace referencia

    1.    agil dijo

      perdon, veia que no se mandaba y se ha duplicado