educación, informática y demás

Shell scripts

Resumen de Bash Shell Script

Hay tres herramientas básicas en la programación estructurada:

  1. Secuencia. Significa que las instrucciones, ordenes o en este caso comandos se van a ejecutar en secuencia, en el mismo orden en el que nosotros las escribamos en el fichero de shell script.
  2. Selección. Permite ejecutar una rama u otra de comandos (un conjunto de comandos) en función de una condición.
  3. Iterativas. Permite ejecutar repetidamente un mismo grupo de comandos (cuerpo del bucle) en función de una condición o recorriendo una lista de elementos.

Además, deberíamos añadir las funciones y la modularidad. Esta última parte, la modularidad la veremos en otra entrada.

Un función nos permite ejecutar un conjunto de instrucciones o comandos (cuerpo de la función) de una sola vez, haciendo referencia al nombre de la función, que la identifica.

Lo importante, lo que deberíamos tener super claro cuando desarrollemos scripts es que aquí no hay sentencias ni instrucciones de programación, no hay palabras reservadas que identifiquen una instrucción, todo lo que ejecutemos son comandos.

Selección

Sentencias condicionales:

  • if. Permite ejecutar un conjunto de comandos si se cumple o no una condición. Tiene varias formas de usar.
    • if.. then
    • if… then.. else
    • if.. elif.. else..
  • case

Sentencia if en Bash

Lo difícil de la sentencia if, siempre y cuando sepamos algoritmia, es que se trata de un comando, y además que la condición que se evalúa en el comando if es un comando.

Si el comando que ponemos en la condición se ejecuta correctamente, entonces se cumple la condición. Si el comando no se ejecuta correctamente, entonces no se cumple la condición.

Así funciona la evaluación de condiciones tanto en el comando if como en el comando while.

Todo comando que ejecutamos en la shell bash devuelve un entero cómo valor de salida. Si este valor, este número, de código de salida es un 0 significa que el comando se ha ejecutado correctamente. Si devuelve cualquier otro valor, significa que ha habido un error.

El comando echo se ha ejecutado correctamente. Como humanos lo tenemos claro, porque vemos la salida del comando. Sin embargo si tuvieramos que comprobar desde un script si se ha ejecutado bien un comando, no podríamos hacerlo, salvo por el código de salida del comando.

Nosotros no lo vemos, el sistema no nos muestra, porque es una información que nos podría liar, sobre todo a usuarios del sistema, más que ayudar.

Existe una variable especial que nos muestra el código de retorno de un comando.

En este caso no se ha ejecutado correctamente el comando y devuelve, el sistema, un código de error

Volvamos al comando if. Vamos a ver la sintaxis del comando

Aspectos a tener en cuenta:

  • La condición del IF es ORDENES. Es decir, se va a ejecutar uno o varios comandos y si el código de salida del comando es correcto, entonces se cumple la condición y se ejecutarán las ORDENES que estén en el cuerpo del IF.
  • Podemos ver que tenemos la opción de crear un ELSE o rama alternativa que se ejecutará solo si no se cumple la condición del IF
  • Por último, podemos utilizar una serie de elif encadenados. Dónde se comprobarán distintas condiciones para ejecutar distintos cuerpos de comandos.

Tenemos claro que la condición la tenemos que definir con comandos, habitualmente uno. Pero, en lenguajes de programación de alto nivel habitualmente utilizamos comparaciones entre variables o valores para decidir qué hacer o qué ejecutar.

Para ello tenemos el comando test.

Ejemplo 01

Vamos a crear un pequeño script para recordar varios contenidos:

  • Parámetros
  • Comando if
  • Comando test

Para ejecutar este script, vamos a darle permiso de ejecución al menos al usuario. Para ello utilizaremos el comando chmod. En mi caso, le voy a dar permiso a todos los usuarios a ejecutar.

Ahora vamos a ejecutar nuestro script de distintas formas

En este primer ejemplo de ejecución, no hemos pasado parámetro. El comando if ha ejecutado el comando test y cómo se cumple la condición de que la variable usuario está vacía, se ejecuta el cuerpo del then. En este cuerpo de comandos, el último comando es un comando exit con el valor 1, lo cuál provoca que se termine la ejecución del script devolviendo un código de salida de 1.

Vamos a ver otro ejemplo de ejecución.

En este caso hemos ejecutado el script pasando como primer y único parámetro el nombre de un usuario. En ese caso el script ejecuta el comando if con la condición del comando test y cómo no se cumple la condición en la expresión que pasamos por parámetro al comando test, entonces no se ejecuta el cuerpo del if y continua la ejecución en la línea siguiente del if.

El código de retorno o salida del script es el código del último comando que se haya ejecutado en el script. Cómo el último comando ejecutado ha sido un echo y ha funcionado correctamente, entonces el código de retorno es 0.

Vamos a liarla… Vamos a poner un comando en la linea 17 que provoque un fallo.

Primer detalle, hay que guardar para que los cambios se almacenen en el fichero y a la hora de ejecutar el script se tengan en cuenta. Ahora mismo estos cambios tan solo están en memoria. Esto lo podemos ver en el editor de texto en el área de información o notificación. En el caso de mousepad está en la barra de título.

Segundo detalle, cp es un comando que requiere al menos un parámetro obligatorio. Es decir, va a fallar.

Vamos a comprobar en el shell

Vamos a ejecutar el script a ver que pasa

Es importante tener en cuenta este aspecto: «El código de retorno del script será el del último comando ejecutado dentro del script» Imaginemos que la función principal del script es copiar ficheros, si el comando de copia no lo comprobamos y el último comando se ejecuta correctamente, porque por ejemplo es un echo, puede que tengamos problemas y no nos demos cuenta.

Si ejecutamos este código…

Como humanos nos damos cuenta de que algo no ha ido bien. Pero, ¿qué sucederá si este script lo ejecutemos desde otro script dónde se comprueba si todo ha ido bien para seguir haciendo otras tareas en caso afirmativo?.

Es más, era habitual no mostrar información de los comandos que se van ejecutando en el script para evitar saturar al usuario o llenar de información la pantalla. Algunos programadores limpiaban la pantalla después de realizar la tarea o redirigían la salida a un fichero.

Si ejecutamos esto

Podríamos comprobar si se ejecuta el comando cp. Si no se ejecuta bien, entonces mostramos un mensaje de error y salimos.

Vamos a probar qué pasa 🙂

Nuestro gozo en un pozo… resulta que, se ha producido el error, lo hemos notificado pero el código de error que hemos almacenado en la variable errcode es 0 y no 1. Esto, posiblemente, sea así por la ejecución del comando if.

¿Cómo podemos solucionarlo?

Ahora si funciona como esperábamos.

Vamos a darle una vuelta. Nos gustaría contar con una función llamada backup que se encargue de realizar todas las operaciones de copia para nuestro usuario. No te preocupes porque ahora queremos que de error, es decir tan solo vamos a ejecutar cp sin parámetros.

Lo que si queremos es que podemos utilizar la función como condición del if

algo así

if ! backup; then …. fi

Podemos utilizar el comando return.

En este caso estamos guardando el errorcode del comando cp, pero puede que no sea necesario y que seamos nosotros los que decidamos el código de error

Por ejemplo, ahora podemos suponer que vamos a copiar los ficheros del directorio personal del usuario y además, vamos a mover los ficheros de backup antiguos a otro directorio.

Script backup.sh

Con las bases del script con el que hemos estado practicando vamos a crear un script llamado backup.sh que recibirá por parámetro el nombre de un usuario del sistema.

El script realizará una copia de seguridad del directorio personal del usuario pasado por parámetro en el directorio /backups utilizando la herramienta tar.

El nombre del fichero de copia de seguridad será nombreUsuario.tar.gz dónde nombreUsuario es el nombre del usuario pasado por parámetro. Cuando utilicemos la herramienta tar lo que vamos a hacer es copiar todo el contenido del directorio personal del usuario pero si el fichero tar.gz ya existe y tiene contenido, vamos a añadir tan solo los ficheros nuevos o modificados.

man tar

El script deberá comprobar:

  • Si se ha pasado parámetro
  • Si existe la cuenta de ese usuario en el sistema
  • Obtener la ruta del directorio personal del usuario del fichero de cuentas de usuario del sistema
  • Si existe el directorio /backup o no.
  • Si se ha llevado a cabo la copia de seguridad correctamente sin errores

Dejar una respuesta