Scripts básicos en Bash

Como seguramente ya sabéis los scripts o guiones, actúan como programas, pasando instrucciones a un interpretador, en nuestro caso Bash, para realizar determinadas tareas. A diferencia de los programas comunes, ya compilados, son scripts son archivos de texto que se pueden editar en cualquier momento.

El interpretador Bash

En su día ya os hablé de las mejores shell para GNU/Linux. Pues bien Bash, es una de ellas. Cuando creamos un nuevo script debemos especificar qué interpretador vamos a utilizar, el cual es indicado mediante #! (denominado comunmente shebang) En el caso de Bash esa línea comenzaría así: #!/bin/bash

Una vez creado el nuevo guión debemos asignarle permisos de ejecución, este paso es bien sencillo, utilizando el comando «chmod«, como sigue:

  1. chmod +x nuestro-script.sh

Indicamos al final la extensión «sh«, indicando así que es un script de Bash. Aunque realmente esto no es obligatorio.

Variables especiales

Los argumentos pasados a un script y otras informaciones útiles se devuelven por la variable especial $x, el cual x indica el valor de retorno:

  • $*: Todos los valores pasados como argumentos.
  • $#: El número de argumentos.
  • $0: El nombre del fichero del script.
  • $n: El valor de argumento en la posición n.
  • $!: PID del último programa ejecutado.
  • $$: PID de la shell actual.
  • $?: Código de salida del último comando.

Además, para solicitar valor al usuario, durante la ejecución de un script, se utiliza la instrucción read, por ejemplo:

  1. echo "Informe valor solicitado:"
  2. read RESPUESTA

Por lo que el valor devuelto se almacenará en la variable llamada RESPUESTA.

If then else

Con la estructura lógica if se ejecuta un comando o una lista de estos si una afirmación es verdadera. La instrucción test evalúa si la afirmación es verdadera o falsa.

Veamos algunos ejemplos:

  1. if test -x /bin/bash; then
  2.    echo "ok"
  3. fi

En el ejemplo anterior, mediante test -x, evaluamos si un fichero es ejecutable. Esto también se podría hacer de la siguiente manera:

  1. if [ -x /bin/bash ]; then
  2.     echo "ok"
  3. fi

Es importante que dejemos un espacio entre los corchetes y las instrucciones.

Podemos hacer un poquito más complejo el script, añadiendo la instrucción else, como añadido a if. Esta determina el bloque de instrucciones que se ejecutarán, si la afirmación inicial no se cumple.

  1. if [ -x /bin/bash ]; then
  2.       echo "ok"
  3. else
  4.       echo "no ok"
  5. fi

Tal y como hemos podido observar, la estructura debemos finalizar siempre con un fi

Veamos un resumen de las opciones de evaluación de la instrucción test para los archivos y directorios:

  • -d ruta: verdadero si la ruta existe y es un directorio.
  • -c ruta: verdadero si la ruta existe.
  • -f ruta: verdadero si la ruta existe y es un archivo común.
  • -L ruta: verdadero si la ruta existe y es un enlace simbólico.
  • -r ruta: verdadero si la ruta existe y se puede leer.
  • -s ruta: verdadero si la ruta existe y su tamaño es superior a cero.
  • -w ruta: verdadero si la ruta existe y se puede escribir (el fichero)
  • -x ruta: verdadero si la ruta existe y es ejecutable.

También tenemos las opciones de evaluación de test para texto.

  • -n texto: verdadero si el tamaño del texto es diferente de cero.
  • -z texto: verdadero si el tamaño de texto es cero.
  • texto1 == texto2 : verdadero si texto1 es igual a texto2.
  • text1 != text2 : verdadero si texto 1 es diferente a texto2.

Por último, que no menos importante, las opciones de evaluación de test para números

  • num1 -lt num2: verdadero si num1 es inferior a num2.
  • num1 -gt num2: verdadero si num1 es superior a num2.
  • num1 -le num2: verdadero si num1 es inferior o igual a num2.
  • num1 -ge num2: verdadero si num1 es superior o igual a num2.
  • num1 -eq num2: verdadero si num1 es igual a num2.
  • num1 -ne num2: verdadero si num1 es diferente a num2.

La variable de la instrucción if es la instrucción case. Dicha instrucción proseguirá si un ítem indicado se encuentra en una lista de ítems, divisiddos por el carácter «|», como sigue:

  1. case 2 in (1|2)
  2.  echo"Número 2 encontrado en la lista: ";
  3. esac

El final de la instrucción debe ser siempre esac. Sí, al igual que con if, es el nombre al revés.

Sustitución de comandos

Para mostrar o almacenar la salida de un comando, el mismo se coloca entre comillas simples intertidas o entre $(), que es lo más común, desde mi experiencia, o sea:

  1. VKERNEL=`uname -r`
  2. echo "La versión del kernel es :
  3. echo $VKERNEL

O bien:

  1. VKERNEL=$(uname -r)
  2. echo "La versión del kernel es : 
  3. echo $VKERNEL

Las operaciones matemáticas con número enteros se realizan con la instrucción expr

  1. RESTA=`expr $VALOR1 - $VALOR2`

O bien:

  1. RESTA=$(($VALOR1 - $VALOR2))

Instrucciones de bucle

Es muy común la creación de guiones o scripts cuya finalidad es ejecutar una tarea de forma rápida, partiendo de una condición determinada. Para ello existen las instrucciones de bucle o loop, utilizando el término anglosajón.

for

La instrucción for ejecuta o más acciones para cada elemento de una lista.

  1. SERVERS=$(cat /etc/servidores.txt)
  2.  
  3. for i in $SERVERS; do
  4.    NHOSTS=ssh root@$i "hostname";
  5.    VKERNEL=ssh root@$i "uname -r";
  6.    echo "El nombre del host es: $NHOSTS con la versión de kernel: $VKERNEL;
  7. done

De esta manera obtenemos información del nombre y de la versión del kernel de una lista de hosts que tenemos indicados en el fichero servidores.txt Para ello nos conectamos por ssh, ya que previamente hemos realizado intercambio de llaves con dichos hosts.

until

La instrucción until ejecuta una acción en bubcle hasta que una afirmación sea verdadera, por ejemplo:

  1. contador=1
  2. until [ $contador -gt 5 ]
  3. do
  4.   printf "El valor es $contador\n"
  5.   ((contador++))
  6. done

Por lo que hasta que el valor «contador» no sea mayor de 5 no parará de contar.

while

La instrucción while, es la primera perversa de until, ya que esta ejecuta una acción hasta que una afirmación no sea verdadera.

  1. contador=1
  2. while [ $contador -le 5 ]
  3. do
  4.   printf "El valor es $contador\n"
  5.   ((contador++))
  6. done

Se cumplirá la condición hasta que deje de ser verdadera.

Y esto es todo, esta entrada va para mis apuntes de repaso para el examen de LPIC 1, para la parte 102, dentro de la nueva versión 500, en cualquier caso espero que os sea de utilidad en algún momento.