El comando case nos permite implementar una sentencia de selección múltiple.
Este comando nos permite realizar una acción, ejecutar uno o varios comandos en caso de que una variable tenga un valor u otro.
Para ver como funciona vamos a consultar la ayuda de case.
Vamos a ver como funciona case con un ejemplo
Ejemplo 02 – Análisis de código
Ejercicio 03 – Desarrollo
Crea un script llamado dameOpcion.sh que solicite por teclado una operación a realizar. Mientras el usuario inserte una operación el script repetirá el proceso de análisis y solicitud de nueva operación.
En caso de que la opción insertada sea una de las siguientes se realizará la siguiente operación:
- listar. Mostrará el contenido del directorio personal del usuario actual. Comando ls
- usuarios. Mostrará en pantalla información de los usuarios conectados al sistema. Comando w o who.
- info. Mostrará información de identificación del usuario actual. Comando id.
- conexion. Mostrará un mensaje indicando si el equipo tiene conexión con internet o no. Para ello comprobaremos si tenemos conexión con el servidor DNS de google: 8.8.8.8
Si el usuario no inserta ninguna de estas operaciones, se mostrará un mensaje de advertencia indicando que la operación no es reconocida, pero no se terminará la ejecución del script.
El script terminará cuando el usuario no inserte ningún valor de operación.
Recomendaciones
Primero haríamos el bucle while, de forma que se repita mientras el usuario siga insertando algún valor para la variable operacion.
Después, una vez hayamos creado bien el bucle, nos centraríamos en el case. De forma que, seamos capaces de identificar cada una de las operaciones. En el cuerpo de cada opción, podemos simplemente mostrar un mensaje.
Cuando todo funcione, nos centramos en la funcionalidad de cada una de las opciones.
Ejercicio 4 – Otro ejemplo más
La vamos a liar… Esto funciona, pero… qué pasaría si:
El comando case evalua en orden los valores que le hemos puesto. Como * se corresponde con cualquier valor, siempre entrará en esa rama, ejecutará los comandos y terminará el case.
Por eso es necesario que si utilizamos * para valores por defecto, pongamos siempre esa opción al final.
Versión 2 – Opciones más significativas
El 1 y el 2 como opciones, así sin mas, son poco significativos. Queremos que si el usuario inserta una «u» muestre los usuarios; si el usuario inserta una «g«, muestre los grupos; si el usuario inserta una «p«, muestre todos los procesos en ejecución; si el usuario inserta una «t», muestre la hora actual. Si el usuario inserta una «d», muestre la fecha actual. Si el usuario inserta otro valor, mostraremos un mensaje advirtiendo que esa operación no es válida.
En esta primera versión, solo muestra un mensaje indicando la operación que realizarías, no hace falta que realices la operación en sí.
Versión 3 – Nombres completos
Pues eso…
Versión 4 – De todo un poco
A ver… los nombres completos, molan, pero son muy largos. Nos gustaría poder escribir tanto el nombre completo como la letra que identificaba la operación.
Aquí la barra vertical se emplea como un OR o un o. Se leería como, «en caso de que operacion se corresponda con una u o con la cadena user hacemos esto…»
Versión 05 – Mientras quiera seguir metiendo operaciones, que me siga preguntando….
Esta guay, pero… cada vez que queremos realizar una operación tenemos que volver a ejecutar el script. Nos gustaría poder insertar varias operaciones seguidas. Mientras queramos realizar una operación, el script nos pedirá la operación a realizar y la realizará.
De esta forma, el script nos pide una operación, mientras hayamos insertamos una operación, el script realizará la operación y volverá a pedirnos una nueva operación a realizar.
La estructura sería esta:
Esto ya lo hemos estudiado, tenemos la entrada sobre bucles while, así como los contenidos sobre bucles while en el apartado Sentencias iterativas comando while. Bucles mientras condición.
Según este bucle, mientras no esté vacía la variable operacion se repetirá el cuerpo del bucle. En el cuerpo del bucle, ahora mismo, tan solo mostramos un mensaje y volvemos a pedir operación.
¿Qué tendríamos que hacer para que esto funcione como me piden? Sustituir el echo por todo el case que ya hemos elaborado.
Versión 6 – Opción de salir
Nuestro jefe quiere que terminemos la ejecución del script no cuando el usuario no inserte nade, sino cuando el usuario inserte como operación salir o «s».
Hasta ahora estamos comprobando en el bucle while que «el valor de la variable operacion no sea vacio». Sin embargo, ahora tenemos que comprobar que «el valor de la variable operacion no sea ni ‘salir’ ni ‘s'».
Podemos hacer una aproximación de divide y venceras o refinamientos progresivos. Primero vamos a conseguir que si el usuario escribe salir, salgamos.
¡Eureka!
No obstante, como ya advertimos en la línea 7, si el usuario no inserta ninguna operación, dará un error de sintaxis.
¿Qué ha pasado?. Al no haber escrito ningún valor en el comando read, este comando ha asignado a la variable operacion el vacio. Es decir, bash va a sustituir $operacion por vacío. De esta manera el comando que se va a ejecutar será:
while test != salir; do
En el test, falta un operando.
Ahora sip.
Ahora nos falta, comprobar que operación no sea igual a salir Y TAMPOCO sea igual a ‘s’.
Vamos a usar el AND para comprobar que la operacion es distinta de «salir» y de «s». Mientras la operacion sea distinta de salir y de s continuamos ejecutando el bucle.
Versión 7 – Esto se complica
Hemos añadido tres nuevas operaciones, con lo que el código quedaría de la siguiente manera:
Ahora mismo el código no es demasiado complejo, pero aún así no es fácil de leer y comprender del todo. Tenemos una sentencia case demasiado grande dentro de un bucle while, lo que nos dificulta entender el funcionamiento del bucle.
¿Qué podemos hacer? ¿Y si pudieramos sacar el case del bucle y sustituirlo por un script o algo parecido?
¿o esta otra versión?
Esto funcionaría así:
El interprete de comandos en la línea 5 se encuentra la definición de la función function realizaOperacion (). Ya sabe que esa función existe y que tiene el nombre realizaOperacion. Gracias a las llaves de apertura y cierre, /bin/bash, sabe que los comandos que se deben ejecutar si se ejecuta esta función van de la línea 6 a la 26. ¡Pero no ejecuta nada!
Realmente, lo que estamos haciendo es darle un nombre a una serie de comandos que se van a ejecutar en ese orden cuando alguien los invoque o ejecute.. anda, ¡como si fuera un script!.
Una función es como un script dentro de un script
El primer comando que se ejecutará en nuestro script será el de la línea 29 y la función se invocará o ejecutará en la línea 32.
A ver… si tuvieramos que desarrollar este script desde cero, podemos utilizar las funciones para ir dividiendo el script y afrontando distintas partes una a una.
Por ejemplo, primero podríamos escribir el bucle y llamar a una función que no hace nada, porque todavía no nos hemos puesto a desarrollarla.
Ahora que sabemos que el bucle funciona, vamos implementando el case con las distintas operaciones.
Versión 8 – ¿Cómo se que operaciones hay?
¿Cómo sabe nuestro pobre operador qué operaciones puede insertar?. Vamos a mostrar la lista de operaciones disponibles al usuario justo antes de que éste inserte la operación a realizar.
La ejecución del script debería ser similar a la siguiente:
Solución con funciones
Solución sin funciones
Solución sin ninguna función en absoluto
Esta versión es la peor de todas, porque se dificulta mucho entender el código y mantenerlo.
Versión con todas las funciones
Versión aprovechando el código repetido
Versión 9 – Termina la funcionalidad del script
Ahora nos toca sustituir cada uno de los mensajes, por los comandos necesarios para que se realice la operación elegida.
Por ejemplo, u o user que muestre las cuentas de usuario del sistema que utilizan /bin/bash. Ojo! solo el nombre de las cuentas de usuario. Tendrás que utilizar al menos un par de comandos conectados con tuberías.
En cuanto al DNS podéis utilizar el comando nslookup. Para obtener más ayuda del comando consultad la página de manual.
Un ejemplo de uso podría ser:
Como todo comando, nslookup devuelve un código de salida que nos permite conocer si ha habido un error o si ha funcionado correctamente.
Dejar una respuesta