Saltar al contenido

Shell Scripting con Bash para la administración de Linux – Parte 2

Cuando se necesita ejecutar diferentes series de comandos dependiendo de una condición, el shell proporciona una construcción estándar if/elif/else , similar a la mayoría de los lenguajes de programación.

La sintaxis de una declaración condicional básica se muestra en pseudo-código como sigue. Nótese que debe haber un espacio después del paréntesis de apertura y antes del de cierre:

Shell Scripting con Bash para la administración de Linux – Parte 2
Shell Scripting con Bash para la administración de Linux – Parte 2
12345678if[ condición 1]luego comandoselif[ condición 2] comandoselsefi

bash

Usemos el siguiente ejemplo para ilustrarlo:

123456789101112#! /bin/bashDÍA ACTUAL DEL MES=$(fecha +%d)if[$DÍA ACTUAL DEL MES -le 10]thenecho "Estamos dentro de los primeros 10 días del mes";elif[$DÍA ACTUAL DEL MES -le 20]thenecho "Estamos dentro de los primeros 20 días del mes";elseecho "Estamos dentro de los últimos 10 días del mes";fi

bash

El guión anterior devuelve diferentes mensajes dependiendo del día actual del mes. El primero si prueba si el día actual es menor o igual a 10. Si esta condición se evalúa como verdadera, se muestra el mensaje We are within the first 10 days of the month y no se prueban las demás condiciones. De lo contrario, elif comprueba si $CURRENTDAYOFTHEMONTH es menor o igual a 20. Si ese es el caso, Estamos dentro de los primeros 20 días del mes será devuelto en su lugar. Si no se cumple ninguna de las condiciones anteriores, se aplicará el bloque por defecto en su lugar , devolviendo Estamos dentro de los últimos 10 días del mes .

Lazos

De vez en cuando, algunas tareas deberán ejecutarse repetidamente, ya sea un número fijo de veces o hasta que se cumpla una condición específica. Ahí es donde las construcciones de “para y mientras” resultan útiles. Además, a veces necesitarás un guión para elegir entre diferentes cursos de acción basados en el valor de una variable dada – usaremos el enunciado del caso para eso.

El bucle de For

Esta construcción en bucle se utiliza para operar en cada elemento de una lista de elementos conocidos. Dicha lista puede especificarse explícitamente (enumerando cada elemento uno por uno) o como resultado de un comando. La sintaxis básica del bucle para se ilustra en el siguiente pseudocódigo:

1234para el nombre de la variable en listdo Ejecutar el comando en el nombre de la variable como $nombre-de-la-variableun

bash

Por ejemplo, podemos cambiar los permisos de los archivos archivo1.txt , archivo2.txt , y archivo3.txt a 640 usando un bucle para muy fácilmente:

1234forFILEin file1.txt file2.txt file3.txtdochmod640$FILEdone

bash

En el ejemplo anterior, la variable denominada FILE se utiliza dentro del bucle (entre las líneas do y done como $FILE. Durante la primera, segunda y tercera iteración, $FILE representa file1.txt , file2.txt , y file3.txt , respectivamente.

Un enfoque alternativo es proporcionar la lista de archivos utilizando el comando ls y grep para devolver sólo los archivos donde los nombres comienzan con la palabra file .

1234forFILEin$(ls -1 |grepfile)dochmod640$FILEdone

bash

Esto produce el mismo resultado que el ejemplo anterior.

El Bucle de Mientras

A diferencia del bucle para , mientras que se utiliza típicamente cuando no se conoce de antemano el número de iteraciones o cuando el uso de para no es práctico. Los ejemplos incluyen, entre otros, la lectura de un archivo línea por línea, el aumento o la disminución del valor de una variable hasta que alcanza un valor determinado, o la respuesta a la entrada del usuario.

La sintaxis básica del bucle mientras que es:

1234 mientras que la condición es truedo Ejecutar comandos heredone

bash

Para ilustrarlo, consideremos dos ejemplos. Primero, leamos el archivo /etc/passwd línea por línea y devolvamos un mensaje mostrando cada nombre de usuario con su correspondiente UID. Este es un ejemplo del caso en que necesitamos repetir una iteración un número indeterminado de veces.

123456whileread LINEdoUSERNAME=$(echo $LINE |cut -d$0027:$0027 -f 1)USERID=$(echo $LINE |cut -d$0027:$0027 -f 3)echo "El UID de $USERNAME es $USERID "done< /etc/passwd

bash

En este ejemplo, la condición que se comprueba al principio de cada iteración es si hemos llegado al final del archivo. La variable denominada LINE representa cada línea en /etc/passwd . Este archivo se establece como la entrada del bucle mediante el operador de redireccionamiento < . Cuando se lee cada línea, el contenido del primer y tercer campo se almacena en USERNAME y USERID , respectivamente.

Echemos un vistazo a la salida del bucle while, que hemos guardado en un script llamado users.sh en el directorio de trabajo actual. El contenido de la salida puede variar de un sistema a otro dependiendo del número y los nombres de las cuentas de usuario.

Por último, escribamos un simple juego de adivinación de números en un guión llamado guess.sh . Cuando se lanza el script, se genera un número aleatorio entre 1 y 10 y se almacena en la variable RANDOMNUM . El guión entonces esperará la entrada del usuario e indicará si la suposición es correcta, menor o mayor que el número correcto. Esto continuará hasta que el usuario adivine el número correctamente. En este ejemplo, $NUMBER != $RANDOMNUM está encerrado entre corchetes para indicar con precisión cuál es la condición a probar.

12345678910#!/bin/bashRANDOMNUM=$(shuf -i1-10 -n1)NUMBER=0while[$NUMBER!=$RANDOMNUM]doread -p "Introduce un número entre 1 y 10: " NUMBERdoneecho "¡Felicidades! Tu suposición era correcta!"

bash

La siguiente imagen muestra nuestro juego en acción: