Vous êtes sur la page 1sur 40

UD4: Programacin de scripts en GNU/Linux

IMPLANTACIN DE SISTEMAS OPERATIVOS

1 Introduccin: shell como lenguaje de


scripting
Un Shell es un interfaz que permite a
los usuarios interactuar con el Sistema
Operativo.
No se considera una aplicacin debido a
su innegable naturaleza, pero es como
cualquier otro proceso en ejecucin del
sistema. La diferencia entre uno y otro
es que el propsito del Shell es permitir
a los usuarios la ejecucin de otras
aplicaciones.
En algunos S.O. (UNIX, LinuX, VMS), el
Shell es un interfaz de lnea de
comandos (CLI), en otros (Windows,
MAC OS) es un interfaz grfico (GUI).
Aunque actualmente la mayora de los
sistemas operativos proporcionan tanto
una shell basada en lnea de comandos
como en entorno grfico.

1.2 Tipos de shells


Si nos ceimos a los sistemas operativos ms conocidos hoy en da, podemos
indicar los siguientes intrpretes shell.
GNU/Linux:
Tenemos diversos intrpretes (slo los ms utilizados en GNU/Linux): sh
(Bourne shell), bash (Bourne-Again shell), ksh (Korn shell) y zsh (Z shell).
En Wikipedia podemos tener un punto de partida bastante interesante para
conocer ms los distintos shells que tiene cualquier distribucin de
GNU/Linux. Shells en cualquier distribucin GNU/Linux.
Windows:
Bsicamente tenemos dos: cmd y powershell.
Cmd es el ms conocido y puede interpretar scripts o guiones realizados en
ficheros Batch (extensin BAT), Visual Basic Scripts (extensin VBS); ambos
son los ms conocidos.
PowerShell: Microsoft ha creado, a partir de Windows Vista, Powershell
como intrprete de comandos. Mucho ms potente y con una herramienta de
edicin y depurador incluidos.

1.3 Estructura del lenguaje


El intrprete de comandos o "shell" es tambin un lenguaje de programacin
completo. La programacin de shell se usa mucho para realizar tareas
repetidas con frecuencia y que no requieren programas complejos. Los
administradores de sistemas suelen escribir programas o aplicaciones en el
lenguaje de base del sistema operativo por razones de rapidez y eficiencia.
Como todo lenguaje, debe cumplir con unos requisitos tales como emplear la
sintaxis correcta, que no tenga errores, no slo sintcticos sino tambin
lgicos.
Ese tipo de lenguaje de programacin consta de rdenes. rdenes que,
generalmente, podremos usar directamente en un entorno tipo terminal. Y
aparte de estas rdenes, disponemos de instrucciones con una estructura
que nos permite jugar con las rdenes del sistema.
Ejemplo de script:
clear
echo Hola Mundo!

1.4 Variables de entorno y paso por


parmetros
No debemos olvidar que, para interactuar ms eficientemente con el sistema
operativo, debemos tener un sistema cmodo para comunicarnos ms
fiablemente y conseguir que esas rutinas que implementamos sean lo ms
eficientes posibles. Esto lo conseguimos, por ejemplo, con la utilizacin de las
variables de entorno.
Sabemos que todo lenguaje de programacin tiene distintas maneras de
guardar informacin o datos a medida que se va generando. Los datos en
memoria se almacenan en variables. Estas variables pueden generarse en el
propio programa o bien pueden pasarse como parmetros al programa.
El scripting puede utilizar las variables de entorno que usa el sistema
operativo.
En Debian GNU/Linux podemos leer las variables de entorno con el comando
env.
echo $PATH #extrae todos los caminos de bsqueda por defecto
export PATH=$PATH:/home/usuario/bin #aade el directorio al path

2 Creacin de un script
Cmo crearemos un programa de scripting en GNU/Linux? Bien, para realizar
un programa interpretado no necesitamos grandes herramientas de diseo.
En GNU/Linux podemos usar herramientas de procesador de textos como
nano, vi o herramientas grficas como gedit.
En GNU/Linux no se requiere extensin en el nombre del fichero pero suele
utilizarse una extensin ms bien por reconocimiento a simple vista ms que
como imprescindible. La extensin que suele utilizarse es ".sh". Por ejemplo
"direccionar.sh".
Ejemplo de script:
Un ejemplo de script muy simple, que muestra por pantalla la fecha, el
intrprete de comando activo, el directorio HOME y visualiza el contenido del
directorio actual, todo ello secuencialmente, sera el siguiente:
date
echo $SHELL $HOME
ls

