Shell Script Linux

19
SHELL SCRIPT LINUX Capitulo cuarto. En este cuarto capitulo trataremos de lleno la base de la programación en shell-script, para que os sirva como punto de partida en la elaboración de vuestros propios shell-script Trataremos el paso de parámetros o variables de captura, las variables autodefinidas por la shell, comandos de captura de variables, comandos para operaciones aritméticas, condicionales simples, condicionales múltiples, ciclos o 'loops', iteración, el uso de funciones, y captura de señales. Dada la dificultad que conlleva el explicar cada comando con las posibles variantes con las que se puede aplicar, explicare con ejemplos genéricos, los cuales podréis ir copiando y pegando en la terminal para ver su forma de funcionar y poder practicar con ellos para un mejor entendimiento de estos. Consideraciones a tener en cuenta Un shell-script es un guión de comandos que la shell va ejecutando en orden. A la shell le da igual si comentamos los comandos, o los identamos, los ejecutará por orden igualmente, pero a nosotros en scripts lo suficientemente largos no nos da igual, es algo básico llevar un orden a la hora de elaborarlos, ya que como comenté anteriormente en otras ocasiones, en el momento de hacer un comando, tendremos claro lo que queremos que haga, pero a la hora de modificar un script o intentar interpretar lo que hace un comando dentro de este, pasado el tiempo, no lo tendremos tan claro, y agradeceremos mucho el hecho de haber tenido en cuenta esto. Para comentar el código, ya vimos anteriormente el uso del caracter '#' almohadilla el cual se puede utilizar antes de el comando a comentar o incluso en líneas que efectúen el comando propiamente dicho de este modo : #!/bin/bash # Ejemplo de comentado de scripts echo "hola mundo" # este comando imprime el texto entre comillas en pantalla Identación del código La identación del código es algo extendido y normal en todos los lenguajes de programación. Es un buen modo de ordenar de una forma visual el código, para poder ver a simple vista donde acaba una orden y empieza otra, la cual a su vez se ejecuta o no dentro de otra orden o condición. Esto lo entenderemos mejor de una forma visual, del mismo modo que se identan los programas: inicio comando 1 >>>>>>>>>inicio comando 2 >>>>>>>>>>>>>>>>>>inicio comando 3 >>>>>>>>>>>>>>>>>>fin comando 3 >>>>>>>>>fin comando 2 fin comando 1 Como se puede ver, el comando 3 empieza y acaba dentro de el comando 2 el cual empieza y termina dentro del comando 1. Paso o captura de parámetros o argumentos.

Transcript of Shell Script Linux

Page 1: Shell Script Linux

SHELL SCRIPT LINUX

Capitulo cuarto.

En este cuarto capitulo trataremos de lleno la base de la programación en shell-script, para que os sirva como punto de partida en la elaboración de vuestros propios shell-scriptTrataremos el paso de parámetros o variables de captura, las variables autodefinidas por la shell, comandos de captura de variables, comandos para operaciones aritméticas, condicionales simples, condicionales múltiples, ciclos o 'loops', iteración, el uso de funciones, y captura de señales.Dada la dificultad que conlleva el explicar cada comando con las posibles variantes con las que se puede aplicar, explicare con ejemplos genéricos, los cuales podréis ir copiando y pegando en la terminal para ver su forma de funcionar y poder practicar con ellos para un mejor entendimiento de estos.

Consideraciones a tener en cuenta

Un shell-script es un guión de comandos que la shell va ejecutando en orden. A la shell le da igual si comentamos los comandos, o los identamos, los ejecutará por orden igualmente, pero a nosotros en scripts lo suficientemente largos no nos da igual, es algo básico llevar un orden a la hora de elaborarlos, ya que como comenté anteriormente en otras ocasiones, en el momento de hacer un comando, tendremos claro lo que queremos que haga, pero a la hora de modificar un script o intentar interpretar lo que hace un comando dentro de este, pasado el tiempo, no lo tendremos tan claro, y agradeceremos mucho el hecho de haber tenido en cuenta esto.Para comentar el código, ya vimos anteriormente el uso del caracter '#' almohadilla el cual se puede utilizar antes de el comando a comentar o incluso en líneas que efectúen el comando propiamente dicho de este modo :

#!/bin/bash# Ejemplo de comentado de scriptsecho "hola mundo" # este comando imprime el texto entre comillas en pantalla 

Identación del código

La identación del código es algo extendido y normal en todos los lenguajes de programación. Es un buen modo de ordenar de una forma visual el código, para poder ver a simple vista donde acaba una orden y empieza otra, la cual a su vez se ejecuta o no dentro de otra orden o condición.Esto lo entenderemos mejor de una forma visual, del mismo modo que se identan los programas:

