2. Estructura básica de shell-scripts. Invocación¶
En su forma más básica, un shell-script puede ser un simple fichero de texto que contenga uno o varios comandos. Para ayudar a la identificación del contenido a partir del nombre del archivo, es habitual que los shell scripts tengan la extensión «.sh», por lo que seguiremos este criterio (pero recuerde que es algo meramente informativo y opcional). Por ejemplo, el siguiente fichero sería un shell-script:
echo "Contenido carpeta personal:"
ls ~/
Tareas
Compruebe que el fichero
script.sh
tiene permisos de ejecución generales (si no los tuviese, para asignárselos bastaría ejecutarchmod +x script.sh
).Invoque el script para que sea interpretado, usando por ejemplo el comando:
cd ./script.sh
Además de comandos, los shell-scripts pueden contener otros elementos, aportados por el shell para mejorar la funcionalidad de los scripts. De forma resumida, la estructura básica de un shell-script es la siguiente:
#!/bin/dash
# Esto es un comentario y no se interpreta
echo Hola
ps w
echo "Proceso lee el script: $$"
En el anterior código, la primera línea es lo que se conoce como «shebang» y la segunda es un comentario. Como contenido del script pueden utilizarse múltiples elementos (comandos, variables, funciones, estructuras de control, comentarios,…) que se analizarán en el siguiente apartado.
El «shebang» permite especificar el intérprete de comandos con el que
deseamos que sea interpretado el resto del script cuando se usa
invocación implícita (ver más adelante). La sintaxis de esta línea es
la secuencia #!
seguida del ejecutable del shell deseado, sobre lo
que deben realizarse la siguientes advertencias:
Es imprescindible que sea la primera línea del script, ya que, en caso contrario, sería interpretado como un comentario (comienza con el carácter
#
).Puede haber espacios entre
#!
y el ejecutable del shell.El shebang no es obligatorio (cuando se usa invocación implícita, si no se indica se intentará usar el mismo tipo de shell desde el que se ha invocado el script).
Advertencia
Sintaxis estricta
La sintaxis de los shell-scripts se caracteriza por ser bastante estricta en su escritura, especialmente en lo que se refiere a la inserción u omisión de espacios en blanco entre las palabras especiales. Tenga esto muy en cuenta a la hora de escribir los scripts que se proponen.
La utilización del shebang está condicionada por la forma en que sea invocado el shell-script, existiendo 3 opciones:
Explícita: escribiendo explícitamente qué shell se desea invocar y pasando como argumento el nombre del script, cargándose en memoria un nuevo proceso para dicho shell (subshell o proceso shell hijo del shell padre responsable de la línea de comandos desde la que se ha invocado el script). En este caso se ignora el shebang.
Implícita: invocando al script como si fuera un ejecutable, lo que requiere asignar permisos de ejecución al script. Se lee el shebang para determinar qué shell deberá usarse para leer el script, cargándose en memoria un proceso hijo (subshell) para dicho shell (si el script no presenta shebang, para el subshell se utilizará el mismo tipo de shell que el encargado de la línea de comandos desde la que se ha hecho la invocación). Tenga en cuenta que los shell-scripts son ficheros de texto leídos por el intérprete de comandos, esto es, se interpretan, NO se ejecutan. La asignación del permiso de ejecución a un shell-script es una utilidad del sistema de ficheros para acelerar la invocación de scripts, pero cuyo funcionamiento interno es cargar un nuevo proceso de shell (subshell) para que éste interprete el script.
Implícita con . (equivale a importar): el script será interpretado por el mismo proceso del shell responsable de la línea de comandos desde la que se está invocando el script (luego aquí no se abre ningún subshell). Consecuentemente, en este caso también se ignora el shebang.
En los casos en los que se crean subshells, salvo que se fuerce lo
contrario (con su -c
por ejemplo), el subshell pertenecerá al mismo
usuario al que pertenecía el shell padre que lo ha creado. El usuario
al que pertenece el proceso shell que interpreta un script condiciona
las operaciones que se podrán hacer desde dentro del script (por
ejemplo, si el shell pertenece al usuario dit
, el script no podrá
modificar el fichero /etc/passwd
, mientras que si el shell pertenece
al superusuario root
, sí podrá hacerlo). Tenga en cuenta este
aspecto para determinar qué operaciones puede realizar dentro de un
script, y con qué usuario debe invocarlo.
Tareas
En una consola de comandos ejecute el comando
ps w
y localice el proceso asociado al shell responsable de la línea de comandos desde la que está trabajando.Invoque dicho script mediante los distintos métodos de invocación. Para cada uno de ellos, analice la salida obtenida para determinar en cada caso cuál es el proceso shell que está interpretando el script, el usuario al que pertenece dicho proceso y si se ha abierto un subshell o no:
Explícita:
/bin/sh script_ejemplo.sh /bin/dash script_ejemplo.sh /bin/bash script_ejemplo.sh
Implícita con
.
:. script_ejemplo.sh
Implícita: compruebe que el script tiene permiso de ejecución y ejecútelo con:
./script_ejemplo.sh
Modifique el script eliminando el shebang, y vuelva a ejecutarlo. Analice si hay alguna diferencia respecto a la ejecución anterior.
Conforme se ha indicado en la introducción, si bien tanto bash
como
dash
siguen el estándar POSIX, especialmente bash
añade múltiples
extensiones particulares, no soportadas por otros shells como dash
.
Consecuentemente, cada vez que diseñemos un script deberemos tener en
cuenta el shell o shells que lo soportan, asegurando que sea invocado
por uno de ellos. Para que se haga una idea de la importancia de este
aspecto, considere los dos scripts siguientes, basados en el uso de
la estructura for
(que se usará más adelante):
#!/bin/sh
for VAR in 0 1 2 3
do
echo $VAR
done
#!/bin/bash
for ((VAR=0 ; VAR<4 ; VAR++ ))
do
echo $VAR
done
Ambos scripts realizan la misma funcionalidad, pero
script_estandar.sh
está escrito bajo la sintaxis POSIX, mientras que
script_bash.sh
utiliza una sintaxis no estándar soportada por bash
.
Tareas
Invoque el guión
script_estandar.sh
(recuerde que debe disponer de ellos ya creados en el directorioscripts/
) mediante los siguientes comandos, debiendo comprobar que todas funcionan correctamente y con igual resultado (la primera y segunda llamada realmente son la misma, usando el shell dash):/bin/sh script_estandar.sh /bin/dash script_estandar.sh /bin/bash script_estandar.sh
Ahora invoque el guión
script_bash.sh
mediante los siguientes comandos:/bin/dash script_bash.sh /bin/bash script_bash.sh
Podrá comprobar cómo, debido a la sintaxis no estándar del script, la segunda invocación funciona, pero la primera (que emplea
dash
) da un error de sintaxis.