2.1 Insercin de comentarios


Todo buen programador debe ser cuidadoso y aadir comentarios a sus
programas; as, en el caso de que otra persona (o incluso el autor) deba
utilizarlos tendr informacin ms detallada de lo que hace el programa, y las
modificaciones sern ms fciles de realizar.
Para aadir comentarios a un script se utiliza el carcter #, que se coloca
delante del texto que se desee comentar y afecta hasta el final de la lnea.
Existe un comentario especial llamado shebang que indica el camino y el tipo
de shell que tiene que interpretar el script. Este comentario debe colocarse
en la fila 1 y en la columna 1 del script, comienza con los caracteres #! y
contina con el camino de la shell que va a ejecutar el programa.
#!/bin/sh
# Este script muestra por pantalla:
# la fecha, el interprete de comando activo,
# el directorio HOME y visualiza el contenido
# del directorio actual.
date
echo $SHELL $HOME; ls

2.2 Ejecucin de un script


El primer mtodo consiste en invocar a un intrprete de comandos y pasarle
como parmetro el script que se desea ejecutar:
$ /bin/sh mi_primer_script

El segundo mtodo implica el cambio de permisos al fichero que contiene el


script. Se le deben dar permisos de ejecucin mediante el comando chmod.
Una vez cambiados los permisos, se puede teclear el nombre del programa en
la lnea de comandos sin ningn problema.
$ chmod u+x mi_primer_script
$ ./mi_primer_script

Tambin podemos copiar el script a una ruta especial que permita invocarlo
fcilmente. Por ejemplo, podemos copiarlo en /usr/sbin y ejecutarlo desde
cualquier parte sin incluir la ruta completa donde se encuentre:
# cp miscript.sh /usr/sbin/miscript

2.3 Depuracin de un script


La salida de un script aporta muy poca informacin del camino seguido por el
flujo del proceso, es decir, los comandos han sido ejecutados. No obstante, si
ejecuta con la opcin de depuracin, la cantidad de informacin es mayor y
permite ver rpidamente la instruccin donde se ha producido el error.

Opciones de depuracin:

La opcin -x del comando sh lista los comandos y sus argumentos que


son ejecutados. As puedes ver qu partes del script se han ejecutado
cuando ocurre el error.
La opcin -n del comando sh hace que no se ejecute ningn comando,
solo chequea la sintaxis.
La opcin -e en modo no interactivo, hace que si un comando falla se
termine inmediatamente el script.
La opcin -v imprime las lneas de entrada segn son ledas..

2.4 Utilizacin de parmetros


Los shell scripts pueden recibir argumentos desde la lnea de comandos, que
se denominan parmetros posicionales. Para hacer referencia a un parmetro
dentro de un script se utiliza el carcter $ (el utilizado para las variables)
seguido por un nmero indicando la posicin del parmetro en la lnea de
comandos. El parmetro $0 es el nombre del script, el $1 el primer argumento,
el $2 es el segundo argumento, etc.
Otras variables son $#, $*, $@ y $?:

$# va a almacenar el nmero de argumentos que recibe el script, sin


contar con su nombre.

$* almacena el nombre de todos los argumentos pasados, excepto el de


$0.

$? Contiene el cdigo de retorno del ltimo mandato ejecutado en el


script. Si el mandato se ha ejecutado correctamente devolver un 0, en
caso contrario el valor ser distinto a 0.

Ejemplo de utilizacin de parmetros:

#!/bin/sh
#Fichero: Ej01-param_1.sh
#Versin: 13/05/2006
#Ejemplo de utilizacin de parametros
posicionales
#Ejecucion de ejemplo: sh parametros.sh
uno dos tres
echo $#
echo $*
echo $0
echo $1
echo $2
echo $3
echo $4

2.5 Utilizacin de variables


En los scripts se pueden utilizar variables para almacenar informacin temporal. Los
parmetros posicionales vistos anteriormente son un tipo especial de variable. Todas
las variables tienen un nombre o identificador. Las variables son creadas en scripts,
especificando su identificador, seguido del carcter = y del valor asociado al
identificador, que debe ser una cadena de caracteres. Si la cadena de caracteres
contiene espacios, sta debe estar encerrada entre comillas.
Ejemplo:

#!/bin/sh
# Fichero: variables.sh
# Ejemplo de utilizacin de variables
# Ejecucion de ejemplo: sh variables.sh
nombre=Juan;apellidos="Lozano Rubio"
nombre_y_apellidos=$nombre" "$apellidos
echo $apellidos; echo $nombre_y_apellidos

2.6 Introduccin de variables desde teclado


Podemos utilizar el comando read para leer variables desde teclado y el
comando echo para visualizar su contenido.
Ejemplo:

#!/bin/sh
# Fichero: readvariables.sh
# Ejemplo de utilizacin de variables
# Ejecucion de ejemplo: sh readvariables.sh
echo Indique su nombre y sus dos apellidos
read nombre apellido1 apellido2
echo Hola $nombre $apellido1 $apellido2, Cmo estas?

2.7 Expresiones aritmticas


Las variables en el Shell son por defecto alfanumricas. Para darles
tratamiento numrico debemos recurrir al comando expr que evala
expresiones aritmticas. Este comando acepta como entrada los argumentos
dados en la forma de expresin numrica, los evala e imprime el resultado
en la salida estndar. Cada trmino de la expresin debe ir separado por
espacios en blanco. Soporta las siguientes operaciones:
+ -> suma
- -> resta
Ejemplo:
\* -> producto.
$ expr 3 + 4
/ -> divisin
7
% -> resto
$ expr 5 \* 2
10
$ expr 7 / 2
3
$ a= 3
$ a= `expr $a +2`
$ echo $a
5

2.8 Uso de comillas


Existen tres tipos diferentes de entrecomillados soportados por la shell:
Comillas simples ( ): El contenido es un literal y no es interpretado por la shell de
ninguna forma.
Comillas dobles ( ): El contenido es interpretado por la shell. Las variables son
expandidas.
Comillas simples invertidas ( ` ): El contenido es evaluado, y el resultado es
sustituido por las comillas.
#!/bin/bash
# Ejemplo de uso de diferentes comillas y variables
# Uso: 12diferentescomillas.sh /home
# Comillas simples ('):El contenido es un literal y no lo interpreta la shell
# Comillas dobles ("):El contenido es interpretado y las variables expandidas
# Comillas simples invertidas (`): Contenido evaluado y se sustituye
# el resultado por las comillas
directorio=$1
var1='ls $directorio'
var2="ls $directorio"
var3=`ls $directorio`
clear
echo $var1
echo $var2
echo $var3

2.9 Expresiones condicionales


Las expresiones condicionales son evaluadas por la shell utilizando el
comando test. ste comando puede comparar enteros y cadenas de
caracteres, as como chequear la existencia de ficheros, directorios y permisos
de acceso a ficheros. Se pueden agrupar las condiciones que van a ser
evaluadas mediante los operadores lgicos.
Si la expresin (expr) es verdadera, test devuelve un cero. Si la expresin
evaluada es falsa, devuelve un valor distinto de cero.
La sintaxis es:
test expr

Ejemplo:

#!/bin/sh
# Fichero: expresiones.sh
# Ejemplo de utilizacin de expresiones
# Se chequea que se pasen tres parmetros al script y en caso
# de que no sean tres, el programa finaliza su ejecucin.
# Ejecucin: sh expresiones.sh uno dos tres cuatro
if test $# -ne 3
then
echo Numero de parametros incorrectos
exit
fi
echo $1 $2 $3

Comparaciones numricas:
test
test
test
test
test
test

n1
n1
n1
n1
n1
n1

eq
ne
ge
gt
le
lt

n2
n2
n2
n2
n2
n2

-> verdadero si son iguales


-> verdadero si son distintos
-> verdadero si n1 es mayor o igual que n2
-> verdadero si n1 es mayor que n2
-> verdadero si n1 es menor o igual que n2
-> verdadero si n1 es menor que n2

Comparaciones de cadena de caracteres:


test
test
test
test
test

cadena1 == cadena2 -> Verdad si las cadenas son iguales. Tb (=)


cadena1 != cadena2 -> Verdad si las cadenas no son iguales.
cadena1 -> Verdadero si cadena1 no es la cadena nula.
-n cadena -> Verdadero si longitud de cadena distinta 0
-z cadena -> Verdadero si longitud de cadena es 0

Ejemplo:

cadena1=linux
cadena2=windows
if test -n cadena1 Si la longitud de la cadena es distinta de 0
if test cadena1 = cadena2 Si las cadenas cadena1 y cadena2 son iguales

2.10 Condicionales para ficheros y


directorios

test -e fichero -> Verdad si fichero existe.

test -f fichero -> Verdad si fichero existe y es un fichero regular (fichero normal, que no
es directorio, dispositivos, etc.).

test -r fichero -> Verdad si fichero existe y se puede leer.

test -w fichero -> Verdad si fichero existe y se puede modificar.

test -x fichero -> Verdad si fichero existe y es ejecutable.

test -d fichero -> Verdad si fichero existe y es un directorio.

test -s fichero -> Verdad si fichero existe y tiene un tamao mayor que cero.

test -b fichero -> Verdad si fichero existe y es un fichero especial de bloques.

test -c fichero -> Verdad si fichero existe y es un fichero especial de caracteres.

test -L fichero -> Verdad si fichero existe y es un enlace simblico o blando.

test fichero1 -nt fichero2 -> Verdad si fichero1 es ms reciente (segn la fecha de
modificacin) que fichero2.

test fichero1 -ot fichero2 -> Verdad si fichero1 es ms antiguo que fichero2.

test fichero1 -ef fichero2

-> Verdad si fichero1 y fichero2 estn en el mismo

dispositivo y tienen los mismos inodos

2.11 Operadores lgicos


Las condiciones pueden agruparse con los operadores lgicos OR, AND y
NOT. Se utilizan de la siguiente forma:

expr1 o expr2 -> OR verdad cuando al menos una de las condiciones sea
cierta.
expr1 a expr2 -> AND verdad cuando todas las condiciones sean ciertas.
! expresion -> NOT verdadero si expresion no es cierta.

3 Sentencias y operadores condicionales


Las sentencias condicionales permiten ejecutar un conjunto de comandos o
no, en funcin del valor de una expresin condicional. Los tipos de sentencias
y operadores condicionales que proporciona la shell son:

La sentencia if
La sentencia case
El operador &&
El operador ||

3.1 Sentencia if
Su sintaxis posee tres posibles variaciones:

1 forma:
if condicion
then
Comandos a ejecutar
fi
2 forma:
if condicion
then
comandos si la condicin se cumple
else
comandos si la condicin no se cumple
fi

3 forma:

if condicion1
then
comandos si la condicin1 se cumple
elif condicion2
then
comandos si la condicin2 se cumple
else
comandos si las condiciones 1 y 2 no se cumplen
fi

Y la sentencia if en una solo lnea:


if condicin; then mandato; mandato; mandato;else mandato; mandato; fi

Ejemplo:
#!/bin/sh
# Fichero: sentenciasconif.sh
# Ejemplo de ejecucin de script con sentencias if
# Ejecucin: sh sentenciasconif.sh
echo Introduce numero1
read n1
echo Introduce numero2
read n2
if test $n1 gt $n2
then
echo El numero $n1 es mayor que $n2
elif test $n2 gt $n1
then
echo El nmero $n2 es mayor que $n1
else
echo Los nmeros $n1 y $n2 son iguales
fi

3.2 Sentencia case


La sentencia case se utiliza para comparar una variable frente a una serie de posibles
valores. La sintaxis es:
case variable in
patron1) comandos condicion1;;
patron2) comandos condicion2;;
...
patron n) comandos condicion n;;
*) comandos si no se cumplen ninguna;;
esac
Ejemplo:
echo -n "Introduzca el nombre de un animal: "
read animal
echo -n "Un $animal tiene "
case $animal in
caballo | perro | gato) echo -n "cuatro";;
hombre | mono | pato) echo -n "dos";;
*) echo -n "un numero desconocido de";;
esac
echo " patas."

Ejemplo:
#!/bin/sh
# Fichero: menu_case.sh
# Versin: 13/05/2006
# Ejemplo de utilizacin de la sentencia case
# Elimina recursivamente con confirmacin.
echo Este script borra recursivamente.
echo todos los ficheros a partir del directorio actual.
echo Desea realizar la operacin?
read option
case $option in
[Ss]*) rm r * ;;
[Nn]*) echo La operacin no se realizara;;
*) echo Respuesta incorrecta. La operacin no se realizar;;
esac

3.3 Operador &&


El operador && se utiliza para ejecutar un comando y si no es errneo se ejecuta el
siguiente comando de la lista. Por ejemplo, si tenemos:
comando1 && comando2
Primero se ejecutar comando1 y si no se han producido errores se ejecutara el
comando2. El operador es equivalente a la siguiente estructura.
if comando1
then
comando2
fi
Ejemplo:
#!/bin/sh
# Este script comprueba si un usuario est dentro del sistema
# y en caso afirmativo intenta establecer comunicacin con
# el mediante el programa talk (talk se utiliza para establecer
# comunicacin interactiva con otros usuarios).
(who | grep $1) && talk $1

3.4 Operador ||
El operador || se utiliza para ejecutar un comando y en el caso de que falle ejecutar el
siguiente comando de la lista. El formato es el siguiente:
comando1 || comando2
Primero se ejecuta el comando1 y si se produce un error se ejecuta el comando2. La
estructura equivalente ser:
comando1
if test $? ne 0
then
comando2
fi
Ejemplo:
#!/bin/sh
# Ejemplo de utilizacin del operador ||
# El usuario enva un mensaje a otro usuario desde el terminal si
# est en el sistema y en caso contrario le enva un correo.
# Ejemplo: enviar_mensaje.sh pedro Tengo el documento. Llamame
echo $2 | (write $1 || mail S1 ;)

4.1 Sentencia iterativa while


La sentencia while se utiliza para repetir la ejecucin de una serie de comandos de la
shell mientras una expresin condicional es verdadera. La sintaxis de la sentencia es:
while condicion
do
comandos
done
Ejemplo:
#!/bin/sh
# Ejemplo de utilizacin de la sentencia while
# Script que muestra los nmeros del 1 al 10 por pantalla,
# utilizando la sentencia while
contador=0
incremento=1
while [ $contador ne 10 ]
do
echo $contador
contador=`expr $contador + $incremento`
done

Ejemplo:
#!/bin/sh
Option=0
while [ $option ne 4 ]
do
echo Editores
echo 1.- vi
echo 2.- emacs
echo 3.- nano
echo 4.- Salir
echo
echo Selecciona una opcion ?
read option
case $option in
1) vi ;;
2) emacs ;;
3) nano ;;
4) echo Fin del programa exit ;;
*) echo Opcion incorrecta;;
esac
done

Ejemplo:
#!/bin/sh
#Fichero: sentencia_while.sh
# Ejemplo de utilizacin de la sentencia while
# Script que crea 5 ficheros cuyo nombre empieza por "curso" y
# luego un nmero que lo diferencia
num=1
while test $num le 5
do
touch curso$num
num=`expr $num + 1`
done

4.2 Sentencia iterativa until


La sentencia until es similar a la sentencia while, excepto que en este caso se repite el
bucle mientras la condicin es falsa. La sintaxis de esta sentencia es:
until condicion
do
comandos
done

Ejemplo 1:
#!/bin/sh
# Fichero: sentencia_until.sh
# Ejemplo de utilizacin de la sentencia until. El script muestra
# los numeros del 1 al 10 por pantalla
contador=0
incremento=1
until

[ $contador eq 10 ]

do
echo $contador
contador=`expr $contador + $incremento`
done

