ISO UD6 Scripting en GNU Linux

40
UD4: Programación de scripts en GNU/Linux IMPLANTACIÓN DE SISTEMAS OPERATIVOS

description

scripts de linux

Transcript of ISO UD6 Scripting en GNU Linux

  • UD4: Programacin de scripts en GNU/Linux

    IMPLANTACIN DE SISTEMAS OPERATIVOS

  • 1 Introduccin: shell como lenguaje de scriptingUn 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 shellsSi 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 lenguajeEl 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 defectoexport PATH=$PATH:/home/usuario/bin #aade el directorio al path

  • 2 Creacin de un scriptCmo 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:

    dateecho $SHELL $HOMEls

  • 2.1 Insercin de comentariosTodo 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.dateecho $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 tresecho $#echo $*echo $0echo $1echo $2echo $3echo $4

  • 2.5 Utilizacin de variablesEn 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.shnombre=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.shecho Indique su nombre y sus dos apellidosread nombre apellido1 apellido2

    echo Hola $nombre $apellido1 $apellido2, Cmo estas?

  • 2.7 Expresiones aritmticasLas 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. / -> divisin% -> resto

    $ expr 3 + 47$ expr 5 \* 210$ expr 7 / 23$ a= 3$ a= `expr $a +2`$ echo $a5

  • 2.8 Uso de comillasExisten 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 comillasdirectorio=$1var1='ls $directorio'var2="ls $directorio"var3=`ls $directorio`clearecho $var1echo $var2echo $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 exitfiecho $1 $2 $3

  • Comparaciones numricas:

    test n1 eq n2 -> verdadero si son igualestest n1 ne n2 -> verdadero si son distintostest n1 ge n2 -> verdadero si n1 es mayor o igual que n2test n1 gt n2 -> verdadero si n1 es mayor que n2test n1 le n2 -> verdadero si n1 es menor o igual que n2test n1 lt n2 -> verdadero si n1 es menor que n2

    Comparaciones de cadena de caracteres:

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

  • Ejemplo:

    cadena1=linuxcadena2=windowsif test -n cadena1 Si la longitud de la cadena es distinta de 0if 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 lgicosLas 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 condicionalesLas 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 ifSu sintaxis posee tres posibles variaciones:

    1 forma:

    2 forma:

    if condicionthen

    Comandos a ejecutarfi

    if condicion then comandos si la condicin se cumple else

    comandos si la condicin no se cumplefi

  • 3 forma:

    Y la sentencia if en una solo lnea:

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

    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 cumplenfi

  • Ejemplo:

    #!/bin/sh# Fichero: sentenciasconif.sh# Ejemplo de ejecucin de script con sentencias if# Ejecucin: sh sentenciasconif.sh

    echo Introduce numero1read n1echo Introduce numero2read n2if test $n1 gt $n2then echo El numero $n1 es mayor que $n2

    elif test $n2 gt $n1then

    echo El nmero $n2 es mayor que $n1else

    echo Los nmeros $n1 y $n2 son igualesfi

  • 3.2 Sentencia caseLa sentencia case se utiliza para comparar una variable frente a una serie de posibles valores. La sintaxis es:

    Ejemplo:echo -n "Introduzca el nombre de un animal: "read animalecho -n "Un $animal tiene "case $animal incaballo | perro | gato) echo -n "cuatro";;hombre | mono | pato) echo -n "dos";;*) echo -n "un numero desconocido de";;esac

    echo " patas."

    case variable in patron1) comandos condicion1;; patron2) comandos condicion2;; ... patron n) comandos condicion n;; *) comandos si no se cumplen ninguna;;esac

  • 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 optioncase $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 && comando2Primero se ejecutar comando1 y si no se han producido errores se ejecutara el comando2. El operador es equivalente a la siguiente estructura.

    if comando1then

    comando2fi

    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 || comando2Primero se ejecuta el comando1 y si se produce un error se ejecuta el comando2. La estructura equivalente ser:

    comando1if test $? ne 0then comando2fi

    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 whileLa 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:

    Ejemplo:

    #!/bin/sh# Ejemplo de utilizacin de la sentencia while# Script que muestra los nmeros del 1 al 10 por pantalla,# utilizando la sentencia whilecontador=0incremento=1while [ $contador ne 10 ]do echo $contador contador=`expr $contador + $incremento`

    done

    while condiciondo comandosdone

  • Ejemplo:

    #!/bin/shOption=0while [ $option ne 4 ]do

    echo Editoresecho 1.- viecho 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;; esacdone

  • 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 diferencianum=1while test $num le 5 do touch curso$num num=`expr $num + 1` done

  • 4.2 Sentencia iterativa untilLa 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:

    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

    until condiciondo comandosdone

  • 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=1until test $num gt 5 do touch curso$num num=`expr $num + 1` done

  • 4.3 Sentencia iterativa forLa 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:

    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

    for variable in [ lista de valores ]do comandosdone

  • 5 Otros comandosModificando 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) break;; #no mas comandos, se sale del bucle

    ) continue;; #un comando vaco

    *) eval $cmd;; #ejecuta el comando

    done

  • 6 FuncionesEl 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:

    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.

    Nombre_funcion(){ sentencia1 sentenciaN}

  • 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 7echo 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`