Inicio wiki
Aula Virtual
 Administración de Sistemas Operativos
Inicio ASO Aula Virtual

Vistas
  •   5. Programación shell
De ASO

El shell es un intérprete de comandos que permite al administrador ejecutar determinadas tareas. Pero el shell no es únicamente eso, ya que los intérpretes de comandos son un auténtico lenguaje de programación que le permite al administrador automatizar y programar tareas. Como cualquier lenguaje de programación, el shell de GNU/Linux, incorpora sentencias de control de flujo, sentencias de asignación, funciones, etc.

Los programas de shell no necesitan ser compliados, como ocurre en otros lenguajes, y son ejecutados línea a línea por lo que a estos programas se les conoce con el nombre de shell script.

Desde que en los años 70 se desarrollara UNIX, se han incluido con él varias variantes del lenguaje de shell. El más popular y común es el Bourne Shell, por su creador. En las variantes de UNIX de BSD se incluyó el C-Shell, una variante con sintaxis más parecida a C que el Bourne. También, el Korn shell incluyó funciones para controlar los trabajos en segundo plano, etc.

En el caso de Linux, se inlcuye el Bash (Bourne-again shell), que aglutina características de todas las variantes, pero que sigue la filosofía del Bourne. Se utilizará este intérprete por ser el que viene por defecto.

A continuación se va a realizar un pequeño resumen de programación en shell script para que puedas realizar tus propios scripts para automatizar las tareas del servidor.


Contenido

Mi primer script "Hola mundo"

A continuación se muestra la estructura de un shell scripto básico

#! /bin/bash
# inicio del script
echo "hola mundo"
#fin del script

En el anterior escript la primera línea #!/bin/bash se utiliza para establecer el intérprete de comandos /bin/bash. Las demás lineas que empiezan por # son comentarios y el shell las omite. Y la línea echo "hola mundo" muestra en pantalla la frase hola mundo.

Para poder ejecutar el script debemos guardarlo en un fichero (p.e. mi_primer_script.sh), asignarle permisos de ejecución

chmod +x mi_primer_script.sh

y ejecutarlo

./mi_primer_script.sh


Conceptos básicos

Variables

Como en cualquier lenguaje de programación, las variables se utilizan para poder guardar información y a partir de ella poder tomar decisiones o realizar operaciones. Lógicamente, las variables no pueden tener el nombre de ninguna variable reservada (p.e echo) y hay dos formas diferentes de utilizarla despendiendo de si queremos asignarle un valor o operar con ellas. A continuación vamos a ver un ejemplo en el que se le asigna a la variable numero un valor y luego se muestra por pantalla.

#!/bin/bash
numero=5
echo "el valor de la variable es"$numero

Como se puede ver en el ejemplo cuando se quiere acceder al valor de la variable se utiliza el símbolo $.


Paso por parámetros

A menudo es necesario que nuestros scripts reciban parámetros desde la línea de comandos para hacerlos más versátiles. Los parámetros se pueden usar dentro del script como cualquier otra variable de shell.

Los parámetros dentro del shell script son accesibles utilizando las variables:

$0 es el nombre del programa
$1 Primer parámetro
$2 Segundo prámetro
...

Además, se utiliza la variable $# que establece el número de parámetros que ha recibido el shell. A continuación vamos a ver un ejemplo:

#!/bin/bash
echo "El nombre del programa es "$0
echo "El primer parámetro recibido es "$1
echo "El segundo parámetro recibido es "$2
echo "..."
echo "En total se han recibido "$#" parámetros"

Entrada y salida de datos

E/S por consola

Como ya hemos visto antes, la salida de datos se realiza con el comando echo y la entrada de datos, además de poder realizarla con el paso de parámetros se realiza con el comando read. A continuación se muestra un ejemplo:

#!/bin/bash
echo -n "Introduce el valor de la variable"
#el parámetro -n se utiliza para evitar el salto de línea
read numero
echo "El valor introducido es: "$numero

Si queremos leer directamente varios valores se puede realizar de dos formas:

read numero1
read numero2
read numero3

o

read numero1,numero2,numero3

Además, la entrada y salida de datos se puede realizar a través de ficheros o del resultado de la ejecución de un comando, pero eso lo veremos más adelante


Redirección E/S

Cuando se ejecuta un programa en Linux se abre automáticamente tres archivos (flujos) de E/S para ellos. Estos son: la entrada estándar, la salida estándar y el error estándar. Aunque parezca confuso todos los sistemas UNIX utilizan este sistema, basado en el manejo de archivos. Por ejemplo, si deseas enviar datos a tu disco extraible debes enviar los datos al archivo asociado con dicho pendrive, por lo general /dev/sda1.

Por defecto la salida estándar está conectada a la pantalla, la entrada de estándar al teclado, y el error estándar a la pantalla. Es posible reasignar estos destinos antes de ejecutar el programa, en lo que se conoce como redirección de E/S. Supongamos que queremos crear una lista de archivos de configuración (*.conf) del directorio /etc. Una forma sencilla de hacer esto sería:

grep /etc/*.conf > ListaArchivos.txt

o lo que es lo mismo

less ListaArchivos.txt | grep /etc/*.conf 

En ambos casos grep realiza un listado de los archivos de la carpeta /etc cuya extensión sea *.conf. El carácter > es el que indica la redirección de salida; esto ocasiona que el shell redireccione la salida estándar a el archivo ListaArchivos.txt

Si por el contrario quiero que un determinado utilice el contenido de un fichero utilizo el carácter "<". Por ejemplo

grep host <ListaArchivos.txt

muestra las líneas de texto del fichero ListaArchivos.txt que contienen la palabra host.

Filtrado de textos

Para empezar debemos conocer los comandos que nos permiten mostrar el contenido de un fichero. Los comandos más utilizados son: less y more. Por ejemplo, para mostrar el contenido del fichero /etc/passwd podemos ejecutar: less /etc/passwd Para filtrar la salida podemos hacerlo de las siguientes formas:

  • Mostrar las líneas que cumplen una determinada condición (grep)
  • Mostrar las n primeras líneas (head) o las n últimas líneas (tail).
  • Mostrar una determinada columna (cut)
  • Además, podemos ordenar la salida utilizando el comando sort.

A continuación vamos a ver cada uno de los comandos:

grep

El comando grep nos permite filtrar la salida para que se muestren las líneas que cumplen una determinada condición. La sintaxis es:

grep [expresión regular o palabra]

Por ejemplo, si queremos mostrar las lineas del fichero /etc/passwd que contienen la palabra root ejecutaremos:

less /etc/passwd | grep root


head y tail

El comando head muestra las primeras n líneas de un fichero mientras que el comando tail muestra las últimas n últimas líneas del fichero. Ambos comandos tienen la misma sintaxis:

head -n num_lineas
tail -n num_lineas

Por ejemplo, si queremos motrar las primeras 5 líneas del fichero /etc/passwd ejecutaremos:

less /etc/passwd | head -n 5

Y para ver las últimas 5 líneas ejecutaremos:

less /etc/passwd | tail -n 5


cut

El comando cut permite obtener de una salida unas determinadas columnas de datos. Su sintaxis es:

cut –d “delimitador” -f filas

donde delimitador es el carácter que separa los datos entre filas y filas son los números de filas que queremos mostrar. Podemos mostrar una fila (p.e. ¬-f2) o varias filas (p.e. -f2,3). Por ejemplo, para obtener el nombre de todos los usuarios del sistema deberemos obtener la primera fila del fichero /etc/passwd cuyo delimitador es el carácter “:”. Por lo tanto, ejecutaremos:

less /etc/passwd | cut -d ":" –f1


sort

El comando sort permite ordenar una salida de datos. Por ejemplo, siguiente el ejemplo anterior, podemos ordenar los nombres de usuario del equipo.

less /etc/passwd | cut -d ":" –f1 | sort

El caso de estar ordenando valores númericos deremos poner el operador –n. Por ejemplo, si queremos ordenar los identificadors de los usuarios del sistema deberemos ejecutar:

less /etc/passwd | cut -d ":" –f3 | sort -n


Operaciones aritmético y lógicas

Como cualquier lenguaje de programación se pueden realizar operaciones aritmético y lógicas sobre las variables.

Para realizar operaciones se utiliza el comando 'expr' y para realizar comparaciones se utiliza el comando 'test'. A continuación vamos a ver a fondo cada uno de los comandos.

expr

El comando 'expr' se utiliza principalmente para realizar operaciones de aritmética simple y, en menor medida para manipular cadenas. La sintaxis de 'expr' es:

expr arg1 op arg2 [op arg3...]

Los 'operadores aritméticos' que se pueden realizar son:

  • + Suma
  • - Resta
  • \* Multiplación
  • / División
  •  % Resto de la división

El operador * va predecidido de \ porque * ya tiene un significado en GNU/Linux

Veamos un ejemplo:

#!/bin/bash
echo -n "Introduce un valor"
read var1
echo -n "Introduce un valor"
read var2
resultado='epr $var1 \* $var2'
echo "El resultado de la multiplicación es "$resultado


Los 'operadores relacionales' se utilizan para comparar dos argumentos y son los siguientes:

  • = igualdad
  •  != diferentes
  • > Mayor
  • >= Mayor o igual
  • < Menor
  • < Menor o igual

Veamos un ejemplo:

#!/bin/bash
echo -n "Introduce un valor"
read var1
echo -n "Introduce un valor"
read var2
resultado='epr $var1 = $var2'
echo "El resultado es "$resultado


Y finalmente, los 'operadores lógicos' que se pueden utilizar son:

  • | Or lógico
  • & And lógico


Otra funcionalidad adicional de la función expr y que resulta muy interesante a la hora de programa es la generación de números aleatorios. A continuación podemos ver un ejemplo:

#/bin/bash
numero=`expr $RANDOM % 5`
echo $numero

test

El comando 'test' permite evaluar tres tipos de elementos: archivos, cadenas y números. Su sintaxis es:

test - opcion archivo
test [expresión]

Las opciones para 'evaluar archivos' o directorios son las siguientes:

  • -f Devuelve verdadero (0) si el archivo existe y es un archivo regular (no es un directorio ni un archivo de dispositivo)
  • -s Devuelve verdadero (0) si el archivo existe y si su tamaño es mayor que 0.
  • -r Devuelve verdadero (0) si el archivo existe y tiene permisos de lectura.
  • -w Devuelve verdadero (0) si el archivo existe y tiene permisos de escritura.
  • -x Devuelve verdadero (0) si el archivo existe y tiene permisos de ejecución.
  • -d Devuelve verdadero (0) si existe y es un directorio.

Ejemplo:

test -f /etc/passwd
test -d /datos

Para 'evaluar cadenas' se utiliza la siguiente sintaxis:

test [cadena1 = cadena2]
test [cadena1 != cadena2] 

Y finalmente, también se utiliza para 'evaluar números'. Su sintaxis es:

test número operador número

Las evaluaciones numéricas son sólo válidas para números enteros y los operadores existentes son:

  • -lt Menor que
  • -le Menor o igual que
  • -qt Mayor que
  • -qe Menor o igual que
  • -eq Igual a
  • -ne No igual a

Veamos un ejemplo:

#!/bin/bash
echo -n "Introduce un valor"
read var1
echo -n "Introduce un valor"
read var2
resultado='test $var1 -lt $var2'
echo "El resultado es "$resultado


Además se pueden utilizar los conectores:

  • -o OR
  • -a AND
  •  ! NOT


Flujo de datos

Condicionales (if)

La sintaxis de las sentencias if es:

if condicion
then
      comandos
else
      comandos
fi

A continuación podemos ver un ejemplo

#!/bin/bash
echo -n "Introduce un valor"
read var1
if (test $var1 -qt 10)
then
   echo "Es mayor que 10"
else
   echo "Es menor que 10"
fi


Condiciones múltiples(Case)

Cuando queremos realizar muchas condiciones sobre un mismo valor (p.e. en un menú) la mejor opción es utilizar un Switch. Su estructura es:

case  $variable-name  in
   valor1)   command
             ...
             ..
             command;;
   valor2)   command
             ...
             ..
             command;;
   valorN)   command
             ...
             ..
             command;;

   *)   command
             ...
             ..
             command;;
esac

A continuación se puede ver un ejemplo sencillo:

#!/bin/bash
echo -n "Introduce un valor: "
read var1
case $var1 in
 1) echo " uno ";;
 2) echo " dos ";;
 3) echo " tres ";;
 4) echo " cuatro ";;
 *) echo "opcion incorrecta ";;
esac

Bucle for

El bluce for se utiliza para ejecutar un código un determinado número de veces. Su sintaxis es:

for (( expr1; expr2; expr3 )) do
   ...
Done

A continuación podemos ver un ejemplo que muestra los números del 0 al 5:

#!/bin/bash
for ((  i = 0 ;  i <= 5;  i++  ))
do
  echo " $i "
done

tambien se puede utilizar el for para moverse en una lista de elementos

for variabe in lista_elementos
do
  echo " $variable "
done


Bucle while

El bluce while permite ejecutar un código hasta que no se cumpla una determianda condición de salida. Su sintaxis es:

while [ condition ]
do
    comando1
    comando2
    comando3
    ...
done

A continuación podemos ver un ejemplo muy sencillo:

#/bin/bash
limite=5
i=0;

while (test $limite -gt $i)
do
    echo Acci�n $i ejecutada
    let i=$i+1
done


URLs de interés

A continuación de muestra un listado de páginas donde puede profundizar más sobre la utilización de shell script:



Libro Recomendado

ADMINISTRACION AVANZADA DE SISTEMAS INFORMATICOS
Ver fichaVer ficha
Comprar libroComprar