inicio comando 1>>>>>>>>>inicio comando 2>>>>>>>>>>>>>>>>>>inicio comando 3>>>>>>>>>>>>>>>>>>fin comando 3>>>>>>>>>fin comando 2fin comando 1

Como se puede ver, el comando 3 empieza y acaba dentro de el comando 2 el cual empieza y termina dentro del comando 1.

Paso o captura de parámetros o argumentos.

Como bien sabemos, en un script podemos incorporar cientos de comandos, pero estos necesitan de argumentos para poder funcionarán shell-script que use siempre los mismos parámetros, nos servirá una vez o dos.. pero lo realmente útil es que podamos incorporar a nuestro script distintos argumentos para que funcione según nos interese en cada momento. Estos parámetros se traducen en forma de variables dentro de nuestro script las cuales modificamos nosotros añadiendo o pasándoselas en el momento de lanzarlo lo llamaremos forma 'estática', o haciendo que nos las pida en un momento determinado de su ejecución, la cual llamaremos forma 'dinámica'.

Esto lo entendermos mejor, como siempre con un ejemplo:

Page 2: Shell Script Linux

SHELL SCRIPT LINUX

#!/bin/bash#Paso de argumentos de forma 'estatica'.echo "primera opción $1"echo "segunda opción $2"echo "tercera opción $3"

En el ejemplo anterior al ejecutar el script tendríamos que pasarle el valor de las variables $1, $2 y $3, en el momento de lanzar el script, para que este las tome en consideración.

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script2 primera segunda terceraprimera opción primerasegunda opción segundatercera opción tercerarh3nt0n@rh3nt0n-laptop:~/scripts$

Como vemos en su ejecución, las variables $1,$2 y $3 la shell las coge de la línea al lanzar este, y las traduce por orden dentro del script según se las ha llamado.Estas variables pueden ser cadenas de texto (entrecomilladas), números, ficheros o rutas de directorios. Dependiendo de el tipo de argumento que necesite el comando que las requiera.El paso de argumentos esta limitado a 9 pero este inconveniente se subsana con el comando 'shift' el cual explicare un poco mas adelante ya que es necesario que antes conozcáis las variables autodefinidas por la shell para shell-script.

Variables autodefinidas por shell-script

$# ---- Esta variable contiene el numero de argumentos que hemos pasado al script.$0 ---- Esta variable contiene el nombre de el shell-script que se ejecuta.$* ---- Esta variable muestra una cadena con los parámetros que hemos pasado al script.$? ---- Esta variable contiene la salida del comando anterior donde se encuentre dentro de el script.

Esto lo veremos mas claro añadiendo estas variables a nuestro script anterior

#!/bin/bash#Paso de argumentos de forma 'estática'.echo "primera opción $1"echo "segunda opción $2"echo "tercera opción $3"#Variables autodefinidasecho "se ejecuta $0"echo "tengo $# argumentos"echo "los cuales han sido $*"cp #este comando necesita parámetros, por lo tanto lanzara un error que $? capturara echo "salida de error: $?"

Al ejecutar nuestro script, obtendremos la siguiente salida:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script2a primera segunda terceraprimera opción primerasegunda opción segundatercera opción tercerase ejecuta script2atengo 3 argumentoslos cuales han sido primera segunda terceracp: falta un fichero como argumentoPruebe `cp --help' para más información.salida de error: 1rh3nt0n@rh3nt0n-laptop:~/scripts$

Page 3: Shell Script Linux

SHELL SCRIPT LINUX

Como se puede apreciar las variables autodefinidas del script toman el valor de los parámetros y las circunstancias en las que se ejecuta el script, variando si estas circunstancias varían.

Comando 'shift'

Este comando hace posible que podamos una vez usada una variable, eliminarla y poder usar ese valor de variable para otro argumento, esto como es habitual lo veremos mejor con un ejemplo:

#!/bin/bash#uso del comando shiftecho "primera opción $1"shiftecho "segunda opción $1"shiftecho "tercera opción $1"

Como podremos apreciar en la ejecución de este script, el comando shift nos permite usar una misma variable, para distintos argumentos:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script2b primera segunda terceraprimera opción primerasegunda opción segundatercera opción tercerarh3nt0n@rh3nt0n-laptop:~/scripts$

Como se puede observar obtenemos la misma salida que en el primer script pero sin la necesidad de dar un valor a cada argumento.

Pase o captura de parámetros de forma 'dinámica'.

Si en un momento dado de la ejecución de nuestro script, necesitamos de la introducción de algún parámetro de forma, por llamarlo de alguna manera, 'en caliente', mientras se ejecuta el script, tenemos la opción de usar el comando 'read'.

Comando 'read'

Durante la ejecución de un script, si este se encuentra con el comando read seguido de un nombre de variable, la ejecución se detendrá y nos mostrara el cursor parpadeando en espera de que introduzcamos un parámetro, que a continuación la shell almacenara asignándolo como valor de el nombre de variable en cuestión.

Ejemplo:

#!/bin/bash#uso del comando readecho "Cual es tu nombre?"read nombreecho "Hola $nombre"

Si hasta ahora hemos sido un poco avispados, nos habremos dado cuenta, de que para asignar un nombre a una variable desde read, no se usa el signo de '$' ,se usa solo en el momento de usar dicha variable.

Veamos la ejecución del script:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script3Cual es tu nombre?rh3nt0n <------------ aqui tipeamos el valor de la variable nombre.Hola rh3nt0n <-------- aqui toma el valor tipeado y lo muestra por pantallarh3nt0n@rh3nt0n-laptop:~/scripts$

Page 4: Shell Script Linux

SHELL SCRIPT LINUX

Se pueden asignar varias variables en un mismo read, así como pedir varios argumentos con varios read.

Ejemplo:

#!/bin/bash#uso del comando read con varios parámetros y varios readecho "Cual es tu nombre?"read nombreecho "Cuales son tus apellidos?"read apellido1 apellido2sleep 5 # dormimos la terminal 5 segundos echo " Tu segundo apellido es $apellido2 "echo " Tu nombre completo es $nombre $apellido1 $apellido2"echo " Hola $nombre"

Como veremos en la salida podemos llamar a las variables introducidas en el orden en que queramos. Solo he usado el comando sleep para que podáis apreciar la salida de el script diferenciada de la entrada de parámetros.

La salida seria la siguiente:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script4Cual es tu nombre?pingüinoCuales son tus apellidos?unix linuxTu segundo apellido es linuxTu nombre completo es pingüino unix linuxHola pingüinorh3nt0n@rh3nt0n-laptop:~/scripts$

Comando para operaciones aritméticas

comando 'expr'. Este comando suele usarse con asiduidad dentro de condicionales tanto simples como múltiples que explicare mas adelante, o para simplemente hacer operaciones aritméticas. Necesita como mínimo tres argumentos, dos operandos y un operador.Los operadores son los típicos de operaciones aritméticas :suma ---------- '+'resta --------- '-'multiplicación- '*'Este símbolo hay que escaparlo '\*' dada su condición de carácter especial.división------- '/'modulo--------- '%' el modulo no es mas que el resto de una división, el cual suele ser el divisor menos uno.Ejemplo de modulo: 100 % 5 ------> el modulo 5 de 100 sería de 0 a 4.Esto nos puede servir a la hora de generar un numero aleatorio, reducirlo a la cantidad que deseemos, Se entenderá mas adelante con algunos ejemplos.

Sintaxis: expr [operando1] operador [operando2]

Ejemplo de expr:

#!/bin/bash#Ejemplo de expr (el cuadrado de un numero)echo "Dame un numero."read numeroresultado=`expr $numero \* $numero` # declaramos la variable resultado, como resultado de exprecho "El resultado de el cuadrado de $numero es $resultado"

La salida del script seria la siguiente:

Page 5: Shell Script Linux

SHELL SCRIPT LINUX

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script5Dame un numero.6El resultado de el cuadrado de 6 es 36rh3nt0n@rh3nt0n-laptop:~/scripts$

Como se puede observar read pide la variable numero, y expr se encarga de dar como valor a la variable resultado, la operación que realiza con la variable numero, la cual en este caso no es mas que una multiplicación por si misma. Como se puede también observar 'escapamos' el carácter asterisco '\*' para que la shell no lo tome como metacarácter.

Evaluar cadenas

Para evaluar cadenas, ya sean cadenas de texto, ficheros, o números, tenemos el comando 'test' el cual nos permite de una forma rápida y fácil comparar o comprobar cualidades o valores de las cadenas evaluadas para poder a grosso modo obtener un resultado positivo o negativo que haga actuar a tal o cual comando de uno u otro modo.

Comando 'test'. Este comando para que no cause confusión desde el principio se suele abreviar usando solo corchetes [cadena valor cadena ] y suprimiendo el propio comando 'test', dentro de un 'if', 'case', 'until', 'for' etc ... (que veremos mas adelante) o simplemente para definir una variable, variable=`[ $1 != $2 ]`Como veo que me enredo mucho, veamos un ejemplo con test, con y sin comando.Un sencillo ejemplo de 'test'para ver su sintaxis:

#!/bin/bash# ejemplo de testtest $1 = $2 # necesitamos dos argumentos al lanzar el scriptecho $? #si 'echo' devuelve un 0 es que el comando test es verdadero.

Si lo ejecutamos introduciendo dos valores iguales como argumentos, el resultado de la comparación será verdadero, ya que evaluamos si $1 es igual '=' a $2, por lo tanto 'echo' imprimirá un 0 en la pantalla:

rh3nt0n@rh3nt0n-laptop:~$ bash script6 uno uno0rh3nt0n@rh3nt0n-laptop:~$

En caso de que introduzcamos dos argumentos distintos, la comparación no será verdadera, y por lo tanto nos devolverá un 1:

rh3nt0n@rh3nt0n-laptop:~$ bash script6 paquito paquita1rh3nt0n@rh3nt0n-laptop:~$

Ahora probemos a editar el anterior script de la siguiente manera, y lo ejecutamos del mismo modo que el anterior:

#!/bin/bash# ejemplo de test con corchetes[ $1 = $2 ] # necesitamos dos argumentos al lanzar el scriptecho $? #si 'echo' devuelve un 0 es que el comando test es verdadero.

Una vez ejecutado el script, nos daremos cuenta que es lo mismo poner los corchetes que la palabra test.

Como dijimos anteriormente, el comando test sirve para evaluar ficheros, cadenas de texto, y números, pero estos no se evalúan de la misma forma ya que evidentemente no son argumentos del mismo tipo, y cada uno se trata de forma diferente:

Modos de evaluar con 'test'.

Page 6: Shell Script Linux

SHELL SCRIPT LINUX

1º Evaluando ficheros.Los ficheros se pueden avaluar con estos parámetros:-f-----------indica si el fichero existe.0 si es verdadero y 1 si es falso.-s-----------indica si el fichero existe y no esta vacio.0 si verdad, 1 si falso.-r-----------indica si tiene permiso de lectura.0 verdad, 1 falso.-w-----------indica si tiene permiso de escrituta.0 verdad, 1 falso.-x-----------indica si tiene permiso de ejecución.0 verdad, 1 faslo.-d-----------indica si es directorio. 0 verdad, 1 falso.Estos parámetros se pueden unir usando los enlazadores :-a-----------and, 'y'.-o-----------or, 'o'.!------------not, no.

Veamos un ejemplo de evaluación de ficheros:

#!/bin/bash# evaluación de ficheros con test.[ -f $1 ] # al lanzar el script damos ruta relativa o absoluta del fichero.echo $? #mostrara 0 si exite y 1 si no existe

Probemos con uno de nuestros scripts:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script7 script10rh3nt0n@rh3nt0n-laptop:~/scripts$

Podemos comprobar que existe ya que la evaluación nos retorna un 0.

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script7 script101rh3nt0n@rh3nt0n-laptop:~/scripts$

Podemos comprobar que no existe ya que test nos retorna un uno.También podemos usar 'read' para introducir dinámicamente el fichero a evaluar.

2º Evaluando cadenas de texto.

Para evaluar cadenas de texto tenemos los parámetros:

parámetros:'=' ---------- igual'!='---------- distinto

Ejemplo:

#!/bin/bash# evaluación de ficheros con test.[ $1 != $2 ] # al lanzar el script damos dos cadenas de texto como argumentoecho $? #mostrara 0 si distinto y 1 si si igual

Si ejecutamos el script, nos dará en función de los argumentos una salida u otra.

números aleatorios:

Antes de nada, explicare como se genera un numero aleatorio usando la variable $RANDOM.La variable $RANDOM genera un numero aleatorio de entre 1 y 32000, podemos necesitar conseguir un numero aleatorio para multitud de funciones, a mi por ejemplo se me ocurre una, los números de la primitiva, pero hay un problema, nos sobran muchos números ya que la primitiva solo tiene 48, para solucionar el problema utilizaremos la expresión '%' modulo, la cual nos limita el numero aleatorio a el modulo que elijamos de este, en este caso será 49.Lo mejor es un ejemplo:

Page 7: Shell Script Linux

SHELL SCRIPT LINUX

#!/bin/bash# aleatorio con random 'primitiva'alea=`expr $RANDOM % 49` # generamos un numero aleatorio1=`expr $alea + 1`# nos aseguramos que no sea 0 sumándole 1alea=`expr $RANDOM % 49` # el segundo ..aleatorio2=`expr $alea + 1`alea=`expr $RANDOM % 49`aleatorio3=`expr $alea + 1`alea=`expr $RANDOM % 49`aleatorio4=`expr $alea + 1`alea=`expr $RANDOM % 49`aleatorio5=`expr $alea + 1`alea=`expr $RANDOM % 49`aleatorio6=`expr $alea + 1`echo "Copia estos numeros:"echo " $aleatorio1 - $aleatorio2 - $aleatorio3 " # imprimimos los tres primerosecho " $aleatorio4 - $aleatorio5 - $aleatorio6 " # imprimimos los otros tres

La salida seria algo parecido a esto:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash aleatorioCopia estos numeros:24 - 2 - 296 - 33 - 11rh3nt0n@rh3nt0n-laptop:~/scripts$

Por supuesto hay mas métodos para generar números aleatorios, pero me pareció la forma mas rápida y sencilla de que vierais un ejemplo, espero que halláis captado la idea.Sigamos con text.

3º Evaluando números

Pensareis que con las opciones anteriores de evaluación de cadenas de texto, también se pueden evaluar números, y en cierto modo si se puede, pero hay que tener algo en cuenta :[ 04 = 4 ]Si nos damos cuenta, esa evaluación nos devolvería '1', ya que el '=' evalúa si 04 es igual a 4, y como cadena de texto, no lo es.Por lo tanto, si lo que queremos es evaluar números, tenemos las siguientes opciones o parámetros:-lt --------- menor que ... -le --------- menor o igual -gt --------- mayor que ... -ge --------- mayor o igual -eq --------- igual -ne --------- no igual

Visto lo cual haremos un script para adivinar un numero aleatorio, en el cual nos basaremos para ir mejorándolo y para así entender lo que viene a continuación: condicional simple.

#!/bin/bash# adivinador con evaluación numéricaecho "Adivina mi numero"read adivaleatorio=`date +%S` #creamos un numero aleatorio en segundos de 0 a 59 aleatorio=`expr $aleatorio % 5` # lo reducimos a su modulo 5 (de 0 a 4)# si nos damos cuenta hemos sobrescrito la variable $aleatorio # no hay problema en esto ...[ $aleatorio -eq $adiv ] # evaluamos si el numero que hemos introducido es igual a el aleatorioecho $? # nos imprime si lo es o no: 0 si, 1 no .

Ejecutad el script:

Page 8: Shell Script Linux

SHELL SCRIPT LINUX

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash adivinadorAdivina mi numero:30rh3nt0n@rh3nt0n-laptop:~/scripts$ bash adivinadorAdivina mi numero:21rh3nt0n@rh3nt0n-laptop:~/scripts$

Como se puede apreciar, en la primera ejecución he tipeado el numero 3, y he acertado, por consiguiente la salida de el comando test es 0.Por contra, en la segunda ejecución, he tipeado 2, y he fallado, por consiguiente la salida ha sido un 1.

Bueno después de todo esto, espero que halla quedado claro lo que significa un 0 y lo que significa un 1 en la salida de de un test...sigamos

Condicional simple.

Cuando hablamos de condicional simple, básicamente hablamos de el uso de el comando 'if', el cual nos permite usar el 'test' para que dependiendo de la salida de este, nuestro script haga una cosa u otra.. veamos un ejemplo con el anterior script: 

#!/bin/bash# adivinador mejorado con if echo "Adivina mi numero:"read adivaleatorio=`date +%S` #creamos un numero aleatorio en segundos de 0 a 59 aleatorio=`expr $aleatorio % 5` # lo reducimos a su modulo 5 (de 0 a 4)# si nos damos cuenta hemos sobrescrito la variable $aleatorio # no hay problema en esto ...if [ $aleatorio -eq $adiv ] ; # evaluamos si el numero que hemos introducido es igual a el aleatoriothen # si es igual pasamos a el echo de la siguiente líneaecho "has acertado!!"else # si no es igual pasamos a el echo de mas abajo echo "has errado!!" fi

Si lo ejecutamos:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash adivinador2Adivina mi numero:3has errado!!rh3nt0n@rh3nt0n-laptop:~/scripts$

Podemos ver que la principal diferencia es que la salida de test nos redirige el camino a tomar por el script hacia un comando u otro, según sea la salida de este falsa o verdadera.

sintaxis de comando 'if':

if [ evaluación ] ;

----then

---------paso a tomar si verdadero

----else

---------paso a tomar si falso

Page 9: Shell Script Linux

SHELL SCRIPT LINUX

fi

Como podréis comprobar, este comando es de los que hay que identar para una mayor comprensión de el a la hora de comprenderlo cuando lo miremos tiempo después de hacerlo.

Respecto a su funcionamiento solo añadir, que en caso de que no se cumpla la condición evaluada, no es estrictamente necesario usar 'else', con lo cual la opción 'else' es opcional, si lo que nos interesa es una salida verdadera de la evaluación..

Otro ejemplo de 'if' pero esta vez evaluando ficheros:

#!/bin/bash##################################### Este script evalua dos ficheros dados de forma estatica## diciendonos cual es mayor en tamaño .###############################################uno=`ls -l $1 | tr -s " " | cut -f5 -d " "` #filtramos el primer ficherodos=`ls -l $2 | tr -s " " | cut -f5 -d " "` #filtramos el segundo ficheroif [ $uno -gt $dos ] ;then echo " $1 es mayor "else echo " $2 es mayor "fi

Si ejecutamos nuestro script, evaluando por ejemplo dos de los script que hemos creado hasta ahora:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash ficheromayor /home/rh3nt0n/scripts/script1 /home/rh3nt0n/scripts/script7/home/rh3nt0n/scripts/script7 es mayorrh3nt0n@rh3nt0n-laptop:~/scripts$

Condicional múltiple.

Para explicar el uso de esta forma de condicionar, haremos una calculadora simple la cual necesitara de tres argumentos a añadir de forma 'estática'.así entenderemos el como y por que de la opción de el comando 'case' para poder hacer múltiples condiciones, sin necesidad de alargar el código con 'if' recurrentes, como en el siguiente caso:

#!/bin/bash# calculadora con if.if [ $3 = "suma" ]thenexpr $1 + $2elseif [ $3 = "resta" ]thenexpr $1 - $2 elseif [ $3 = "multi" ]thenexpr $1 \* $2elseif [ $3 = "divi" ]thenexpr $1 / $2elseecho "opción no valida"fifififi

Page 10: Shell Script Linux

SHELL SCRIPT LINUX

Si ejecutamos la calculadora:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash calculadora 34 56 suma90rh3nt0n@rh3nt0n-laptop:~/scripts$ bash calculadora 34 56 multi1904rh3nt0n@rh3nt0n-laptop:~/scripts$

Bien, vemos que la calculadora funciona, pero el código es demasiado extenso y además tiene demasiados 'if', y no es necesario si usamos 'case'.

Comando 'case'.

Sintaxis:(cambiad '>' por espacios)case variable in>>>>>>patron1)>>>>ordenes ;;>>>>>>patron2)>>>>ordenes ;;>>>>>>patron3)>>>>ordenes ;;...>>>>>>*)>>>>>>>>ordenes ;;esac

Veamos como ejemplo la calculadora anterior a que se reduce con 'case':

#!/bin/bash# Calculadora con casecase $3 in"suma")expr $1 + $2 ;;"resta")expr $1 - $2 ;;"multi")expr $1 \* $2 ;;"divi")expr $1 / $2 ;;esac

Al ejecutar nuestra nueva calculadora con la mitad de líneas gracias a case, tenemos que case nos permite dar múltiples valores a una variable y actuar de la forma que sea, según el valor que introduzcamos.

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash calculadora2 50 50 multi2500rh3nt0n@rh3nt0n-laptop:~/scripts$ bash calculadora2 50 50 suma100rh3nt0n@rh3nt0n-laptop:~/scripts$

Ciclos o loops.

Los ciclos o loops, sirven para hacer que cuando se cumple una determinada circunstancia, una orden se repita, hasta que esa circunstancia deje de cumplirse.Para esto tenemos varios comandos que comentaremos a continuación:

Comando 'while'.'mientras'

Este comando ejecuta las ordenes que contenga, si la condición es cierta.(0).

Page 11: Shell Script Linux

SHELL SCRIPT LINUX

Sintaxis:while [ condición ]do#orden#orden...done

Veamos un ejemplo:

#!/bin/bash# El cuadrado de 1 a 100 con whilecont=1while [ $cont -lt 100 ] #siempre se usa test, se evalua que $cont sea menor que 100docuad=`expr $cont \* $cont` #hacemos que $cuad valga el cuadrado de $contecho "el cuadrado de $cont es: $cuad"cont=`expr $cont + 1` #hacemos que $cont se vaya incrementando en uno.done

Al ejecutarlo, veremos que while hace que se repitan de la línea 4 a la 8, hasta que la condición $cont -lt 100, se incierta, o sea que $cont valga 100 o mas.

rh3nt0n@rh3nt0n-laptop:~$ bash script8el cuadrado de 1 es: 1el cuadrado de 2 es: 4el cuadrado de 3 es: 9el cuadrado de 4 es: 16el cuadrado de 5 es: 25...el cuadrado de 94 es: 8836el cuadrado de 95 es: 9025el cuadrado de 96 es: 9216el cuadrado de 97 es: 9409el cuadrado de 98 es: 9604el cuadrado de 99 es: 9801rh3nt0n@rh3nt0n-laptop:~$

También tenemos la opción de el comando 'until' que hace lo mismo que while pero al contrario, o sea su negación.

Comando 'until'.'hasta' Negación de while.

Sintaxis:until [ condición ]doordenes #misma estructura que whiledone

Veamos otro ejemplo:

#!/bin/bash# imprimimos hasta 10 con untilcont=1until [ $cont -gt 10 ] #hasta que $cont sea mayor que 10do echo $contcont=`expr $cont + 1`done

Page 12: Shell Script Linux

SHELL SCRIPT LINUX

Al ejecutarlo veremos que el bucle funciona hasta que la variable $cont es mayor que 10.

rh3nt0n@rh3nt0n-laptop:~$ bash script912345678910rh3nt0n@rh3nt0n-laptop:~$

Comando de iteración 'for'.

Este comando es muy útil para evaluar y actuar sobre elementos que estamos pasando por parámetros.

Sintaxis:for variable in 'lista de parámetros'doordenesdone

Veamos un ejemplo basico:

#!/bin/bash# ejemplo basico de forfor numero in $1doecho $numero done

Al ejecutarlo veremos que coge los argumentos y ejecuta uno a uno el comando entre do y done:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script10 "uno dos tres"unodostresrh3nt0n@rh3nt0n-laptop:~/scripts$

Continuemos con for.Ahora veremos una forma de estructurar for condicionando directamente la variable a introducir por parametros.Sintaxis:for (( 1º ; 2º ; 3º ))dodone1º Da un valor de inicio a la variable.2º Condiciona la variable.3º Incrementa la variable.Veamos un ejemplo tonto en el que nuestro script nos dirá de un rango entre dos números dados por parámetros la cantidad de números que hay entre ellos y que son menores que el mayor de los introducidos, en caso de que el primer parámetro sea mayor que el segundo se parara el script avisando del error :

#!/bin/bash# mas opciones de forif [ $1 -lt $2 ]thennumero=`expr $2 + 1`

Page 13: Shell Script Linux

SHELL SCRIPT LINUX

for (( i=$1 ; i<$numero ; i++ ))doecho "$i es menor que $numero"if [ $i = $2 ]thenexit 0fidoneelseecho "opcion incorrecta !! la primera variable a de ser menor"fi

Si ejecutamos el script veremos que for da el valor a la variable i, la compara con el segundo parámetro dado, si es menor ejecuta el comando echo, y después incrementa el valor de i en uno, haciendo esto hasta que i es igual o mayor que el segundo parámetro:

rh3nt0n@rh3nt0n-laptop:~$ bash prueba 44 4544 es menor que 4645 es menor que 46rh3nt0n@rh3nt0n-laptop:~$

Si la primera variable es mayor que la segunda, nos lanza el error y sale:

rh3nt0n@rh3nt0n-laptop:~$ bash prueba 46 45opcion incorrecta !! la primera variable a de ser menorrh3nt0n@rh3nt0n-laptop:~$

Como operar con los ciclos.

Podemos interactuar con los ciclos o bucles según se comporten estos, es decir, si por ejemplo obtenemos una indeterminación dentro de un bucle, podemos hacer que este pare y salte a la siguiente línea del script dejando el bucle, que siga con el bucle, o que el script pare.Para esto, podemos usar los siguientes comandos:Comando 'break'. Si después de una indeterminación en un bucle, la shell encuentra un break, esta lo interpreta saltando el bucle y siguiendo con la siguiente orden después del bucle.Comando 'continue'. continue, es un escape, con lo cual, si el bucle termina correcta o incorrectamente, y la shell encuentra un continue, en lugar de proseguir con el siguiente comando después del bucle, vuelve a ejecutar el bucle.Comando 'exit'. Aunque exit no es un comando exclusivo de los bucles, también se usa con estos, en el caso de que queramos parar la ejecución del script, si se produce una situación determinada.

Para comprender el uso de estas ordenes, crearemos un script con un bucle que de como resultado una indeterminación. Por ejemplo una indeterminación seria el resultado de dividir un numero entre cero :

#!/bin/bash# ejemplo de indeterminaciónfor (( i=-10 ; i<=10 ; i++ ))doif [ $i -ne 0 ] ; thenexpr 1 \ $ielsebreak # continue # exit # aqui probad con cada una de las opcionesfidone

Ahora probemos estas opciones con un script mas útil, el siguiente ejemplo te dice de un rango de números dados por parámetros, cuales son pares:

#!/bin/bash# ejemplo con continue break y exit

Page 14: Shell Script Linux

SHELL SCRIPT LINUX

if [ $# -ne 2 ] ; thenecho "necesito dos argumentos"exit 1fiif [ $1 -gt $2 ] ; thenecho "$1 no puede ser mayor que $2"exit 2fifor (( i=$1 ; i<$2 ; i++ ))domod=`expr $i % 2`if [ $mod -ne 0 ] ; thencontinue # aqui probad primero segun esta y despues con break y exitfiecho " $i es par !!"done

Al ejecutarlo según esta, la salida será:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script13 4 94 es par !!6 es par !!8 es par !!rh3nt0n@rh3nt0n-laptop:~/scripts$

Si cambiamos la línea que contiene el continue, por break o exit, la salida será como esta, ya que el bucle con estas dos opciones quedara inutilizado:

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script13 4 94 es par !!rh3nt0n@rh3nt0n-laptop:~/scripts$

Menús selectivos en shell-script.

En shell-script, podemos confeccionar menús con los cuales elegir opciones a ejecutar con solo pulsar una tecla, para esto tenemos el comando 'select', el cual siempre debe de ir acompañado de el comando 'case'.Sintaxis:select i in lista de opcionesdocaseesacdone

Veamos un ejemplo:

#!/bin/bash# ejemplo de selectselect i in managed monitor cualquiera_orden salidadocase $i in"managed") echo "aquí podríamos poner la configuración de nuestra interfaz de red en modo managed";;"monitor") echo "aquí podríamos poner la configuración de nuestra interfaz de red en modo monitor";;"cualquiera_orden") echo "aquí podríamos hacer lo que nos diera la gana..";;"salida") break;;*) exit;; # esta opción hace que con cualquier opción que tecleemos invalida, el script pare. esacdone

Al ejecutarlo tendremos:

Page 15: Shell Script Linux

SHELL SCRIPT LINUX

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script11 1) managed 3) cualquiera_orden 2) monitor 4) salida #? 1 aquí podríamos poner la configuración de nuestra interfaz de red en modo managed #? 3 aquí podríamos hacer lo que nos diera la gana.. #? 4 rh3nt0n@rh3nt0n-laptop:~/scripts$ 

Uso de funciones

Una función es un trozo de código que se utilizara con frecuencia en un script, y que solo varia en una variable.Sintaxis:nombre_funcion() {código a ejecutar en la función}Veamos un ejemplo:

#!/bin/bash# determina par e impar de los números que introduzcamos dinámicamentedeterminaPar() { # aquí empieza la funciónnum=`expr $a % 2` if [ $num -eq 1 ];then echo "impar ; $a" else echo "par: $a" fi} # aquí termina la funciónecho "Dame tres números" read a1 read a2 read a3 export a=$a1determinaPar export a=$a2 determinaPar export a=$a3 determinaPar

Si lo ejecutamos veremos que a cada variable introducida se le aplica la función, lo cual ahorra muchas líneas de código ya que sin usar la función, tendríamos que repetir continuamente el código que contiene esta, para cada variable, con lo que esto conllevaría.

rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script12Dame tres numeros7007512346par: 700impar: 75par: 12346rh3nt0n@rh3nt0n-laptop:~/scripts$

Captura de señales.

Podemos hacer que nuestro script capture señales a la shell, lanzadas desde el teclado tipo 'crtl+c' y que la shell las ignore.

Page 16: Shell Script Linux

SHELL SCRIPT LINUX

Para esto, se usa el comando 'trap'.Comando 'trap'.Atrapa señales.

Sintaxis:trap ordenes señaló:trap señal <---- captura señal

Veamos un ejemplo:

#!/bin/bash# Ejemplo de traptrap mensaje 2mensaje() {echo "no puedes pararme ;)"}while [ 1 -eq 1 ] # buble infinitodo date sleep 1 done

Al ejecutarlo veremos que con 'ctrl+c' no podemos pararlo, podremos 'pararlo' usando 'ctrl+z', pero no podremos terminarlo hasta que no hagamos un 'kill %PID' :

rh3nt0n@rh3nt0n-laptop:~/scripts$ vi script15rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script15sáb nov 18 23:46:52 CET 2006sáb nov 18 23:46:53 CET 2006no puedes pararme ;)sáb nov 18 23:46:54 CET 2006sáb nov 18 23:46:55 CET 2006no puedes pararme ;)sáb nov 18 23:46:56 CET 2006sáb nov 18 23:46:57 CET 2006no puedes pararme ;)sáb nov 18 23:46:57 CET 2006sáb nov 18 23:46:58 CET 2006sáb nov 18 23:46:59 CET 2006[2]+ Stopped bash script15rh3nt0n@rh3nt0n-laptop:~/scripts$ jobs[1]- Stopped bash script15[2]+ Stopped bash script15rh3nt0n@rh3nt0n-laptop:~/scripts$kill %1rh3nt0n@rh3nt0n-laptop:~/scripts$ jobs[1]- Terminado bash script15[2]+ Stopped bash script15rh3nt0n@rh3nt0n-laptop:~/scripts$ kill %2rh3nt0n@rh3nt0n-laptop:~/scripts$ jobs[2]+ Terminado bash script15rh3nt0n@rh3nt0n-laptop:~/scripts$