Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
Administración de sistemas operativos Práctica 0: Programación de shell de shell scripts scripts
OBJETIVOS
Estudiar los principales aspectos del lenguaje bash para bash para programar shell programar shell scripts. scripts. Entender la filosofía de programación de shell de shell scripts mediante scripts mediante ejemplos sencillos.
TEMPORIZACIÓN El plazo de realización de esta práctica será de dos sesiones de laboratorio, cada una de dos horas para un total de cuatro horas.
BIBIO!RA"#A B$SICA %NI& ' IN%&( !)*a pr+ctica, -. edición Autor: ebastián ánchez Prieto ! "scar #arcía Población Editorial: $a%&a Edición: '00( COMPEMENTARIA E/ s0e// Bas0 )irección: http:// http://personal personales.ya.com/m es.ya.com/macprog/b acprog/bash.pdf ash.pdf Pro1ramación en BAS2 3 COMO de introd)cción )irección: http:// .ibibl http:// .ibiblio.org/p! io.org/p!b/Lin!"/ b/Lin!"/docs/#O$% docs/#O$%O/tran O/translation slations/es/pdf s/es/pdf/&ash /&ash ' Prog Pr og (n (ntr tro o') ')O* O*O. O.pd pdff
Página + ,
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación Programación de shell
scripts
PR$CTICA 4 Programación de shell de shell scripts TABA 5E CONTENI5OS6 *ntroducción+++++++++++++++ *ntroducción++++++++++++++++++++++++ ++++++++++++++++++ +++++++++ Primer programa de shell de shell ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ustituciones de órdenes por su salida+++++++++++++++++++++.. salida+++++++++++++++++++++.......( .....( &ecanismos de escape+++++++++++++++++ escape+++++++++++++++++++++++++++ ++++++++++.......( .......( arra in/ertida++++++++ in/ertida++++++++++++++++++ +++++++++++++++++++ ++++++++++..............( +..............( omillas simples+++++++++++++++++ simples++++++++++++++++++++++++++ ++++++++++..............( +..............( omillas dobles+++++++++++++++++ dobles++++++++++++++++++++++++++ ++++++++++++++1 +++++1 Paso de parámetros a un programa de shell de shell +++++++++++++++++++++1 +++++++++++++++++++++1 Algunas /ariables especiales de la shell la shell ++++++++++++++++++++++.1 ++++++++++++++++++++++.1 onstrucciones del lenguaje+++++++++ lenguaje+++++++++++++++++++ ++++++++++++++++...... ++++++.......2 .2 shift+++++++++++++++++++ shift++++++++++++++++++++++++++++ +++++++++++++++.......3 ++++++.......3 read+++++++++++++++++++ read+++++++++++++++++++++++++++++ +++++++++++++++.......4 +++++.......4 e5pr++++++++++++++++++++++++++++++++++.....60 7peradores aritm8ticos+++++++ aritm8ticos+++++++++++++++++ +++++++++++++++++++ ++++++++++...60 +...60 7peradores relacionales+++++++ relacionales++++++++++++++++ +++++++++++++++++++ +++++++++++..66 +..66 7peradores lógicos++++++++++++++++ lógicos++++++++++++++++++++++++++ ++++++++++++.....6' ++.....6' E/aluaciones++++++++++++++++ E/aluaciones++++++ +++++++++++++++++++ +++++++++++++++...6 ++++++...6 test 9para archi/os++++++++++++++++ archi/os++++++++++++++++++++++++++ ++++++++++++...6 ++...6 test 9para e/aluación de cadenas++++++++++++++++ cadenas++++++++++++++++++++++.....6++++++.....6test 9para e/aluaciones num8ricas++++++++++++++++++++++ num8ricas++++++++++++++++++++++...6...6if++++++++++++++++++++++++++++++++++++6( case++++++++++++++++++++++++++++++++++...62 ;hile+++++++++++++++++++ ;hile+++++++++ +++++++++++++++++++ ++++++++++++++.....63 +++++.....63 until++++++++++++++++++++++++++++++++++...64 for++++++++++++++++++++++++++++++++++.....64 brea<, continue ! e5it++++++++++++++ e5it++++++++++++++++++++++++ +++++++++++++...'6 +++...'6 select++++++++++++++++++ select++++++++++++++++++++++++++++ +++++++++++++++.....'6 +++++.....'6 =so de funciones en programas de shell de shell +++++++++++++++++++++..'' +++++++++++++++++++++..'' Ejercicios+++++++++++++++++ Ejercicios+++++++ ++++++++++++++++++++ ++++++++++++++++..'++++++..'Introd)cción El shell es un int8rp int8rprete rete de órdenes, órdenes, pero pero el shell no no es solamente eso> los int8rpretes de órdenes de =ni5 son aut8nticos lenguajes de programación. omo tales, incorporan sentencias de control de flujo, sentencias de asignación, funciones, etc. ?os programas de shell de shell no no necesitan ser compilados como ocurre en otros lenguajes. En este caso es el propio shell propio shell el el @ue se encarga de interpretarlos línea a línea. A estos programas se les conoce generalmente como shell scripts, scripts, ! son los e@ui/alentes a los archi/os por lotes de otros sistemas operati/os.
Página + -
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
abe destacar @ue a pesar de @ue en los sistemas =ni5 no e5isten las e5tensiones de los archi/os 9.txt , .exe, etc. es recomendable asignarle a los archi/os de script la e5tensión .sh, para @ue de esta manera sepamos @ue corresponde a un script particular escrito por nosotros. Esta práctica esta orientada al aprendizaje de la programación de shell script mediante el lenguaje bash 9bourne-a gain shell el cual es un lenguaje interpretado de programación @ue a!uda al administrador de sistemas a realizar la ma!or parte de las tareas necesarias, tanto en la automatización como en el arran@ue del sistema. En la presente práctica se ampliarán aspectos del lenguaje bash mostrando su aplicación para la programación de shell scripts. in embargo, la ma!or parte de las órdenes, definiciones de /ariables, constantes, etc. pueden utilizarse directamente por la línea de órdenes.
Primer pro1rama de shell amos a crear a continuación un sencillo shell script para mostrar cual /a a ser la t8cnica general para crear este tipo de programas. En primer lugar, lo @ue tenemos @ue hacer es elegir el nombre @ue le /amos a dar a nuestro programa. En nuestro caso debemos ser originales ! asignarles nombre en función de lo se pretenda @ue /a a ejecutar el script . A continuación in/ocaremos a nuestro editor fa/orito 9vim, emacs, gedit , kate, etc. e introduciremos dos líneas
Página +
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
de te5to correspondientes a dos órdenes =ni5. on ello generaremos un archi/o @ue contiene lo siguiente:
7 cat script8pr)e9a(s0 #!/bin/bash # Shell script de prueba who # Mostramos a los usuarios que están actualmente conectados en el sistema date # mprimimos la echa " hora del sistema 7 )ebido a @ue e5isten diferentes tipos de shell 9csh, sh, tcsh, sh, bash, etc., cada una con un conjunto de órdenes internas, es necesario @ue para el correcto funcionamiento de nuestros shell scripts, tengamos @ue indicar al comienzo del script cuál /a ha ser la shell @ue lo /a a interpretar. El modo de conseguirlo, es colocando una primera línea en el script @ue comience con los caracteres #! seguido de la ruta hasta el ejecutable de la shell a utilizar. Para conocer cual es la shell implementada en nuestro sistema podemos hacer uso del siguiente comando: ec0o 7S2E 9el resultado debe ser /bin/bash, ! lo @ue a@uí aparezca es lo @ue hemos de colocar despu8s de los caracteres #!.
NOTA6 En esta práctica sólo se describirá la sinta5is reconocida por bash. En caso de encontrar otra shell implementada en su sistema @ue sea diferente de bash fa/or de no continuar con la práctica e indicarle al docente dicho problema o probar establecer el shell bash como predeterminado mediante el uso del siguiente comando: c0s0 3s :9in:9as0. =na /ez creado el archi/o de te5to 9 script$prueba.sh, debemos cambiar sus atributos para @ue tenga derecho de ejecución. ?a forma de hacerlo es la siguiente:
7 c0mod ;< script8pr)e9a(s0 =na /ez cambiados los derechos, !a podemos ejecutar nuestro programa de la siguiente forma: (:script8pr)e9a(s0. ólo es necesario poner al archi/o el atributo de ejecución una /ez, puesto @ue una /ez cambiado, este atributo no se /erá modificado. Así pues, aun@ue /ol/amos a editar el archi/o, no será necesario utilizar de nue/o la orden chmod . ?os resultados de la ejecución del programa se muestran seguidamente:
7 (:script8pr)e9a(s0 gatewa" %& '&&(-&)-'* &&%+* mar ma" '* &)%,)%', S '&&( 7 Es posible 9e incluso recomendable, tal ! como hemos hecho en este primer ejemplo, aBadir comentarios a nuestros programas de shell , para ello, si una línea es de comentarios, debemos comenzar con el carácter # . S)stit)ciones de órdenes por s) sa/ida
Página +
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
Esta t8cnica consiste en sustituir el nombre de una orden por su salida estándar. Para realizar esta transformación, la orden ha de introducirse entre los caracteres especiales + 9tildes gra/es. Esta notación se conoce tambi8n como antigua sustitución de órdenes. Empleando esta notación se eliminan los caracteres de escape 90 @ue preceden a los caracteres especiales 1 ! 0 antes de ejecutar la orden. Esto permite incluir estos caracteres e/itando @ue sean interpretados por la shell . Ejemplo:
7 ec0o E/ directorio act)a/ de tra9a=o es6 >p?d> 2l directorio actual de traba3o es% /home/luis 7 Mecanismos de escape ?os mecanismos de escape son a@uellos @ue sir/en para e/itar @ue la shell interprete caracteres especiales o palabras reser/adas con un significado habitual, tomándolos entonces como literales. Estos mecanismos e/itan, por tanto, la e5pansión de parámetros o la sustitución de órdenes. ?os caracteres empleados como mecanismos de escape son la barra in/ertida 90, las comillas simples 945 ! las comillas dobles 9657. ‟
Barra invertida ?a barra in/ertida tiene las siguientes interpretaciones dependiendo de la situación en la @ue se encuentre: i no aparece encerrado entre comillas 9simples o dobles, se elimina ! el carácter al @ue precede es tomado como literal. i el carácter al @ue acompaBa es el de la línea nue/a, newline, tambi8n se elimina este carácter. Este comportamiento se denomina continuación de línea ! permite escribir te5to en /arias líneas ! @ue la shell las considere como una sola. i forma parte del te5to encerrado entre comillas simples mantiene su significado literal 9no es interpretada. uando se encuentra dentro de un te5to encerrado entre comillas dobles mantiene su significado literal, e5cepto cuando se usa para escapar los caracteres 1, 4 ! 6. Ejemplo:
7 ec0o @72OME es 72OME 189M2 es /home/luis 7 Comi//as simp/es ?os caracteres situados dentro de las comillas simples pierden su significado ! son tomados como literales. ?a comilla simple no puede aparecer dentro del literal puesto @ue delimitaría el final de la cadena. Ejemplo:
7 ec0o 72OME, , @n, /s 89M2: 6: 0n: ls 7 ec0o @ Esto se enc)entra dentro de6 @ D @ comi//as simp/es @ 42sto se encuentra dentro de% ;4... < comillas simples 7 ‟
‟
‟
‟
‟
‟
‟
‟
Página +
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
Comi//as do9/es Eliminan la interpretación de todos los caracteres @ue encierran e5cepto: 1, 4, 6 ! 0. Ejemplo:
7 ec0o @72OME es 72OMEF 189M2 es /home/luis 7 Paso de par+metros a )n pro1rama de shell A menudo @ueremos @ue nuestros programas de shell reciban parámetros desde la línea de órdenes para hacerlos más /ersátiles. Estos parámetros son los @ue se conocen como parámetros de posición. ?os parámetros de posición se pueden usar dentro de un programa del shell como cual@uier otra /ariable del shell > es decir, para saber su /alor utilizaremos el símbolo 1. ?os parámetros dentro del shell script son accesibles utilizando
$0 $epresenta al parámetro cero o nombre del programa. $1 $epresenta al parámetro uno.
+
$9 $epresenta al parámetro nue/e. Aun@ue una línea de
órdenes puede tener más de nue/e parámetros, un programa shell sólo puede acceder directamente a los primeros nue/e parámetros mediante 1=, 1', +, 1>> para parámetros superiores a nue/e se emplea la notación 1 ?n@mero$parametroA o se emplea la orden shit como se mostrará más adelante. í, por ejemplo, tenemos un programa de shell denominado prog.sh ! lo in/ocamos de la siguiente forma:
7 (:pro1(s0 datos -G s)ma )entro del programa de shell tenemos lo siguiente: 1& B ./prog.sh 1= B datos 1' B +) 1+ B suma amos a poner un ejemplo de un shell script @ue /isualiza los cuatro primeros parámetros @ue le pasemos. Al programa lo denominaremos param.sh, ! su contenido es el siguiente:
7 cat param(s0 #!/bin/bash
Página + 1
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
# 2ste script visualia los parámetros que le pasamos desde la lCnea de Drdenes echo Earámetro & B 1& echo Earámetro = B 1= echo Earámetro ' B 1' echo Earámetro + B 1+ 7
A/1)nas varia9/es especia/es de /a shell )entro de un programa de shell e5isten /ariables con significados especiales, algunas d elas cuales se citan a continuación: $# Esta /ariable guarda el nCmero de argumentos de la línea de órdenes 9e5clu!endo el nombre del programa. $* Esta /ariable guarda la cadena de argumentos entera 9e5clu!endo el nombre del programa. $? Esta /ariable guarda el código de retorno de la Cltima orden ejecutada 90 si no ha! error ! distinto de 0 si ha! error. $@ Esta /ariable representa la cadena de argumentos entera 9e5clu!endo el nombre del programa pero como una lista de cadenas, a diferencia de 1F @ue obtiene todos los argumentos como una Cnica cadena. amos a mostrar con un sencillo ejemplo el uso de estas /ariables. En este caso, el nombre del shell script será var.sh
7 cat var(s0 #!/bin/bash # Erograma shell que visualia las variables #: F " G echo Ha variable 0# vale% 1# echo Ha variable 0F vale% 1F cp # Ioramos un error "a que al comando cp le altan argumentos echo Ha variable 0G vale% 1G 7 omo podemos apreciar, cual@uier carácter susceptible de ser interpretado por la shell es precedido por el carácter backslash 9D para @ue pierda su significado especial. Ahora para probar el programa lo lanzamos con una serie de argumentos:
7 (:var(s0 )no dos tres c)atro Ha variable # vale% , Ha variable F vale% uno dos tres cuatro cp% alta un archivo como argumento Eruebe 4cp Jhelp para más inormaciDn. Ha variable G vale% = 7 ‟
omo podemos obser/ar, la /ariable 1G toma un /alor distinto de cero, puesto @ue la orden cp se ha ejecutado con errores. Es importante @ue si dentro de un programa de shell , se produce algCn error tomemos decisiones al respecto. omo /eremos más adelante, e5isten mecanismos para tomar diferentes caminos en función del resultado de la ejecución de una orden.
Constr)cciones de/ /en1)a=e
Página + 2
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
amos a /er seguidamente las construcciones del lenguaje típicas empleadas en los programas de shell . o /amos a realizar una descripción e5hausti/a de todas ! cada una de las construcciones, sino @ue nos /amos a centrar en lo empleado más comCnmente.
shift
inta5is: shift n Esta orden se utiliza para desplazar los argumentos, de manera @ue 1' pasa a ser 1=, 1+ pasa a ser 1', ! así sucesi/amente 9esto si el desplazamiento n es igual a 6. Es mu! utilizado dentro de los bucles. amos a poner un ejemplo con un programa @ue denominaremos shit=.sh, cu!o contenido se muestra a continuación:
7 cat s0iHt(s0 #!/bin/bash # Erograma de shell que muestra el uso de shit echo 01= vale% 1= echo 01' vale% 1' echo 01+ vale% 1+ shit ' echo Khora 01= vale% 1= echo Khora 01' vale% 1' echo Khora 01+ vale% 1+ 7 En el ejemplo anterior, al desplazar dos lugares tendremos @ue 1) pasa a ser 1+, 1, pasa a ser 1' ! 1+ pasa a ser 1=. ?os argumentos iniciales, 1= ! 1', se pierden despu8s del desplazamiento. amos a ejecutar el programa anterior:
7 (:s0iHt(s0 )no dos tres c)atro cinco 1= vale% uno 1' vale% dos 1+ vale% tres Khora 1= vale% tres Khora 1' vale% cuatro Khora 1+ vale% cinco
Página + 3
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
7 E/identemente este desplazamiento afecta tambi8n a las /ariables # ! F. eamos otro ejemplo, @ue denominaremos shi'.sh
7 cat s0iHt(s0 #!/bin/bash # 9tro e3emplo con shit echo 01# vale% 1# echo 0 1F vale% 1F shit ' echo Khora 01# vale% 1# echo Khora 01F vale% 1F 7 Al ejecutar el programa anterior, se produce el siguiente resultado:
7 (:s0iHt )no dos tres c)atro cinco 1# vale% ) 1F vale% uno dos tres cuatro cinco Khora 1# vale% + Khora 1F vale% tres cuatro cinco 7 ?a orden shit desplaza todas las cadenas en F a la iz@uierda n posiciones ! decrementa # en n. i a shit no se le indica el /alor de n, por defecto tomará el /alor 6. ?a orden shit no afecta al parámetro de posición 0 o nombre del programa. read
inta5is: read /ariable9s ?a orden read se usa para leer información escrita en el terminal de forma interacti/a. i ha! más /ariables en la orden read @ue palabras escritas, las /ariables @ue sobran por la derecha se asignarán a LHH. i se introducen más palabras @ue /ariables ha!a, todos los datos @ue sobran por la derecha se asignarán a la Cltima /ariable de la lista. En el siguiente ejemplo, el programa read=.sh /a a leer una /ariable desde la entrada estándar, ! posteriormente /a a /isualizar esa /ariable por la salida estándar. Ejemplo:
7 cat read(s0 #!/bin/bash # Erograma que ilustra el uso de la orden read # Ha opciDn Jn en la orden echo: se emplea para evitar el retorno de carro echo Jn ntroduce una variable% read var echo Ha variable introducida es% 1var 7
Página + 4
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
uando ejecutemos este programa, obtendremos el siguiente resultado:
7 (:read(s0 ntroduce una variable% ='+ Ha variable introducida es% ='+ 7 A continuación analizaremos el caso en @ue leemos más o menos /ariables de las @ue @ueremos leer desde el programa shell . Para ello, consideremos el siguiente programa, @ue lee tres /ariables. En un primer caso /amos a introducir sólo dos, ! en un segundo introduciremos más de tres /ariables. El código del programa en cuestión es el siguiente:
7 cat read(s0 #!/bin/bash # Erograma que lee varias variables con read echo Jn ntroduce las variables% read var= var' var+ echo Has variables introducidas son% echo var= B 1var= echo var' B 1var' echo var+ B 1var+ 7
eamos una ejecución normal en la @ue leemos tres /ariables:
7 (:read(s0 ntroduce las variables% +, hola >+( Has variables introducidas son% var= B +, var' B hola var+ B >+( 7 amos a ejecutar el programa anterior introduciendo sólo dos /ariables:
7 (:read(s0 ntroduce las variables% uno dos Has variables introducidas son% var= B uno var' B dos var+ B
Página + ,0
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
7 omo podemos obser/ar, la /ariable var+ @ueda sin asignar, puesto @ue sólo hemos introducido dos /alores. A continuación ejecutaremos de nue/o el programa, pero ahora introduciremos cuatro /ariables:
7 (:read(s0 ntroduce las variables% uno dos tres cuatro Has variables introducidas son% var= B uno var' B dos var+ B tres cuatro 7 En este caso a la /ariable var+ se le asignan todas las /ariables a partir de la dos. expr
inta5is: e5pr arg6 op arg' Fop arg +G ?os argumentos de la orden expr se toman como e5presiones ! deben ir separados por espacios en blanco. ?a orden expr e/alCa sus argumentos ! escribe el resultado en la salida estándar. El uso más comCn de la orden expr es para efectuar operaciones de aritm8tica simple !, en menor medida, para manipular cadenas 9a/eriguar la longitud de una cadena, filtrar determinados caracteres de una cadena, etc..
Operadores aritmKticos ?os siguientes operadores se utilizan para e/aluar operaciones matemáticas ! escribir el resultado de la operación por la salida estándar. ?as operaciones @ue podemos realizar son las siguientes: suma, resta, multiplicación, di/isión entera ! cálculo del resto de la di/isión entera.
+ uma arg' a arg=. - $esta arg' a arg=. * &ultiplica los argumentos. / )i/ide arg= entre arg' 9di/isión entera. % $esto de la di/isión entera entre arg= ! arg'.
En el caso de utilizar /arios operadores, las operaciones de suma ! resta se e/alCan en Cltimo lugar, a no ser @ue /a!an entre par8ntesis. o ha! @ue ol/idar @ue los símbolos F, ; ! < tienen un significado especial para la shell , por lo deben ser precedidos por el símbolo backslash o encerrados entre comillas simples. Ejemplo:
7 cat e
Página + ,,
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
echo -------------------------------------echo echo Jn ntroduce la primera variable% read arg= echo Jn ntroduce la segunda variable% read arg' resultadoBexpr 1arg= 0F arg' echo NesultadoB1resultado 7 El resultado de ejecutar el programa anterior es el producto de las dos /ariables leídas desde el teclado. eamos un uso particular:
7 (:e
Operadores re/aciona/es Estos operadores se utilizan para comparar dos argumentos. ?os argumentos pueden ser tambi8n palabras. i el resultado de la comparación es cierto, el resultado es uno> si es falso, el resultado es cero. Estos operadores se utilizan mucho para comparar operandos ! tomar decisiones en función de los resultados de la comparación. eamos los distintos tipos de operadores relacionales:
= Hon los argumentos igualesI != Hon los argumentos distintosI > HEs arg= ma!or @ue arg'I >= HEs arg= ma!or o igual @ue arg'I < HEs arg= menor @ue arg'I <= HEs arg= menor o igual @ue arg'I
o ol/ide @ue los símbolos O ! Ptiene significado especial para la shell , por lo @ue deben ser entrecomillados. Ejemplo:
7 cat e
Página + ,-
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
# Erograma de shell que determina si dos variables leCdas desde el # teclado son iguales o no echo echo Son iguales las variablesG echo ------------------------------- echo echo J n ntroduce la primera variable% read arg= echo Jn ntroduce la segunda variable% read arg' resultadoBexpr 1arg= B 1arg' echo NesultadoB1resultado 7 El programa anterior de/ol/erá cero si las dos /ariables introducidas son distintas ! uno si son iguales.
Operadores /ó1icos Estos operadores se utilizan para comparar dos argumentos. )ependiendo de los /alores, el resultado puede ser arg= 9o alguna parte de 8l, arg' o cero. omo operadores lógicos tenemos los siguientes:
| OR lógico. i el /alor de arg= es distinto de cero, el resultado es arg=> si no es así, el
resultado es arg'. " lógico. i arg= ! arg' son distintos de cero, el resultado es arg=> si no es así, el resultado es arg'. El arg' es el patrón buscado en arg=. i el patrón arg' está encerrado dentro de par8ntesis D9D, el resultado es la parte de arg= @ue coincide con arg'. i no es así, el resultado es simplemente el nCmero de caracteres @ue coinciden.
o ol/ide @ue los símbolos Q ! R deben ser entrecomillados o precedidos del símbolo 0, por tener un significado especial para la shell . eamos ahora algunos ejemplos en los @ue in/ocamos a expr desde la línea de órdenes:
7 aLG 7 aL>e
7 ec0o 7a 7 En este primer ejemplo hemos incrementado en una unidad el /alor de la /ariable a.
7 aLpa/a9ra 7 9L>e 7 ec0o 79 * 7 En este ejemplo hemos calculado el nCmero de caracteres de la cadena a. 7 aL=)nio844 7 9L>e ‟
Página + ,
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
7 ec0o 79 3unio 7 En este Cltimo ejemplo hemos determinado cuáles son los caracteres comprendidos entre la letra a ! la minCsculas en la cadena a.
Eva/)aciones ir/en para a/eriguar el /alor lógico de una determinada e5presión. Jabitualmente su uso se combina con una instrucción de bifurcación, como por ejemplo i . test (para archivos)
inta5is: test Kopción argumento F%opción argumentoG ?a orden test se usa para e/aluar e5presiones ! generar un /alor de retorno> este /alor no se escribe en la salida estándar, pero asigna cero al código de retorno si la e5presión se e/alCa como /erdadera, ! le asigna uno si la e5presión se e/alCa como falsa. e puede in/ocar la orden test tambi8n mediante F e5presión G, tanto a la derecha como a la iz@uierda de e5presión debe haber un espacio en blanco. test puede e/aluar tres tipos de elementos: archi/os, cadenas ! nCmeros. 7pciones:
- )e/uel/e /erdadero 90 si el archi/o e5iste ! es un archi/o regular 9no es un directorio ni
un archi/o de dispositi/o. -s )e/uel/e /erdadero 90 si el archi/o e5iste ! tiene un tamaBo ma!or @ue cero. -& )e/uel/e /erdadero 90 si el archi/o e5iste ! tiene permiso de lectura. -' )e/uel/e /erdadero 90 si el archi/o e5iste ! tiene permiso de escritura. -( )e/uel/e /erdadero 90 si el archi/o e5iste ! tiene permiso de ejecución. -) )e/uel/e /erdadero 90 si el archi/o e5iste ! es un directorio. Ejemplo:
7 test 3H arc0ivo- 7 ec0o 7 = 7 test 3H :etc:pass?d 7 ec0o 7 & 7
Página + ,
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
test para eva/)ación de cadenas inta5is: test cadena6 operador cadena' F cadena6 operador cadena' G Ejemplo:
7 aLpa/a9ra 7 7a L pa/a9ra 7 ec0o 7 = 7 7a L pa/a9ra 7 ec0o 7 & 7 )e esta manera, test e/alCa si las cadenas son iguales o distintas. uando se e/alu8 una /ariable del shell , es posible @ue dicha /ariable no contenga nada. onsideremos el siguiente caso: F L/ar M /t600 G i a var no le hemos asignado nada, el shell realizará la sustitución de /ariables, ! la orden @ue el shell intentará ejecutar será la siguiente: F M /t600 G ?o cual nos dará un error de sinta5is. =na forma sencilla de e/itarlo consiste en meter entre comillas la /ariable @ue /amos a e/aluar, ! así sabremos @ue la /ariable tomará el /alor LHH. F NL/arO M /t600 G i como en el ejemplo anterior, 1var no contiene ningCn /alor, la e5presión @ue /erá test , una /ez procesada por el shell será: F NO M /t600 G Esta e5presión es sintácticamente correcta ! no pro/ocara ningCn error de sinta5is.
test para eva/)aciones n)mKricas inta5is: test numero6 operador numero' F numero6 operador numero' G
Página + ,
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
En e/aluaciones num8ricas esta orden es sólo /alida con nCmeros enteros. ?os operadores usados para comparar nCmeros son diferentes de los usados para comparar cadenas. Estos operadores num8ricos son: -l &enor @ue. -le &enor o igual @ue. -g &a!or @ue. -ge &a!or o igual @ue. -e *gual a. -,e o igual a.
Ja! unos cuantos operadores @ue son /álidos en una e5presión de la orden test a la hora de e/aluar tanto archi/os como cadenas o nCmeros. Estos operadores son: -o 7$ -a A) ! 7
Ejemplo:
7 aL- 7 7a 3/t GG 7 ec0o 7 & 7 test 7a L - 7 ec0o 7 = 7 if
inta5is: if condicion6 then orden6 Felif condicion' then orden'G + Felse ordenG fi ?a construcción i se utiliza para tomar decisiones a partir de los códigos de retorno, normalmente de/ueltos por la orden test . ?a ejecución de la instrucción i es tal como sigue: 6. e e/alCa la condicion6.
Página + ,1
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
'. i el /alor de retorno de condicion= es /erdadero 90, se ejecutará orden=. . i esto no es así ! se cumple la condicion', se ejecutará la orden'. -. En cual@uier otro caso, se ejecuta orden+. Ejemplo:
7 cat iH(s0 #!/bin/bash # Shell script que muestra el uso de la sentencia de control i-i i test J /etc/hosts then cat /etc/hosts else echo 2l archivo no existe i 7 En el ejemplo anterior, si e5iste el archi/o /etc/hosts, entonces lo /isualizaremos. i no e5iste, imprimiremos por pantalla un mensaje diciendo @ue tal archi/o no e5iste. A continuación /amos a poner otro ejemplo, en el cual, si no e5iste un directorio, lo crearemos desde un programa de shell ! le habilitaremos los derechos de modo @ue sólo el propietario tenga acceso a 8l. El nombre del archi/o se le pasa como parámetro al shell script . El contenido del programa es el siguiente:
7 cat crea(s0 #!/bin/bash # 23emplo de uso de i. 2ste programa crea si ;no existe< el archivo que le # indiquemos desde la lCnea de Drdenes. Kl directorio reciTn creado sDlo # tendrá acceso el propietario del mismo. i U ! Jd 1= V then mkdir 1= chmod *&& 1= i 7 En el siguiente ejemplo /amos a diseBar un shell script @ue admita un argumento. i el argumento dado coincide con el nombre de un archi/o o directorio, deberá sacar por pantalla de @u8 tipo es. i es además un archi/o, deberá determinar si es ejecutable o no.
7 cat iH(s0 #!/bin/bash # Erograma shell que comprueba si existe un archivo pasado como argumento # " si existe muestra de que tipo es. i U 1# B & V then echo Webes introducir al menos un argumento. exit = i i U - 61=7 V then # 2s un archivo regular echo Jn 61= es un archivo regular 7 i U -x 61=7 V then
Página + ,2
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
echo 6e3ecutable.7 else echo 6no e3ecutable.7 i eli U -d 61=7 V then # 2s un directorio echo 61= es un directorio7 else # 2s una cosa rara echo 61= es una cosa rara o no existe7 i 7 i tambi8n puede utilizarse para comprobar el resultado de la ejecución de un programa e5terno, !a @ue todos los programas en =ni5 de/uel/en un /alor num8rico como resultado de su ejecución, @ue indica si dicha ejecución se lle/o a cabo correctamente o no. Por ejemplo, podemos diseBar un shell script @ue compruebe si e5iste un determinado usuario en el archi/o de contraseBas. Para ello /amos a utilizar una e5presión regular interpretada por grep. El programa de shell podría ser el siguiente:
7 cat comp8)s)ario(s0 #!/bin/bash # Erograma shell que comprueba la existencia de un usuario en el # archivo de contraseXas. i grep Jq 4Y 1=4% /etc/passwd then echo 2l usuario 1= "a existe en el sistema. else echo 2l usuario 1= no existe en el sistema. i 7 ‟
‟
Podemos ampliar el programa anterior para a/eriguar si el usuario, de e5istir, es un usuario regular 9su =*) es ma!or @ue 6000.
7 cat comp8)s)ario(s0 #!/bin/bash # Erograma shell que comprueba la existencia de un usuario en el archivo # de contraseXas " veriica si se trata de un usuario regular i grep Jq 4Y 1=4% /etc/passwd then echo 2l usuario 1= "a existe en el sistema. WBcat /etc/passwd Q grep 4Y 1=4% Q cut J+ J d4% i U W Jge =&&& V then echo 1= es un usuario regular. else echo 1= no es un usuario regular. ‟
‟
‟
‟
Página + ,3
‟
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
i else echo 2l usuario 1= no existe en el sistema. i 7 case
inta5is: case palabra in patron6 orden6 >> patron' orden' >> + patron orden >> esac ?a construcción case controla el flujo del programa basándose en la palabra dada. ?a palabra se compara, en orden, con todas las platillas. uando se encuentra la primera @ue corresponde, se ejecuta la lista de órdenes asociadas, la cual tiene @ue terminar con dos punto ! coma 9ZZ. Ejemplo:
7 cat case(s0 #!/bin/bash # Erograma que ilustra el uso de la sentencia de control de lu3o case-esac. diaBdate Q cut Jc &-+ case dia in lun< echo 8o" es Hunes ZZ mar< echo 8o" es Martes ZZ mie< echo 8o" es MiTrcoles ZZ 3ue< echo 8o" es [ueves ZZ vie< echo 8o" es \iernes ZZ sab< echo 8o" es Sabado
Página + ,4
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
ZZ dom< echo 8o" es Womingo ZZ esac 7 El programa anterior puede ser utilizado para saber el día de la semana, /isualizando los resultados en espaBol. 7bs8r/ese cómo en la /ariable dia almacenamos lo @ue retorna la orden date Q cut Jc &-+, @ue son las tres primeras letras del día de la semana. while
inta5is: ;hile condición do orden9es done ?a ejecución de la construcción while es como sigue: 6. e e/alCa la condición. '. i el código de/uelto por la condición es /erdadero 90, se ejecutará la orden u órdenes ! se /uel/e a iterar. . i el código de retorno de la condición es falso 96, se saltará a la primera orden @ue ha!a despu8s de la palaba reser/ada done. Ejemplo:
7 cat ?0i/e(s0 #!/bin/bash # Erograma que ilustra el uso de la sentencia de control de lu3o while. aB,' while U 1a Jle )+ V do echo contador B 1a aBexpr 1a ] = done 7 En el anterior ejemplo se incrementa ! /isualiza el /alor del contador mientras 8ste sea menor o igual @ue )+. Para ello, while comprueba el código de retorno de la orden U 1a Jle )+ V, ! si es cierto, se repite la iteración. until
Página + -0
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
inta5is: until condición do orden9es done ?a construcción until es mu! similar a la de while. ?a ejecución es como sigue: 6. e e/alCa la condición. '. i el código de retorno de la condición es distinto de 0 9falso, se ejecutará la orden u órdenes ! se /uel/e a iterar. . i el código de/uelto por la condición es 0 9/erdadero, se saltará a la primera orden @ue ha!a despu8s de la palabra cla/e done. Ejemplo:
7 cat )nti/(s0 #!/bin/bash # Erograma que ilustra el uso de la sentencia de control de lu3o until. until U 1a B hola V do echo Jn ntroduce una cadena% read a done 7 En el ejemplo anterior, el bucle until se ejecuta hasta @ue el usuario introduzca la cadena hola. A partir de este momento, la condición se /uel/e /erdadera ! se termina el bucle. for
inta5is: for /ariable in lista do orden9es done variable puede ser cual@uier /ariable del shell , ! lista es una lista compuesta de cadenas separadas por espacios en blanco o tabuladores. ?a construcción funciona como sigue: 6. '. . -. (.
e asigna a variable la primera cadena de la lista. e ejecuta orden. e asigna a variable la siguiente cadena de la lista. e /uel/e a ejecutar orden. $epetir hasta @ue se ha!an usado todas las cadenas. )espu8s de @ue ha!a acabado el bucle, la ejecución continua en la primera línea @ue sigue a la palabra cla/e done. Ejemplo:
7 cat Hor(s0 #!/bin/bash Página + -,
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
# Erograma que ilustra el uso de la sentencia de control de lu3o or. or i in manuel ana carlos miguel do mail 1i P carta done 7 En el ejemplo anterior se en/ía el archi/o carta a todos los usuarios indicados en la lista. i dentro del bucle or omitimos lista, se asumirá como lista el parámetro de posición 1^ @ue representa la cadena de argumentos entera e5clu!endo el nombre del programa. El siguiente ejemplo es una modificación del shell script 9i'.sh /isto en la parte correspondiente a i para @ue pueda tratar con /arios archi/os pasados como argumento. El código del programa es el siguiente:
7 cat modiHiH(s0 #!/bin/bash # Erograma shell que comprueba si existe un archivo pasado como argumento " si existe muestra de quT tipo es i U 1# B & V then echo Webes introducir al menos un argumento. exit = i or i in 1^ do i U - 61=7 V then # 2s un archivo regular echo Jn 61= es un archivo regular 7 i U -x 61=7 V then echo 6e3ecutable.7 else echo 6no e3ecutable.7 i eli U -d 61=7 V then # 2s un directorio echo 61= es un directorio7 else # 2s una cosa rara echo 61= es una cosa rara o no existe7 i # Khora desplaamos los argumentos shit done 7 break, continue y exit
Página + --
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
b&ea ., Jace @ue cual@uier bucle or , while o until termine ! pase el control a la siguiente
orden @ue se encuentre despu8s de la palabra reser/ada done.
co,i,e ., )etiene la iteración actual del bucle or , while o until ! empieza la ejecución de
la siguiente iteración.
e(i ., )etiene la ejecución del programa del shell ! asigna n al código de retorno
9normalmente cero implica 85ito, ! distinto de cero, error. Ejemplo:
7 cat e
inta5is: select i Fin listaG do orden9es done Esta sentencia /isualiza los elementos indicados en lista, numerados en el orden en @ue aparecen, en la salida estándar de error. i no se proporciona tal lista, 8sta es leída desde la línea de órdenes a tra/8s de la /ariable 1^. A continuación de las opciones numeradas indicadas en lista se /isualiza la cadena 9 prompt , indicada por la /ariable ES+. uando aparezca este prompt , tendremos @ue elegir una de las opciones indicadas en la lista introduciendo el nCmero @ue la identifica. i se introduce una opción /álida, se ejecutarán las órdenes asociadas. i como opción introducimos 2nter , el menC de opciones /ol/erá a ser /isualizado. ual@uier entrada @ue indi@ue el usuario será almacenada en el /ariable N2EH_ .
Ejemplo:
7 cat se/ect(s0 #!/bin/bash # Erograma que ilustra el uso de la sentencia select ES+B69pcion% 7 Página + -
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
select i Histado `uien Salir do case 1i in Histado< ls Jl ZZ `uien< who ZZ Salir< exit & ZZ F< echo 9pcion incorrecta esac done 7
%so de H)nciones en pro1ramas de shell )entro de los programas de shell se puede hacer uso de funciones. En una función podemos agrupar un conjunto de órdenes @ue se ejecuten con cierta frecuencia. ?as funciones ha! @ue declararlas antes de usarlas. Ejemplo:
7 cat H)nciones(s0 #!/bin/bash # Si no se pasan parámetros al programa se e3ecuta la unciDn error. 9bsTrvese # que para invocar a la unciDn no colocamos los parTntesis. Seguidamente # deinimos la unciDn error. error;< ? echo 2rror de sintaxis exit = A i U 1# B & V then error else echo 8a" 1# argumentos i 7 ?as funciones además pueden colocarse en otro archi/o aparte. )e esta forma podemos diseBar una biblioteca de funciones ! reutilizarlas en nuestros programas.
Página + -
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
omo ejemplo de aplicación de funciones /amos a diseBar una función @ue denominaremos espacio$ocupado;id$particion< @ue obtenga la cantidad de espacio ocupado de una partición de disco dada como argumento. Esta función la /amos a situar en un archi/o aparte denominado unciones.sh. Para diseBar la función partiremos de la información @ue nos aporta la orden d cu!a salida es similar a la siguiente:
7 dH S. icheros /dev/hda' none 7
=-blocks *+(,,', ==>',
sed &>&&* &
Kvailable >=>'+' ==>',
se Montado en (* / & /dev/shm
Esta orden nos informa de @ue la partición hda' tiene 1040021 b!tes ocupados. Podemos utilizar el filtro cut para obtener sólo este campo ! grep para localizar la línea @ue contiene la información sobre la partición en la @ue estemos interesados:
7 dH 3U 1rep :dev:0da tr 3s c)t 3H- 3d &>&&* 7 ‟
‟
=tilizamos el modificador Jk para @ue el resultado de d est8 e5presado en
7 cat H)nciones(s0 #!/bin/bash espacio$ocupado;< ? 2SEK9B d Jk Q grep /dev/1particion Q tr Js 4 Q cut J+ Jd4 A 7 ‟
‟
Para hacer uso de esta función desde otro script es necesario indicar en @ue archi/o se encuentra. Para esto se coloca al principio de la línea un punto, un espacio ! el nombre del archi/o @ue contiene la función con su camino 9 path si fuera necesario. El siguiente ejemplo muestra cómo incluir el archi/o unciones.sh ! cómo utilizar la función espacio$ocupado @ue acabamos de diseBar. El objeti/o es crear un script llamado espacio.sh @ue reciba como argumento el nombre lógico de una partición ! muestre un mensaje por pantalla informando del espacio ocupado en dicha partición.
7 cat espacio(s0 #!/bin/bash . ./unciones.sh particiDn 1= espacio$ocupado
Página + -
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
echo Ha particiDn 1= tiene ocupados 12SEK9 b 7
E=ercicios A. $ealice un programa de shell @ue compruebe si el mes actual es 3ulio o no. . $ealice un programa de shell @ue /erifi@ue si el usuario @ue lo ejecuta es root . En caso de @ue esta condición se cumpla se deberá mostrar por pantalla el siguiente mensaje: 6elcome root7. En caso de @ue el usuario @ue ejecuta el script no sea el root , mostrar el siguiente mensaje por pantalla: 62l usuario que e3ecutD el script ue% 1usuario7 . )onde 1usuario es una /ariable @ue contiene el usuario actual @ue ha ejecutado el script. . $ealice un programa de shell @ue compruebe si el usuario @ue esta ejecutando el script esta ubicado actualmente en su directorio de cone5ión o no. ). $ealice un programa de shell @ue reciba desde la línea de órdenes Cnicamente cinco nombres de personas ! se encargue de mostrarlas por pantalla ordenadas alfab8ticamente de forma descendente 9)e la Q a la A. o haga uso de ningCn archi/o para almacenar de forma temporal las palabras pasada al script desde la línea de órdenes. E. $ealice un programa shell @ue reciba desde la línea de órdenes los nombres de dos programas ejecutables. i tras la ejecución del primero se detecta algCn error, el segundo no se deberá ejecutar. enga en cuenta los posibles errores e indi@ue, si se produce alguno, de @u8 tipo es. R. $ealice un programa de shell @ue no reciba ningCn parámetro por la línea de órdenes ! @ue pide de forma interacti/a Cnicamente cinco nCmeros enteros. A cada nCmero ingresado, de forma interacti/a, por teclado se le deberá sumar uno ! por Cltimo todos los resultados deberán ser mostrados por pantalla de forma ascendente 9)e menor a ma!or. #. El administrador de istemas Miguel 8ernánde necesita elaborar un shell script @ue reciba como parámetro al menos una ruta 9Puede ser más de una, incluso muchas de algCn directorio e5istente dentro del sistema de archi/os del sistema @ue esta administrando. ?a idea @ue se persigue es generar un listado @ue contendrá todos los archi/os ! directorios 9*nclu!endo los ocultos @ue se encuentren dentro de cada una de las rutas pasadas como parámetro. )icho listado deberá estar ordenado por tamaBo ! deberá presentar el siguiente formato:
Nom9re
TamaWo en 9'tes
Importante6 erá necesario /erificar @ue el9los directorio9s pasado como parámetro9s e5ista9n dentro del sistema de archi/os.
Página + -1
Práctica 0: Programación de shell scripts
Laboratorio de Administración de Sistemas
Operativos
J. $ealice un programa de shell @ue al ejecutarlo cree un directorio dentro del directorio J7&E del usuario @ue lo ejecuta. El nombre del directorio será bac
*. $ealice un programa de shell @ue dado el nombre de un directorio pasado como parámetro, se encargue de pasar a minCsculas todos los archi/os ! directorios @ue este contenga en su interior 9*nclu!endo el nombre del directorio pasado como parámetro e indi@ue cuales fueron las incidencias @ue se /ieron modificadasSafectadas.
Importante6 erá necesario /erificar @ue el directorio pasado como parámetro e5ista dentro del sistema de archi/os. Pista6 erá necesario utilizar o bien una función recursi/a o bien una orden del sistema @ue permita recorrer recursi/amente los subdirectorios encontrados dentro del directorio pasado como parámetro. T. Elaborar un script @ue recorra todo el directorio /usr/lib buscando Cnicamente ficheros ordinariosSregulares de un tamaBo superior a 60 &. Para cada uno de ellos mostrará la opción de borrarlo, mo/erlo al directorio /tmp o no simplemente no hacer nada.
Importante6 ener cuidado al momento de borrar algCn archi/o, este puede ser indispensable para el correcto funcionamiento del sistema. A efectos de pruebas es recomendable colocar un archi/o creado por nosotros mismo ! probar la solución del script con dicho archi/o. U. rear un shell script de nombre quitar$espacios.sh. Este script deberá, automáticamente, renombrar todos los ficheros del directorio @ue se indi@ue como parámetro 9ólo se admitirá el paso de un Cnico parámetro, de modo @ue se cambien todos los espacios en blanco por guiones bajos 9El carácter V . Así, si en el directorio indicado como parámetro ha! un fichero nombrado como: Narta a pepito.txt O, al ejecutar el script se cambiará su nombre por: Narta V a V pepito.txt O. Esto debe hacerse automáticamente para todos los ficheros del directorio indicado como parámetro @ue tengan espacios en blanco en el nombre. Al finalizar, el script mostrará por pantalla cuántos ficheros han sido renombrados.
Importante6 Es obligatorio /erificarScomprobar @ue el directorio pasado como parámetro e5ista dentro del sistema de archi/os. ?. El administrador de sistemas NamDn lvare Montalván está lle/ando a cabo una tarea de aBadidura de usuarios al sistema, pero se ha encontrado con un problema. HWu8 cla/e de acceso al sistema debe colocar para los (000 usuarios @ue tiene @ue aBadirI, Herá @ue tiene @ue in/entar (000 cla/es de usuario diferentesI, o Herá @ue les debe colocar a todos la misma cla/eI.
Página + -2
Laboratorio de Administración de Sistemas Operativos
Práctica 0: Programación de shell
scripts
A!uda al administrador de sistemas a elaborar un shell scripts @ue genere de forma aleatoria las (000 cla/es diferentes para cada uno de los usuarios @ue necesita agregar al sistema. )icho shell script deberá solicitar por pantalla la cantidad de caracteres 9letras, nCmeros, caracteres especiales, etc @ue deberán tener dichas cla/es de acceso. i se ingresa una cantidad de caracteres igual a cero, inferior o igual a cinco se deberá informar por pantalla @ue las cla/es de acceso deben de ser de más de cinco caracteres. ?a cantidad de cla/es a ser generadas por el shell script deberá ser pasada como parámetro al momento de ejecutarlo. odas ! cada una de las cla/es generadas por el shell script deberán ser /olcadas a un archi/o de te5to llamado password$users.txt Consideraciones importantes6 alidar en todos ! cada uno de los ejercicios propuestos @ue la cantidad de parámetros pasados por la línea de órdenes sean e5actamente los @ue se piden. Por ejemplo: si se necesitan pasar dos parámetros para ejecutar el shell script entonces esto deberá ser /alidado 9o se deberá permitir @ue se ingresen menos de dos parámetros, ni más de dos parámetros> sino Cnicamente dos parámetros. En a@uellos casos donde no es necesario pasar ningCn parámetro para la ejecución del shell script tambi8n se deberá /alidar @ue no se pase ningCn parámetro 9?a cantidad de parámetros pasados por la línea de órdenes debe ser e5actamente cero
Página + -3