Introducción a la creación de shell scripts con bash | Algo de Linux

lunes, 28 de enero de 2008

Introducción a la creación de shell scripts con bash

Una de las cosas con la que trabajamos mucho los administradores linux es la programación de shell scripts, dado que éstos nos dan la posibilidad de preparar tareas que simplifican nuestro trabajo diario.

Veamos a continuación un pequeño guión introductorio sobre programación de shell scripts.

Para escribir un shell script necesitamos un editor de texto plano, como por ejemplo: nano o gedit. En realidad nos vale cualquier editor de texto, siempre y cuando el archivo lo guardemos como text/plain.


3. Uso de parámetros en scripts

Podemos usar parámetros en nuestros scripts. Dichos parámetros nos permitirán pasar valores externos que utilizaremos dentro:


$0 contiene el nombre nombre de nuestro script

$# contiene el número de parámetros con los que se ha invocado al shell

$n contiene los parámetros, con n de 1 a 9 (a $#)

{$n} cuando n > 9, tenemos qu especificar los parámetros entre llaves

$$
contiene el PID de nuestro proceso

$* todos los parámetros menos $0


6. Operadores de comparación

Podemos hacer comprobaciones sobre ficheros utilizando el comando test.

El comando test evalúa una expresión y retorna un valor que será cero si la expresión es verdadera o distinto de cero si la expresión es falsa.

Este comando tiene la siguiente sintaxis:

test expresion
[ expresion ]

donde EXPRESION puede ser una evaluación: de cadenas de caracteres, números enteros, archivos (evaluamos permisos y existencia del archivo) u operadores lógicos que permiten realizar una combinación de varias evaluaciones.

- Utilización abreviada del comando test.

En vez de escribir test EXPRESION, podemos escribir la EXPRESION entre corchetes( [ ] ) y el resultado será exactamente el mismo.

Ejemplo:

$ str="abc"
$ [ "$str" = "abc" ]
$ echo $?

Habitualmente el comando test se utiliza en conjunto con la sentencia if para evaluar distintos tipos de expresiones que veremos a continuación.


6.1. Operadores sobre ficheros

-d fichero cierto si fichero existe y es un directorio
-e fichero cierto si fichero existe, independientemente del tipo que sea
-f fichero cierto si fichero existe y es un fichero normal
-r fichero cierto si fichero existe y se puede leer
-s fichero cierto si fichero existe y tiene tamaño mayor que cero
-w fichero cierto si fichero existe y es se puede escribir sobre él
-x fichero cierto si fichero existe y es ejecutable


6.2. Operadores lógicos

! expresion   cierto si expresion es falsa (negación)
expresion1 -a expresion2 cierto si expresion1 y expresion2 son ciertas
expresion1 -o expresion2 cierto si expresion1 o expresion2 son ciertas


6.3. Operadores de comparación de números enteros

n1 -eq n2 cierto si los enteros n1 y n2 son iguales
n1 -ne n2 cierto si los enteros n1 y n2 no son iguales
n1 -gt n2 cierto si el enteros n1 es mayor que n2
n1 -ge n2 cierto si los enteros n1 y n2 son iguales o n1 es mayor que n2
n1 -lt n2 cierto si el enteros n1 es menor que n2
n1 -le n2 cierto si los enteros n1 y n2 son iguales o n1 es menor que n2


6.4. Operadores de comparación de cadenas

s1 = s2  cierto si las cadenas de texto s1 y s2 son idénticas
s1 != s2 cierto si las cadenas de texto s1 y s2 no son idénticas
s1 <> s2 cierto si la cadena de texto s1 es mayor que s2
-n cadena cierto si la longitud de la cadena de texto es distinta de cero


6.5. Operadores lógicos && y ||

Además de los anteriores, existen los operadores lógicos && (AND, multiplicación lógica) y || (OR, suma lógica), que se puede aplicar al valor de salida de los programas:

$ true && true ; echo $?
$ true && false ; echo $?
$ false && true ; echo $?
$ false && false ; echo $?

$ true || true ; echo $?
$ true || false ; echo $?
$ false || true ; echo $?
$ false || false ; echo $?

7. Sentencias de comparación

7.1. Sentencia if

Esta sentencia nos permitirá ejecutar un bloque de código, o u otro, dependiendo de como se evalue una condición.

La forma más simple tiene la siguiente sintaxis:

if CONDICION; then
bloque de comandos
fi

En este primer caso el bloque de comandos se ejecutará solo si la condición es evaluada a cierto.

Una segunda posibilidad es utilizar else:

if CONDICION; then
bloque de comandos b1
else
bloque de comandos b2
fi

En este segundo caso el bloque de comandos b1 se ejecutará si la condición es cierta. Si la condición fuera falsa, se ejecutará el bloque de comandos b2.

La condición puede ser, por ejemplo, una llamada al comando test o una operación lógica entre los valores de salida de diferentes comandos.

Ejemplo:

read numero
# comparamos cadenas de texto, así que usamos comillas
if [ $numero -eq 5 ]; then
echo Acerté tu número. Es el 5.
fi

7.2. Sentencia case

Se utiliza cuando el valor de una variable ha de ser contrastado con varios valores. Su sintaxis es la siguiente:

case variable in
patron1) comando1
comando2;;
patron2) comando3
comando4;;
....
....
esac

