educación, informática y demás

Ejercicios, Sistemas Operativos en Red

Ejercicios de Bash Shell Script

Vamos a practicar un poco con el recorrido de ficheros en esta serie de ejercicios sobre scripts. A medida que vayamos avanzando en los ejercicios trabajaremos con distintos contenidos relacionados con el shell scripting en general.

Ejercicio 1 – Recorriendo un fichero

Vamos a recorrer un fichero, cualquiera, el que queramos. Lo único que tenemos que hacer es mostrar en pantalla el fichero línea a línea. Es más, delante del contenido de cada línea vamos a mostrar la cadena «Linea: » seguida del contenido de la linea.

Solución propuesta

Pero… esto tiene un pequeño problema, aparte de las limitaciones evidentes de esta primera versión del ejercicio: Si hay espacios en blanco en alguna de las líneas, separará la línea. Vamos a probarlo

La salida parece estar bien, hasta que la miramos más de cerca.

La sentencia for ha separado el contenido de la línea en tres líneas puesto que está utilizando como separador de campos tanto el espacio como el salto de línea. No obstante, nosotros solo queremos el salto de línea como separador.

La solución está en cambiar el separador interno de campos que se almacena en la variable IFS. Lo único que tenemos que hacer es cambiar el valor que contiene la variable IFS por tan solo $’\n’, que es el carácter especial de salto de línea.

Para no perder el contenido de esta variable, la podemos guardar en una variable temporal. Después de recorrer el fichero podemos restablecer el valor de la variable.

Ahora la salida sería la que esperabamos

Ejercicio 2 – Recibir la ruta del fichero por parámetro

Ahora el script deberá recibir la ruta del fichero a recorrer por parámetro.

Solución propuesta

Aunque esto no es del todo suficiente: no sabemos qué valor pasará el operador por parámetro, si es que pasa un valor.

Vamos a crear una función para los errores

Vamos a probar el funcionamiento del script.

Ejercicio 3 – Lista variable de rutas de ficheros

Queremos que nuestro script reciba una lista variable de rutas de ficheros de forma que el operador pueda pasar varias rutas de fichero por parámetro del script. El script deberá mostrar el contenido, línea a línea, de cada uno de los ficheros cuya ruta se ha pasado por parámetro.

Para cada parámetro, mostramos el contenido línea a línea del fichero cuya ruta está en el parámetro.

Solución propuesta

La primera propuesta…

Vemos que tenemos dos bucles for anidados. No pasa nada, pero sería más fácil de razonar y mantener el código si metemos el cuerpo actual del bucle for más externo en una función. Tiene sentido, porque todo ese código sirve para mostrar un fichero concreto.

Vamos a probar a pasarle varios parámetros

Aquí vemos que si se pasa por parámetro la ruta de un fichero que no existe, el script termina su ejecución sin mostrar nada del resto de parámetros que vengan detrás.

La solución estaría en la comprobación y, sobre todo, en la acción que llevamos a cabo en el then del comando if. No deberíamos salir del script con un error, sino salir de la función con un simple mensaje de advertencia y dejar que el script continuara.

Vamos a probar el funcionamiento del script ahora.

Como mejora estética podemos quitar $@ de la lista del for y usar un for sin lista, puesto que por defecto el for en ese caso recorre la variable $@. Esta información la tenemos en la ayuda del comando for.

De esta forma el bucle que invoca a la función showFile para cada parámetro pasado al script quedaría:

Algunas cuestiones interesantes

Cuidado con el ámbito de las funciones y de los parámetros. Sabemos que la variable $@ contiene todos los parámetros que se pasan a un script. También sabemos que las funciones también reciben parámetros y que se utilizan las mismas variables especiales para acceder a su valor.

De esta forma si hacemos este cambio para tratar de simplificar más el script o porque tenemos metido en la cabeza utilizar funciones el máximo posible (que no siempre es buena idea) el script no funcionará.

El código es el mismo, tan solo hemos creado una función nueva con el cuerpo principal del script y una invocación, pero esto no funcionará como esperamos puesto que showAllFiles no recibe ningún parámetro al llamarla y, por tanto, $@ estará vacío.

Dejar una respuesta