Cómo utilizar declaraciones de caso en scripts Bash

Puntos clave

  • Las declaraciones de casos de Bash hacen que los scripts sean más fáciles de leer y mantener que las largas declaraciones if-then-else.
  • La declaración de caso en Bash coincide con una expresión con patrones en las cláusulas y ejecuta declaraciones en consecuencia.
  • Puede utilizar varios patrones en una sola cláusula, lo que hace que su guión sea más conciso y eficiente. También puede utilizar dígitos o variables numéricas en declaraciones de caso.

Las declaraciones del caso Bash son poderosas pero fáciles de escribir. Cuando vuelva a visitar un antiguo script de Linux, se alegrará de haber utilizado una declaración de caso en lugar de una declaración larga si-entonces-si no.

→ Índice de contenidos
  • El caso de la Declaración
  • El caso genérico
  • Un ejemplo sencillo
  • Usar múltiples patrones en una cláusula
  • Usar cifras en declaraciones de casos
  • Usando declaraciones de caso en bucles for
  • Gestión de códigos de salida con declaraciones adecuadas.
  • La legibilidad ayuda a la mantenibilidad
  • El caso de la Declaración

    La mayoría de los lenguajes de programación tienen su propia versión de una declaración de cambio o caso. Dirigen el flujo de ejecución del programa en función del valor de una variable. Normalmente, hay una rama de ejecución definida para cada uno de los posibles valores esperados de la variable, y una rama general o predeterminada para todos los demás valores.

    La funcionalidad lógica es similar a una larga secuencia de declaraciones si-entonces con una declaración else que captura cualquier cosa que no haya sido manejada previamente por uno de los if declaraciones.

    La implementación Bash de case intenta hacer coincidir una expresión con una de las cláusulas. Lo hace examinando cada cláusula por turno, tratando de encontrar un patrón correspondiente. Los patrones en las cláusulas son cadenas, pero, de manera contradictoria, eso no significa que no podamos usar valores numéricos como expresión.

    El caso genérico

    La forma genérica de la declaración de caso es la siguiente:

     case expression in 

      pattern-1)
        statement
        ;;

      pattern-2)
        statement
        ;;
        .
        .
        .

      pattern-N)
        statement
        ;;

      *)
        statement
        ;;
    esac

    • Una declaración de caso debe comenzar con la palabra clave case y terminar con la esac palabra clave.
    • La expresión se evalúa y se compara con los patrones de cada cláusula hasta que se encuentra una coincidencia.
    • Se ejecuta la sentencia o sentencias de la cláusula correspondiente.
    • Un doble punto y coma";;" se utiliza para finalizar una cláusula.
    • Si se encuentra un patrón y se ejecutan las declaraciones de esa cláusula, se ignoran todos los demás patrones.
    • No hay límite en el número de cláusulas.
    • Un asterisco"*" denota el patrón predeterminado. Si una expresión no coincide con ninguno de los otros patrones en la declaración del caso, se ejecuta la cláusula predeterminada.

    Un ejemplo sencillo

    Este guión nos indica el horario de apertura de una tienda imaginaria. Utilizar el date comando con el +"%a" cadena de formato para obtener el nombre del día abreviado. Esto se almacena en el archivo. DayName variable.

     #!/bin/bash

    DayName=$(date +"%a")

    echo "Opening hours for $DayName"

    case $DayName in

      Mon)
        echo "09:00 - 17:30"
        ;;

      Tue)
        echo "09:00 - 17:30"
        ;;

      Wed)
        echo "09:00 - 12:30"
        ;;

      Thu)
        echo "09:00 - 17:30"
        ;;

      Fri)
        echo "09:00 - 16:00"
        ;;

      Sat)
        echo "09:30 - 16:00"
        ;;

      Sun)
        echo "Closed all day"
        ;;

      *)
        ;;
    esac

    Copie ese texto en un editor y guárdelo como un archivo llamado "open.sh".

    Tendremos que usar el comando chmod para hacerlo ejecutable. Deberá hacer esto para cualquier script que cree mientras lee este artículo.

    chmod +x open.sh

    Ahora podemos ejecutar nuestro script.

    ./open.sh

    Ejecutando el script open.sh

    El día en que se tomó la captura de pantalla parece ser un viernes. Esto significa que la variable DayName contiene la cadena "Fri". Esto corresponde al patrón "Viernes" de la cláusula "Viernes)".

    Tenga en cuenta que los patrones en las cláusulas no necesitan estar entre comillas dobles, pero si lo están, no causa ningún daño. Sin embargo, debes utilizar comillas dobles si el patrón contiene espacios.

    La cláusula predeterminada se ha dejado en blanco. Todo lo que no coincida con alguna de las cláusulas anteriores se ignora.

    El guión funciona y es fácil de leer, pero es largo y repetitivo. Podemos acortar este tipo de declaración de caso con bastante facilidad.

    Usar múltiples patrones en una cláusula

    Una característica realmente interesante de las declaraciones de casos es que puedes usar múltiples patrones en cada cláusula. Si la expresión coincide con uno de estos patrones, se ejecutan las declaraciones de esa cláusula.

    Aquí tienes un guión que te dice cuántos días hay en un mes. Sólo puede haber tres respuestas: 30 días, 31 días o 28 o 29 días para febrero. Entonces, aunque sean 12 meses, sólo necesitamos tres cláusulas.

    En este script se le pregunta al usuario el nombre de un mes. Para que la coincidencia de patrones no distinga entre mayúsculas y minúsculas, utilizamos el comando shopt con la opción "-s nocasematch". No importa si la entrada contiene letras mayúsculas, minúsculas o una combinación de ambas.

     #!/bin/bash

    shopt -s nocasematch

    echo "Enter name of a month"
    read month

    case $month in

      February)
        echo "28/29 days in $month"
        ;;

      April | June | September | November)
        echo "30 days in $month"
        ;;

      January | March | May | July | August | October | December)
        echo "31 days in $month"
        ;;

      *)
        echo "Unknown month: $month"
        ;;
    esac

    Febrero tiene su propia cláusula, y todos los demás meses comparten dos cláusulas dependiendo de si tienen 30 o 31 días. Las cláusulas de varias plantillas utilizan el símbolo de barra vertical "|" como separador. El caso predeterminado captura los meses mal escritos.

    Lo guardamos en un archivo llamado "mes.sh" y lo hicimos ejecutable.

    chmod +x month.sh

    Ejecutaremos el script varias veces y mostraremos que no importa si usamos letras mayúsculas o minúsculas.

    ./month.sh

    Ejecutando el script Month.sh con entradas de diferentes casos

    Como le dijimos al script que ignorara las diferencias entre mayúsculas y minúsculas, cualquier nombre de mes escrito correctamente se maneja mediante una de las tres cláusulas principales. Los meses mal escritos caen bajo la cláusula predeterminada.

    Usar cifras en declaraciones de casos

    También podemos utilizar dígitos o variables numéricas como expresión. Este script le pide al usuario que ingrese un número entre 1 y 3. Para dejar claro que los patrones en cada cláusula son cadenas, se han encerrado entre comillas dobles. A pesar de esto, el script aún hace coincidir la entrada del usuario con la cláusula apropiada.

     #!/bin/bash

    echo "Enter 1, 2, or 3: "
    read Number

    case $Number in

      "1")
        echo "Clause 1 matched"
        ;;

      "2")
        echo "Clause 2 matched"
        ;;

      "3")
        echo "Clause 3 matched"
        ;;

      *)
        echo "Default clause matched"
        ;;
    esac

    ./number.sh

    Ejecutar el script number.sh y probar diferentes entradas de usuario

    Usando declaraciones de caso en bucles for

    Una declaración de caso intenta hacer coincidir una sola expresión. Si tiene muchas expresiones para procesar, puede colocar la declaración del caso dentro de un bucle for.

    Este script ejecuta el comando ls para obtener una lista de archivos. En el bucle for, la agrupación de archivos, similar pero diferente a las expresiones regulares, se aplica a cada archivo por turno para extraer la extensión del archivo. Esto se almacena en la variable de cadena de extensión.

    La declaración de caso utiliza la variable Extensión como una expresión que intenta hacer coincidir una cláusula.

     #!/bin/bash

    for File in $(ls)

    do
      
      Extension=${File

      case "$Extension" in

        sh)
          echo " Shell script: $File"
          ;;

        md)
          echo " Markdown file: $File"
          ;;

        png)
          echo "PNG image file: $File"
          ;;

        *)
          echo "Unknown: $File"
          ;;
      esac
    done

    Guarde este texto en un archivo llamado "filetype.sh", hágalo ejecutable y luego ejecútelo usando:

    ./filetype.sh

    Ejecutar el script filetype.sh e identificar los archivos

    Nuestro script de identificación de tipo de archivo minimalista funciona.

    Gestión de códigos de salida con declaraciones adecuadas.

    Un programa con buen comportamiento enviará un código de salida al shell cuando finalice. El esquema convencional utiliza un valor de código de salida de cero para indicar una ejecución sin problemas y valores de uno o más para indicar diferentes tipos de errores.

    Muchos programas sólo utilizan ceros y unos. Agrupar todas las condiciones de error en un único código de salida hace que sea más difícil identificar los problemas, pero es una práctica común.

    Creamos un pequeño programa llamado "go-geek" que devolvía aleatoriamente códigos de salida de cero o uno. El siguiente guión llama go-geek. Adquirir código de salida usando $? variable de shell y la utiliza como expresión para la declaración de caso.

    Un script del mundo real realizaría el procesamiento adecuado en función del éxito o fracaso del comando que generó el código de salida.

     
    #!/bin/bash

    go-geek

    case $? in

      "0")
        echo "Response was: Success"
        echo "Do appropriate processing in here"
        ;;

      "1")
        echo "Response was: Error"
        echo "Do appropriate error handling in here"
        ;;

      *)
        echo "Unrecognised response: $?"
        ;;
    esac

    Guárdelo en un script llamado "return-code.sh" y hágalo ejecutable. Tendrás que sustituir nuestro comando go-geek por algún otro comando. Puede intentar cd en un directorio que no existe para obtener un código de salida de uno, luego cambiar su secuencia de comandos a cd en un directorio accesible para obtener un código de salida de cero.

    Al ejecutar el script varias veces se muestra que la declaración del caso identifica correctamente los diferentes códigos de salida.

    ./return-code.sh

    Ejecutando el script return-code.sh que muestra el manejo de diferentes códigos de salida

    La legibilidad ayuda a la mantenibilidad

    Volver a los viejos scripts de Bash y comprender cómo hacen lo que hacen, especialmente si fueron escritos por otra persona, es un desafío. Cambiar la funcionalidad de los scripts antiguos es aún más difícil.

    La declaración de caso proporciona una lógica de ramificación con una sintaxis clara y sencilla. Es beneficioso para todos.

    Subir Change privacy settings