Shell Script Linux
Shell Script Linux
Capitulo cuarto. En este cuarto capitulo trataremos de lleno la base de la programacin en shell-script, para que os sirva como punto de partida en la elaboracin de vuestros propios shell-script Trataremos el paso de parmetros o variables de captura, las variables autodefinidas por la shell, comandos de captura de variables, comandos para operaciones aritmticas, condicionales simples, condicionales mltiples, ciclos o 'loops', iteracin, el uso de funciones, y captura de seales. Dada la dificultad que conlleva el explicar cada comando con las posibles variantes con las que se puede aplicar, explicare con ejemplos genricos, los cuales podris 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 guin 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 bsico 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 cdigo, ya vimos anteriormente el uso del caracter '#' almohadilla el cual se puede utilizar antes de el comando a comentar o incluso en lneas que efecten 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
Identacin del cdigo La identacin del cdigo es algo extendido y normal en todos los lenguajes de programacin. Es un buen modo de ordenar de una forma visual el cdigo, 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 condicin. 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 parmetros o argumentos. Como bien sabemos, en un script podemos incorporar cientos de comandos, pero estos necesitan de argumentos para poder funcionarn shell-script que use siempre los mismos parmetros, nos servir una vez o dos.. pero lo realmente til es que podamos incorporar a nuestro script distintos argumentos para que funcione segn nos interese en cada momento. Estos parmetros se traducen en forma de variables dentro de nuestro script las cuales modificamos nosotros aadiendo o pasndoselas en el momento de lanzarlo lo llamaremos forma 'esttica', o haciendo que nos las pida en un momento determinado de su ejecucin, la cual llamaremos forma 'dinmica'.
Esto lo veremos mas claro aadiendo estas variables a nuestro script anterior #!/bin/bash #Paso de argumentos de forma 'esttica'. echo "primera opcin $1" echo "segunda opcin $2" echo "tercera opcin $3" #Variables autodefinidas echo "se ejecuta $0" echo "tengo $# argumentos" echo "los cuales han sido $*" cp #este comando necesita parmetros, 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 tercera primera opcin primera segunda opcin segunda tercera opcin tercera se ejecuta script2a tengo 3 argumentos los cuales han sido primera segunda tercera cp: falta un fichero como argumento Pruebe `cp --help' para ms informacin. salida de error: 1 rh3nt0n@rh3nt0n-laptop:~/scripts$
La salida del script seria la siguiente: rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script5 Dame un numero. 6 El resultado de el cuadrado de 6 es 36 rh3nt0n@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 operacin que realiza con la variable numero, la cual en este caso no es mas que una multiplicacin por si misma. Como se puede tambin observar 'escapamos' el carcter asterisco '\*' para que la shell no lo tome como metacarcter. Evaluar cadenas Para evaluar cadenas, ya sean cadenas de texto, ficheros, o nmeros, tenemos el comando 'test' el cual nos permite de una forma rpida y fcil 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 confusin 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 test test $1 = $2 # necesitamos dos argumentos al lanzar el script echo $? #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 comparacin 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 uno 0 rh3nt0n@rh3nt0n-laptop:~$ En caso de que introduzcamos dos argumentos distintos, la comparacin no ser verdadera, y por lo tanto nos devolver un 1: rh3nt0n@rh3nt0n-laptop:~$ bash script6 paquito paquita 1 rh3nt0n@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 script echo $? #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.
Ciclos o loops.
Uso de funciones Una funcin es un trozo de cdigo que se utilizara con frecuencia en un script, y que solo varia en una variable. Sintaxis: nombre_funcion() { cdigo a ejecutar en la funcin } Veamos un ejemplo: #!/bin/bash # determina par e impar de los nmeros que introduzcamos dinmicamente determinaPar() { # aqu empieza la funcin num=`expr $a % 2` if [ $num -eq 1 ];then echo "impar ; $a" else echo "par: $a" fi } # aqu termina la funcin echo "Dame tres nmeros" read a1 read a2 read a3 export a=$a1 determinaPar export a=$a2 determinaPar export a=$a3 determinaPar Si lo ejecutamos veremos que a cada variable introducida se le aplica la funcin, lo cual ahorra muchas lneas de cdigo ya que sin usar la funcin, tendramos que repetir continuamente el cdigo que contiene esta, para cada variable, con lo que esto conllevara. rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script12 Dame tres numeros
Captura de seales. Podemos hacer que nuestro script capture seales a la shell, lanzadas desde el teclado tipo 'crtl+c' y que la shell las ignore. Para esto, se usa el comando 'trap'. Comando 'trap'.Atrapa seales. Sintaxis: trap ordenes seal : trap seal <---- captura seal Veamos un ejemplo: #!/bin/bash # Ejemplo de trap trap mensaje 2 mensaje() { echo "no puedes pararme ;)" } while [ 1 -eq 1 ] # buble infinito do 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 script15 rh3nt0n@rh3nt0n-laptop:~/scripts$ bash script15 sb nov 18 23:46:52 CET 2006 sb nov 18 23:46:53 CET 2006 no puedes pararme ;) sb nov 18 23:46:54 CET 2006 sb nov 18 23:46:55 CET 2006 no puedes pararme ;) sb nov 18 23:46:56 CET 2006 sb nov 18 23:46:57 CET 2006 no puedes pararme ;) sb nov 18 23:46:57 CET 2006 sb nov 18 23:46:58 CET 2006 sb nov 18 23:46:59 CET 2006 [2]+ Stopped bash script15 rh3nt0n@rh3nt0n-laptop:~/scripts$ jobs [1]- Stopped bash script15 [2]+ Stopped bash script15 rh3nt0n@rh3nt0n-laptop:~/scripts$kill %1 rh3nt0n@rh3nt0n-laptop:~/scripts$ jobs [1]- Terminado bash script15 [2]+ Stopped bash script15 rh3nt0n@rh3nt0n-laptop:~/scripts$ kill %2 rh3nt0n@rh3nt0n-laptop:~/scripts$ jobs