Programas de shell

Además de las anteriores posibilidades también se pueden agrupar una serie de órdenes en un fichero de texto que se ejecutarán consecutivamente siguiendo el flujo determinado por órdenes de control similares a cualquier lenguaje de programación. Estos ficheros se conocen como scripts, guiones o simplemente programas de shell. A las órdenes agrupadas en ficheros también se le aplican todas las características descritas anteriormente. No olvidemos que para un sistema unix, una línea leída de un fichero es idéntica a una línea leída desde el teclado, una serie de caracteres terminado por un carácter de retorno de carro.

Cualquier forma de ejecución que se pueda dar en la línea de órdenes también se puede incluir en un fichero de texto, con lo que facilitamos su repetición. Y si por último añadimos las estructuras que controlan el flujo de ejecución y ciertas condiciones lógicas, tenemos un perfecto lenguaje de programación para administrar el sistema con toda facilidad. Un administrador que sabe cual es su trabajo cotidiano, realizar copias de seguridad, dar de alta o baja usuarios, comprobar que los servicios están activos, analizar log de incidencias, configurar cortafuegos, lanzar o parar servicios, modificar configuraciones, etc., normalmente se creará sus script personalizados. Algunos los utilizará cuando sea necesario y para otros programará el sistema para que se ejecuten periódicamente.

La programación en shell es imprescindible para poder administrar un sistema Unix de forma cómoda y eficiente.

Vemos un primer ejemplo:

         #!/bin/bash           
            
         echo Hola Mundo 
            

Puestas estas dos línea en un fichero de texto con permiso de ejecución, al ejecutarlo escribiría en pantalla "Hola Mundo". La primera línea, como veremos con posterioridad, indica qué shell es la que interpreta el programa de shell.

subshell

Para la ejecución de programas de shell, la shell se encarga de interpretar unas órdenes en unos casos o de lanzar el programa adecuado en otros casos. En general, cuando lanzamos la ejecución de un conjunto de órdenes agrupadas en un programa de shell, se abre una nueva shell (subshell hija de la anterior) que es la encargada de interpretar las órdenes del fichero. Una vez concluida la ejecución esta subshell muere y volvemos a la shell inicial. Esto es importante tenerlo presente para saber el comportamiento de los programas. Por ejemplo, los cambios hechos en las variables de shell dentro de un programa no se conservan una vez concluida la ejecución.

Vamos a ilustrar este comportamiento con nuestro primer ejemplo de programa de shell:

Creamos un programa en un fichero de texto, lo ejecutamos, comprobamos que se crea una nueva shell y que los cambios en las variables hechos dentro del programa no se mantienen una vez concluido. Editamos un fichero llamado "pruebashell" con el siguiente contenido:

echo "******** GUION ********"
echo "el valor previo de VAR es ** $VAR **"
VAR="valor asignado dentro del guion"
echo "Ahora VAR vale ** $VAR **"
ps
echo "******** FIN DEL GUION ********"
              

Con este guion mostramos el valor previo de una variable llamada VAR, le asignamos un valor nuevo y también los mostramos. Para verificar que se lanza una nueva shell mostramos la lista de procesos con la orden ps.

Una vez editado el fichero tendremos que asignarle el permiso de ejecución

$ chmod u+x pruebashell
              

después asignamos un una valor a la variable VAR para comprobar como cambia. Además tendremos que exportarla par que la shell hija pueda heredarla:

$ export VAR="valor previo"
              

Ahora mostramos la lista de procesos para ver cuantas shell tenemos abiertas:

$ ps
              

o bien

$ ps |wc -l
              

y a continuación ejecutamos el guion "pruebashell":

$ ./pruebashell
              

y volvemos a mostrar el contenido de la variable:

$ echo $VAR
              

Podremos observar como aparece una shell más. Si la variable VAR está exportada veremos como muestra el valor que asignamos antes de ejecutar el guion y como muestra el que le asignamos dentro del guion. Y al final, al mostrar la variable VAR, observamos como nos muestra el valor que tenía antes de ejecutar el guion; el guion no ha modificado la variable.

Este mismo comportamiento se puede aplicar a la orden cd. Veamos el siguiente ejemplo, un simple script que cambia de directorio.

Editamos el fichero llamado "cambia" con el siguiente contenido:

echo "cambiando de directorio"
cd /tmp
echo "estamos en:"
pwd
              

Es decir, el script simplemente cambia al directorio /tmp.

Una vez editado le asignomos el permiso de ejecución

$ chmod u+x cambia
              

Ahora mostramos nuestro directorio activo

$ pwd
              

ejecutamos el script

$ ./cambia
              

y volvemos a comproba nuesto directorio activo

$ pwd
              

y observamos como estamos situados en el mismo directorio que antes de la ejecución del guion.

¿Por qué ocurre todo esto?, Porque todos los cambios se realizan en la subshell que ha interpretado el guion.