Estructura de control

La programación en shell dispone de las sentencias de control del flujo de instrucciones necesarias para poder controlar perfectamente la ejecución de las órdenes necesrias.

Sentencia if

La shell dispone de la sentencia if de bifurcación del flujo de ejecución de un programa similar a cualquier otro lenguaje de programación. La forma más simple de esta sentencia es:

if   lista_órdenes
then
   lista_órdenes
fi
              

fi, que es if alrevés, indica donde termina el if.

En la parte reservada para la condición de la sentencia if, aparece una lista de órdenes separados por ";". Cada uno de estos mandatos es ejecutado en el orden en el que aparecen. La condición para evaluar por if tomará el valor de salida del último mandato ejecutado. Si la última orden ha terminado correctamente, sin condición de error, se ejecutará la lista de órdenes que hay tras then. Si esta órden ha fallado debido a un error, la ejecución continúa tras el if.

Como condición se puede poner cualquier mandato que interese, pero lo más habitual es utilizar diferentes formas de la orden test. Por ejemplo:

if [ -f mifichero ] 
then 
echo "mifichero existe"
fi
Pero también podemos poner:
if grep body index.html
then
echo "he encontrado la cadena body en index.html"
fi
              

Como en cualquier lenguaje de programación también podemos definir las acciones que se tieenen que ejecutar en el caso de que la condición resulte falsa:

if lista_órdenes
then
        lista_órdenes
else
        lista_órdenes
fi
              

Por ejemplo:

if [ -f "$1" ] then
pr $1
else
echo "$1 no es un fichero regular"
fi
              

Cuando queremos comprobar una condición cuando entramos en el else, es decir, si tenemos else if es posible utilizar elif. Vemos un ejemplo:

if [ -f "$1" ]
then
cat $1 
elif [ -d "$1" ] 
then
ls $1/*
else
echo "$1 no es ni fichero ni directorio"
fi
              

Sentencia while

La sentencia while tiene la siguiente sintaxis:

while lista_órdenes
do
lista órdenes
done
              

La lista de órdenes que se especifican en el interior del bucle while se ejecutará mientras que lista_órdenes devuelva un valor verdadero, lo que significa que la última orden de esta lista termina correctamente.

Vemos un ejemplo:

I=0
while [ ${resp:=s} = s ]
do
I=\`{ }expr $I + 1\`{ }
echo $I
read resp?"Quiere usted continuar(s/n)? "
done
              

Sentencia until

La sentencia until similar a while, es otro bucle que se ejecutará hasta que se cumpla la condición, es decir, hasta que la lista de órdenes termina correctamente. Su formato es el siguiente:

until lista_órdenes
do
lista órdenes
done
              

Sentencia for

La sentencia for repite una serie de órdenes a la vez que una variable de control va tomando los sucesivos valores indicado por una lista de cadenas de texto. Para cada iteración la variable de control toma el valor de uno de los elementos de la lista. La sintaxis de for es la siguientes

for variabl in lista 
do
lista mandatos
done
              

lista es una serie de cadenas de texto separadas por espacios y tabuladores. En cada iteración del bucle la variable de control variable toma el valor del siguiente campo y se ejecuta la secuencia de mandatos lista_mandatos.

Ejemplo:

for i in $*
do 
echo $i
done
              

y mostraríamos todos los parámetros posicionales.

for i in *
do 
echo $i
done
              

y mostraríamos la lista de ficheros del directorio activo.

Sentencias break y continue

La sentencia break se utiliza para terminar la ejecución de un bucle while o for. Es decir el control continuará por la siguiente instrucción del bucle. Si existen varios bucles anidados, break terminará la ejecución del último que se ha abierto.

Es posible salir de n niveles de bucle mediante la instrucción break n.

La instrucción continue reinicia el bucle con la próxima iteración dejando de ejecutar cualquier orden posterior en la iteración en curso.

Sentencia case

La sentencia case proporciona un if múltiple similar a la sentencia switch de C. El formato básico de esta sentencia es el siguiente:

case variable in 
patrón1)
 lista_órdenes1
;; 
patrón2) 
lista_órdenes2
;;
...
patrónN) 
lista_órdenesN;;
esac
              

La shell comprueba si variable coincide con alguno de los patrones especificados. La comprobación se realiza en orden, es decir empezando por patrón1 terminando por patrónN. En el momento en que se detecte que la cadena cumple algún patrón, se ejecutará la secuencia de mandatos correspondiente hasta llegar a ";;". Estos dos puntos y comas fuerzan a salir de la sentencia case y a continuar por la siguiente sentencia después de esac (esac es case alrevés).

Las reglas para componer patrones son las mismas que para formar nombres de ficheros, así por ejemplo, el carácter "*" es cumplido por cualquier cadena, por lo que suele colocarse este patrón en el último lugar, actuando como acción predeterminada para el caso de que no se cumpla ninguna de las anteriores. Ejemplo:

case "$1" in
  start)
        echo -n "Ha seleccionado start "
        ;;
  stop)
        echo -n "Ha seleccionado stop "
        ;;
  status)
        echo -n "Ha seleccionado stop "
        ;;
  restart)
        echo -n " Ha seleccionado restart "
        ;;
  *)
        echo "No es una opción válida"
        exit 1
esac