Comprueba si variable coincide con algunos de los patrones (patron1, patron2,...) y ejecuta los comandos asociados con la primera coincidencia que tiene lugar.

Sólo se ejecuta un único grupo de comandos.

El ";;" es el delimitador de los comandos que se ejecutaran para un determinado patrón y "esac" es el fin de la sentencia case.

Un ejemplo clásico de uso de la sentencia case es la creación de un menú:

!/bin/bash
##############################
# Genera un menú de opciones #
##############################
echo "[1] Listar archivos"
echo "[2] Ver directorio de trabajo"
echo "[3] Crear directorio"
echo "[4] Crear usuario"
read -p "Ingrese una opción: " OPCION
case $OPCION in
1) ls;;
2) pwd;;
3) read -p "Ingrese nombre del directorio a crear: " DIRECTORIO
mkdir $DIRECTORIO;;
4) if id | grep uid=0
then
read -p "Ingrese el nombre del usuario a crear: " NOMBREUSUARIO
useradd $NOMBREUSUARIO
else
echo "Se necesitan permisos de root"
fi;;
*) echo "Opción ingresada no valida, intentelo de nuevo"
exit 1;;
esac

8. Bucles

El shell nos aporta mecanismos para realizar tareas repetitivas mediante el empleo de estructuras que permiten repetir un bloque de comandos.

8.2. El bucle while

Es otra estructura de bucle que permite ejecutar un bloque de comandos mientras se evalúe una condición a cierto:

while CONDICION; do
bloque de comandos
done

Cada iteración se evalua la condición y en el momento que no sea cierta, el bucle termina.

Ejemplos de bucles:

# equivalente a seq 1 5
i=1
while [ $i -le 10 ]; do
echo $i
i=$(($i+1))
done

# leemos de stdin hasta que se introduzca la palabra 'salir'
read linea

while [ $linea != "salir" ]; do
read linea
done

9. Funciones

Una función o subrutina es una agrupación de comandos bajo un mismo nombre. Lo que nos permitirá dividir el programa en bloques y programar cada bloque por separado, o agrupar una serie de comandos que se ejecutan a menudo bajo un mismo nombre.

Veamos cuál es la sintaxis de una función:
nombre_funcion()
{
comando1
comando2
...
...
}

Luego, para ejecutar la función debemos llamarla por su nombre, igual que un comando:

...
nombre_funcion
...

Eso sí, debemos tener en cuenta que es necesario definir cada función antes de utilizarla. Veamos un ejemplo:

mostrar_menu ()
{
echo -e "\n"
echo "[1] Crear usuario"
echo -e "[2] Salir\n"
read -p "Elija una opción: " OPCION
}

crear_usuario ()
{
if [ id | grep uid=0 ]; then
read -p "Nombre del usuario a crear: " NOMBREUSUARIO
useradd $NOMBREUSUARIO
else
echo '*****************************'
echo "Se necesitan permisos de root"
echo '*****************************'
fi
}
############# Programa principal #################
while true; do
mostrar_menu
case $OPCION in
1) crear_usuario ;;
2) echo "Abandonando el programa..."
break;;
*) echo '********************************************'
echo "Opción ingresada no valida, intente de nuevo"
echo '********************************************';;
esac
done

No hay comentarios: