Cómo utilizar declaraciones de casos en scripts Bash

Clasificar formas en categorías en una pizarra
Patpitchaya / Shutterstock.com

Las declaraciones de casos de Bash son poderosas pero fáciles de escribir. Cuando vuelva a visitar un antiguo script de Linux, se alegrará de haber utilizado un case declaración en lugar de una larga if-then-else declaración.

Declaración del caso

La mayoría de los lenguajes de programación tienen su versión de un switch o case declaración. Estos dirigen el flujo de ejecución del programa según el valor de una variable. Por lo general, hay una rama de ejecución definida para cada uno de los posibles valores esperados de la variable y un catch-all o defecto rama para todos los demás valores.

La funcionalidad lógica es similar a una larga secuencia de if-then declaraciones con un else declaración capturando todo lo que no ha sido manejado previamente por uno de los if declaraciones.

La implementación de Bash de case intenta coincidir con un expresión con una de las cláusulas. Hace esto mirando cada cláusula, a su vez, tratando de encontrar una coincidencia patrón. Los patrones en las cláusulas son cadenas, pero, en contra de la intuición, eso no significa que no podamos usar valores numéricos como expresión.

El caso genérico

La forma genérica del case declaración es esta:

case expression in 

  pattern-1)
    statement 
    ;;

  pattern-2) 
    statement
    ;;
    .
    .
    .

  pattern-N) 
    statement 
    ;;

  *) 
    statement 
    ;; 
esac

  • A case declaración debe comenzar con el case palabra clave y terminar con la esac palabra clave.
  • La expresión se evalúa y compara con los patrones de cada cláusula hasta que se encuentre una coincidencia.
  • Se ejecutan la declaración o declaraciones en la cláusula de coincidencia.
  • Un punto y coma doble «;;”Se utiliza para terminar una cláusula.
  • Si un patrón coincide y las declaraciones de esa cláusula se ejecutan, todos los demás patrones se ignoran.
  • No hay límite para 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 de la case declaración se ejecuta la cláusula predeterminada.

Un ejemplo simple

Este guión nos dice el horario de apertura de una tienda imaginaria. Usa el date comando con el +"%a" cadena de formato para obtener el nombre del día abreviado. Esto se almacena en el 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».

Necesitaremos usar el chmod comando para hacerlo ejecutable. Deberá hacer eso para todos los scripts que cree mientras trabaja en este artículo.

chmod +x open.sh

Hacer ejecutable el script 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 es viernes. Eso significa el DayName La variable contiene la cadena «Vie». Esto se corresponde con el patrón «Vie» de la cláusula «Vie)».

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

La cláusula predeterminada se ha dejado vacía. Todo lo que no coincida con una de las cláusulas anteriores se ignora.

Ese guión funciona y es fácil de leer, pero es largo y repetitivo. Podemos acortar ese tipo de case declaración con bastante facilidad.

RELACIONADO: Cómo usar el comando chmod en Linux

Usar múltiples patrones en una cláusula

Una característica realmente genial de case declaraciones es que puede utilizar varios patrones en cada cláusula. Si la expresión coincide con alguno de esos patrones, se ejecutan las declaraciones de esa cláusula.

Aquí hay un guión que le dice cuántos días hay en un mes. Solo puede haber tres respuestas: 30 días, 31 días o 28 o 29 días para febrero. Entonces, aunque son 12 meses, solo necesitamos tres cláusulas.

En este script, se solicita al usuario el nombre de un mes. Para hacer que la coincidencia de patrones no distinga entre mayúsculas y minúsculas, usamos el shopt comando con el -s nocasematch opción. No importará si la entrada contiene mayúsculas, minúsculas o una combinación de las dos.

#!/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 una cláusula para sí mismo, y todos los demás meses comparten dos cláusulas según tengan 30 o 31 días en ellas. Las cláusulas de varios patrones utilizan el símbolo de barra vertical «|» como separador. El caso predeterminado captura meses con mala ortografía.

Guardamos esto en un archivo llamado «month.sh» y lo hicimos ejecutable.

chmod +x month.sh

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

./month.sh

Ejecutando el script month.sh con diferentes entradas de caso

Debido a que le dijimos al script que ignorara las diferencias en mayúsculas y minúsculas, cualquier nombre de mes escrito correctamente es manejado por una de las tres cláusulas principales. Los meses mal escritos están sujetos a la cláusula predeterminada.

Uso de dígitos en declaraciones de casos

También podemos usar dígitos o variables numéricas como expresión. Este script le pide al usuario que ingrese un número en el rango 1..3. Para dejar en claro que los patrones de cada cláusula son cadenas, se han envuelto 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

Guarde esto en un archivo llamado «number.sh», hágalo ejecutable y luego ejecútelo:

./number.sh

Ejecutando el script number.sh y probando diferentes entradas de usuario

Usar declaraciones de casos en bucles for

A case La declaración intenta hacer coincidir el patrón con una sola expresión. Si tiene muchas expresiones para procesar, puede poner el case declaración dentro de un for círculo.

Este script ejecuta el ls comando para obtener una lista de archivos. En el for bucle, globalización de archivos: similar pero diferente a expresiones regulares: Se aplica a cada archivo a su vez para extraer la extensión del archivo. Esto se almacena en el Extension variable de cadena.

los case declaración usa el Extension variable como la expresión que intenta hacer coincidir con una cláusula.

#!/bin/bash

for File in $(ls)

do
  # extract the file extension
  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

Ejecución del script filetype.sh e identificación de archivos

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

RELACIONADO: Cómo utilizar «Documentos aquí» en Bash en Linux

Manejo de códigos de salida con declaraciones de casos

Un programa con buen comportamiento enviará un código de salida al shell cuando finalice. El esquema convencional usa 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 error.

Muchos programas usan solo cero y uno. Agrupar todas las condiciones de error en un solo código de salida dificulta la identificación de problemas, pero es una práctica común.

Creamos un pequeño programa llamado «go-geek» que devolvería aleatoriamente códigos de salida de cero o uno. Esta próxima secuencia de comandos llama go-geek. Adquiere el código de salida utilizando el $? variable de shell y la usa como expresión para la case declaración.

Un script del mundo real haría el procesamiento apropiado según el éxito o el 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

Guarde esto en un script llamado «return-code.sh» y hágalo ejecutable. Tendrá que sustituir algún otro comando por nuestro go-geek mando. Podrías intentar cd en un directorio que no existe para obtener un código de salida de uno, y luego edite su script para cd a un directorio accesible para obtener un código de salida de cero.

Ejecutar el script varias veces muestra que los diferentes códigos de salida están correctamente identificados por el case declaración.

./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 antiguos scripts de Bash y averiguar cómo hacen lo que hacen, especialmente si fueron escritos por otra persona, es un desafío. Modificar la funcionalidad de los scripts antiguos es aún más difícil.

los case La declaración le brinda una lógica de ramificación con una sintaxis clara y sencilla. Eso es beneficioso para todos.

RELACIONADO: Cómo instalar y usar Linux Bash Shell en Windows 10

Deja un comentario

En esta web usamos cookies para personalizar tu experiencia de usuario.    Política de cookies
Privacidad