Ejemplo:
#!/bin/sh
# Fichero: sentencia_until.sh
# Ejemplo de utilizacin de la sentencia until
# Script que crea 5 ficheros cuyo nombre empieza por "curso" y
# luego un nmero que lo diferencia
num=1
until test $num gt 5
do
touch curso$num
num=`expr $num + 1`
done

4.3 Sentencia iterativa for


La sentencia for se utiliza para repetir una lista de rdenes tantas veces como el
nmero de elementos de una lista. La sintaxis de esta sentencia es:
for variable in [ lista de valores ]
do
comandos
done

Ejemplo:
#!/bin/sh
# Fichero: sentencia_for_1.sh
# Ejemplo de utilizacin de la sentencia for
# Script que muestra los nmeros del 1 al 10 por pantalla,
# utilizando la sentencia for
lista= 0 1 2 3 4 5 6 7 8 9
for i in $lista
do
echo $i
done

5 Otros comandos
Modificando el hilo de ejecucin de los bucles
Existen dos sentencias que modifican el hilo de ejecucin dentro de los bucles, que son
las sentencias break y continue.

La sentencia break se utiliza para salir del bucle en el que se est introducido. Este
comando termina la ejecucin del bucle ms interno, provocando que la ejecucin
sea llevada hasta la sentencia done ms cercana. Si se desea salir de cinco niveles,
hay que utilizar el comando:
break num_niveles

El comando continue provoca que la ejecucin salte a la primera lnea de la


sentencia while, until o for que contiene la sentencia continue.

Nota:
El comando eval que se usa en el siguiente ejemplo, interpreta la cadena de caracteres que se pone
como parmetro y a continuacin la ejecuta como un comando.

Ejemplo:
#!/bin/sh
# Fichero: sentencia_break_continue.sh
# Este ejemplo pide al usuario que introduzca un comando. Si el
# comando est vaco, no hace nada y pasa a pedir un nuevo
# comando. Si el comando es la palabra fin, entonces se sale del
# bucle y termina la ejecucin. En otro caso procesa el comando
while echo Introduce el comando:
read cmd
do
case $cmd in
fin)
)
*)
done

break;;
continue;;
eval $cmd;;

#no mas comandos, se sale del bucle


#un comando vaco
#ejecuta el comando

6 Funciones
El lenguaje de programacin de la Shell provee la facilidad para declarar funciones. Una
funcin es un segmento de cdigo reutilizable, que tiene un nombre, una lista de
parmetros y un conjunto de sentencias ejecutables. El formato general de una funcin
es el siguiente:
Nombre_funcion(){
sentencia1

sentenciaN
}

Los argumentos son pasados a la funcin de la misma forma que los parmetros
posicionales se pasan desde la lnea de comandos al script. Para llamar a una funcin
desde el cdigo basta poner su nombre, seguido por los parmetros posicionales que se
le pasan como argumentos.
No existe un mtodo formal para que una funcin devuelva un valor. No obstante, esto
se puede conseguir ejecutando la funcin encerrada entre comillas simples invertidas, y
visualizando el valor devuelto al final de la definicin de la funcin, tal como se hace en
el ejemplo anterior.
Adems, las funciones pueden ser recursivas, es decir, se pueden llamar a s mismas
dentro de las sentencias de la funcin.

Ejemplo 1:
#!/bin/sh
# Fichero: notas_medias.sh
# Ejemplo de utilizacin de funciones
# Consideremos la funcin calcula_media, que toma un nmero
# indeterminado de parmetros y calcula el valor medio de los
# mismos.
calcula_media (){
valor=0
for i in $@
do
valor=`expr $valor + $i`
done
echo `expr $valor / $#`
}
echo Las notas de Pedro son 4 4 5 5 5 7
echo y su nota media `calcula_media 4 4 5 5 5 7`

Ejemplo 2:
#!/bin/sh
# Fichero: prueba_factorial.sh
# Ejemplo de utilizacin de funciones recursivas
# Esta es una funcin recursiva que calcula el factorial de
# un nmero.
factorial(){
if [ $1 ge 1 ]
then
num1=`expr $1 1`;
num2=`factorial $num1`
echo `expr $num2 \* $1`
else
echo 1
fi
}
echo `factorial 4`

Vous aimerez peut-être aussi