Tabla de contenidos
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 una case
declaración en lugar de una if-then-else
declaración larga .
Declaración del caso
La mayoría de los lenguajes de programación tienen su versión de una declaración switch
o case
. Estos dirigen el flujo de ejecución del programa según el 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 if-then
declaraciones con una else
declaración que captura todo lo que no ha sido manejado previamente por una de las if
declaraciones.
La implementación de Bash de case
intenta hacer coincidir una expresión con una de las cláusulas. Lo hace mirando cada cláusula, a su vez, tratando de encontrar un patrón coincidente . 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 de la case
declaración es la siguiente:
expresión de caso en patrón-1) declaración ;; patrón-2) declaración ;; . . . patrón-N) declaración ;; *) declaración ;; esac
- Una
case
declaración debe comenzar con lacase
palabra clave y terminar con laesac
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 ejecutan la declaración o declaraciones en la cláusula de coincidencia.
- Se
;;
utiliza un punto y coma doble » » 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 “
*
” indica el patrón predeterminado. Si una expresión no coincide con ninguno de los otros patrones de lacase
declaración, se ejecuta la cláusula predeterminada.
Un ejemplo simple
Este guión nos dice el horario de apertura de una tienda imaginaria. Utiliza el date
comando con la +"%a"
cadena de formato para obtener el nombre del día abreviado. Esto se almacena en la DayName
variable.
#! / bin / bash DayName = $ (fecha + "% a") echo "Horario de apertura de $ DayName" caso $ DayName en Lun) echo "09:00 - 17:30" ;; Mar) echo "09:00 - 17:30" ;; Casarse) echo "09:00 - 12:30" ;; Jue) echo "09:00 - 17:30" ;; Vie) echo "09:00 - 16:00" ;; Se sentó) echo "09:30 - 16:00" ;; Sol) echo "Cerrado todo el día" ;; *) ;; 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
Ahora podemos ejecutar nuestro script.
./open.sh
El día en que se tomó la captura de pantalla es viernes. Eso significa que la DayName
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, debe utilizar 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.
Usar múltiples patrones en una cláusula
Una característica realmente interesante de las case
declaraciones es que puede usar múltiples 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 que la coincidencia de patrones no distinga entre mayúsculas y minúsculas, usamos el shopt
comando con la -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 "Ingrese el nombre de un mes" mes de lectura caso $ mes en Febrero) echo "28/29 días en $ mes" ;; Abril | Junio | Septiembre | Noviembre) echo "30 días en $ mes" ;; Enero | Marzo | Mayo | Julio | Agosto | Octubre | Diciembre) echo "31 días en $ mes" ;; *) echo "Mes desconocido: $ mes" ;; 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 mes.sh
Ejecutaremos el script varias veces y mostraremos que no importa si usamos mayúsculas o minúsculas.
./month.sh
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 "Introduzca 1, 2 o 3:" leer número caso $ Número en "1") echo "Cláusula 1 coincidente" ;; "2") echo "Cláusula 2 coincidente" ;; "3") echo "Cláusula 3 coincidente" ;; *) echo "Cláusula predeterminada coincidente" ;; esac
Guarde esto en un archivo llamado «number.sh», hágalo ejecutable y luego ejecútelo:
./number.sh
Usar declaraciones de casos en bucles for
Una case
declaración intenta hacer coincidir el patrón con una sola expresión. Si tiene muchas expresiones para procesar, puede poner la case
declaración dentro de un for
ciclo.
Este script ejecuta el ls
comando para obtener una lista de archivos. En el for
bucle, se aplica globalización de archivos (similar pero diferente a las expresiones regulares) a cada archivo para extraer la extensión del archivo. Esto se almacena en la Extension
variable de cadena.
La case
declaración usa la Extension
variable como la expresión que intenta hacer coincidir con una cláusula.
#! / bin / bash para Archivo en $ (ls) hacer # extraer la extensión del archivo Extensión = $ {Archivo ## *.} caso "$ Extension" en sh) echo "Secuencia de comandos de Shell: $ Archivo" ;; Maryland) echo "Archivo de Markdown: $ File" ;; png) echo "Archivo de imagen PNG: $ Archivo" ;; *) echo "Desconocido: $ Archivo" ;; esac hecho
Guarde este texto en un archivo llamado «filetype.sh», hágalo ejecutable y luego ejecútelo usando:
./filetype.sh
Nuestro script de identificación de tipo de archivo minimalista funciona.
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. Este próximo script llama go-geek
. Adquiere el código de salida usando la $?
variable de shell y lo 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 caso $? en "0") echo "La respuesta fue: Éxito" echo "Realice el procesamiento apropiado aquí" ;; "1") echo "La respuesta fue: Error" echo "Realice el manejo de errores apropiado aquí" ;; *) echo "Respuesta no reconocida: $?" ;; esac
Guarde esto en un script llamado «return-code.sh» y hágalo ejecutable. Deberá sustituir nuestro go-geek
comando por algún otro comando. Puede intentar cd
ingresar a un directorio que no existe para obtener un código de salida de uno, y luego editar su secuencia de comandos cd
en un directorio accesible para obtener un código de salida de cero.
La ejecución del script varias veces muestra que la case
declaración identifica correctamente los diferentes códigos de salida .
./return-code.sh
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.
La case
declaración le brinda una lógica de ramificación con una sintaxis clara y sencilla. Eso es beneficioso para todos.