Diapositiva 1 - Academia de Software Libre Mérida
Transcripción
Diapositiva 1 - Academia de Software Libre Mérida
Andrés Arcia. Septiembre 2004. 1 Universidad de Los Andes Escuela de Ingeniería de Sistemas Departamento de Computación Mérida - Venezuela Programación Básica con Perl v0.1 beta Andrés E. Arcia Moret [email protected] Septiembre 2004 Andrés Arcia. Septiembre 2004. 2 CONTENIDO DEL CURSO PARTE I: Sobre la audiencia de este curso PARTE II: Generalidades sobre el estilo de programación PARTE III: Aproximación en espiral hacia Perl PARTE IV: Aspectos básicos del lenguaje Perl Ejercicios propuestos - Perl PARTE V CGI - Aspectos generales PARTE VI: Configuración de servidor Web para CGI PARTE VI: Técnicas de programación CGI con Perl Ejercicios propuestos - CGI Referencias Andrés Arcia. Septiembre 2004. PARTE I: Sobre la audiencia de este curso Un “ idioma” (language) de programación, es en cierta medida como un idioma con el que se comunican los seres humanos entre si. Para el caso de la computación, comunica al hombre y la máquina. Piense cuantos años tiene usted y si conoce a cabalidad su idioma materno. No pretenda dominar un lenguaje luego de un curso introductorio, pero si comience a utilizarlo regularmente para que emprenda 3 Andrés Arcia. Septiembre 2004. 4 Sobre la audiencia de este curso • Objetivos del Curso: – Aprender nociones elementales de las técnicas de programación. – Introducirnos en la programación Perl a través de la práctica. – Comprender cuales problemas podemos atacar efectivamente con Perl. – Crear una base propicia para la Andrés Arcia. Septiembre 2004. 5 Sobre la audiencia de este curso • ¿A quien va dirigido el curso? – Todas aquellas personas: • Que tengan conocimiento básico de algún otro lenguaje de programación. • Con pertinencias básicas en la programación. • Interesadas en el procesamiento de texto y generación de reportes. • Interesadas en la administración automática de sistemas operativos de redes. Andrés Arcia. Septiembre 2004. Parte II: Generalidades sobre el estilo de programación D. Knuth escribo refiriéndose a su programa Tex: Yo creo que el error final en Tex fue descubierto y removido el 27 de noviembre de 1985. Si de alguna manera el código contiene otro error, pagaré gustosamente la multa de $20.48 a la primera persona que lo descubra. Este es el doble de la cantidad anterior y pretendo doblarla en un año. ¿Se da cuenta que tengo confianza? ¿Cuántos programadores pueden darse ese lujo? 6 Andrés Arcia. Septiembre 2004. Generalidades sobre el estilo de programación • Como ninguno de nosotros puede (de lo contrario no estarí amos acá), entonces siempre es útil seguir ciertas normas para capturar los errores en el código mucho más rápidamente: – Sea expresivo. utilice nombres de variables relacionados con su acción. – Sea consistente. Utilice una convención para nombrar las variables. Por ejemplo: Las referencias a archivos siempre en mayúsculas, las variables enteras comienzan con “ int_” , para separar dos palabras se utiliza en subrayado “ _” , etc. – Sea organizado. Utilice la indentación para una mejor comprensión de la estructura de su programa. – Sea humilde. Asuma de facto que va a tener errores en su programa, entonces prepárese para ello no omitiendo los mensajes de error que el sistema le proporcione. 7 Andrés Arcia. Septiembre 2004. PARTE III: Aproximación en espiral hacia Perl 8 ¿Qué es una aproximación en espiral? Aproximarse en espiral hacia algún objeto de conocimiento, es partir desde lo mas elemental y, progresivamente ir añadiendo complejidad. El nombre “ espiral” se debe a una analogí a con la figura geométrica espiral, pues parte de un punto (lo elemental) y luego es posible ir añadiendo curvas sobre dicho punto de forma infinita. complejo sencillo Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl ¿Qué es Perl? Larry Wall, el inventor de Perl, describe este lenguaje en los siguientes términos: Perl es un lenguaje de programación interpretado, optimizado para el manejo de archivos arbitrarios de texto, extracción de información de esos archivos de texto, e impresión de reportes. Es también un buen lenguaje para la administración de muchos sistemas de computo. El lenguaje fue diseñado con la intención de ser práctico, fácil de usar, eficiente y completo, además de elegante, conciso y pequeño. Combina algunas de las mejores caracterí sticas de C, awk y sh... (tomado de [6]) 9 Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 10 Un poco de historia: • Creado por Larry Wall debido a dos cosas: su necesidad de crear reportes tal como se hacia en los Usenet-news y la incapacidad de awk. • Crecio de unos pocos Kb a unos poco Mb y de un solo creador a un conjunto programadores liderados por L.W. • La versión más reciente es la 5.008 de Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 11 • ¿Cómo conseguir perl? – Via HTTP, en CPAN (Comprehensive Perl Archive Network) • http://www.perl.com/CPAN/ • http://www.perl.com/CPAN/README.html • http://www.perl.com/CPAN/modules/ • http://www.perl.com/CPAN/ports/ • http://www.perl.com/CPAN/doc/ • http://www.perl.com/CPAN/latest.tar.gz – Via FTP: • ftp://ftp.CPAN.org/pub/perl/CPAN/src/latest.tar.gz – Generalmente viene ya instalado en cualquiera Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia perl 12 Programa Hola Mundo en Perl: hola-mundo.pl Indica camino donde esta el ejecutable de Perl en el sistema, y -w produce mensajes de #!/usr/bin/perl -w erroreso advertencias detallados Instrucción de salida print(“Hola Mundo!!!”); Transcribalo y ejecutelo. • Hacer el programa Hola Mundo permite: • • Comprobar la correctitud inicial del compilador. Asegurarnos de que entendemos como funciona el esquema de desarrollo en Perl. • Fijar el punto inicial de la espiral. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 13 Caracterí sticas generales de Perl • Perl (Practical Extraction and Report Languaje) es un lenguaje interpretado que es compilado cada vez que va a ejecutarse. • Se deriva de C principalmente, pero también de sed, awk, del lenguaje Shell y UNIX. • Todo programa Perl en Unix generalmente comienza con la siguiente lí nea: #!/usr/local/bin/perl #!/usr/bin/perl • Por lo general a los programas en Perl se le coloca la extensión • Cada lí nea termina con • Las Lí neas de comentarios se inician con ; . #. .pl. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl ¿Cómo recordar datos? print “¿Cuál es tu nombre:”; $name = <STDIN>; Las lí neas leí das de la consola traen un fin de lí nea \n. Nos deshacemos del fin de lí nea con el comando chomp. chomp($name); Y podemos incorporar el valor de la cadena a otro mensaje: print “Bienvenido al mundo Perl $name\n”; Transcribalo y ejecutelo. 14 Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 15 ¿Y si quisieramos ser amables con alguien en particular? Deberiamos comparar (eq) la entrada con su nombre: if ($name eq “Anastacio”) { print “Hola Anastacio, ¿Cómo has estado?”; } else { Transcribalo print “Hola $name”; } y ejecutelo. ¿Ha programado en C? ¿Qué diferencia nota en el constructo de comparación hecha en el if? Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl En los siguientes ejercicios Ud. encontrara instrucciones a las cuales Ud. encontrara que les falta ser definidas. No se preocupe, debe ser paciente muy pronto serán explicadas en detalle. En adelante se desarrollara el siguiente ejercicio: Supongamos que se desea hacer un programa que chequee claves de para diferentes usuarios. 16 Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 17 El usuario debe poder introducir un nombre y una palabra clave asociada al nombre. Mostraremos preferencia por el usuario “ knuth” dejando que proceda sin clave. Nuestro primer programa tendra una sola palabra clave (“ misterio” ) para el resto de los Palabras Reservadas usuarios. print, chomp, while, ne, <STDIN> if, Tipos escalar: $nombre_variable #!/usr/bin/perl –w print “Clave incorrecta”; $password=“misterio”; $try = <STDIN>; print “Nombre:”; chomp ($try); $name=<STDIN>; } #while chomp($name); }#if if ($name eq “Knuth”) { print “Bienvenido Don Knuth!”; } else { print “Hola $name”; print “Clave: “; $try=<STDIN>; chomp($try); while ($try ne $password) { Transcribalo y ejecutelo. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 18 Tomando las consideraciones del programa anterior, ahora deberí a poder manejar varias claves (misterio, intriga y sospecha) para una misma persona. Estas claves deben estar previamente definidas. Palabras Reservadas qw, elsif, eq Transcribalo y ejecutelo. #!/usr/bin/perl –w Tipos arreglo: @nombre_arreglo $guessed = “not”; @passwords=qw(misterio intriga sospecha); while ($guessed eq “not”) { print “Nombre:”; if ($passwords[$i] eq $try) { $name=<STDIN>; chomp($name); $guessed=“yes”; } elsif ($i<2) { if ($name eq “Knuth”) { print “Bienvenido Don Knuth!”; $i=$i+1; } else { } else { print “Clave incorrecta”; print “Hola $name”; $try = <STDIN>; print “Clave: “; chomp ($try); $try=<STDIN>; $i=0; chomp($try); $i=0; } } #while }#if Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 19 Ahora añadamos una tabla que contiene pares compuestos de personas y claves. Palabras Reservadas #!/usr/bin/perl –w Tipos hash: %nombre_tabla while ($try ne $password) { %pairs = qw { print “Clave incorrecta”; turing sospecha $try = <STDIN>; corbato misterio chomp ($try); lampson intriga }; print “Nombre:”; $name=<STDIN>; chomp($name); if ($name eq “Knuth”) { print “Bienvenido Don Knuth!”; } else { print “Hola $name”; $password=$pairs{$name}; print “Clave: “; $try=<STDIN>; chomp($try); } #while }#if Transcribalo y ejecutelo. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 20 Tratemos un poco con la entrada. Para hacer nuestro programa más versátil, podrí amos filtrar la data de entrada. Supongamos que Knuth introduce además su nombre, Knuth Donald. Queremos solamente conceder la entrada con solo observar su apellido. Palabras Reservadas =~ /^ \b /i \W . * A-Z a-z Tipos #!/usr/bin/perl –w Otra forma de hacerlo: @passwords=qw(misterio intriga sospecha); $name =~ s/\W.*//; print “Nombre:”; $name =~ tr/A-Z/a-z/; $name=<STDIN>; chomp($name); if ($name =~ /^knuth\b/i) { print “Bienvenido Don Knuth!”; } else { print “Hola $name”; print “Clave: “; $try=<STDIN>; chomp($try); $i=0; # continua ... Transcribalo y ejecutelo. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 21 Organicemos mejor el código haciéndolo más legible y eficiente a través de funciones. Palabras Reservadas sub, my, ||, ! #!/usr/bin/perl –w @_ while (!good_word($name,$try)) { %pairs = qw { print “Clave incorrecta”; turing sospecha $try = <STDIN>; corbato misterio chomp ($try); lampson intriga }; print “Nombre:”; Transcribalo y ejecutelo. Tipos } #while }#if $name=<STDIN>; chomp($name); if ($name =~ /^knuth\b/) { print “Bienvenido Don Knuth!”; } else { print “Hola $name”; print “Clave: “; $try=<STDIN>; chomp($try); sub good_word { my($somename, $someguess) = @_; $somename =~s/\W.*//; $somename =~tr/A-Z/a-z/; if ($somename eq “knuth”) { return 1; } elsif ($pairs{$somename} eq $someguess) { return 1; } else { return 0; } } Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 22 Podemos hacer que los pares <nombre, clave> sean extraí dos de un archivo. Para este tipo de problemas se creo Perl. Palabras Reservadas Tipos open, die, defined #!/usr/bin/perl –w chomp ($try); init_pairs(); print “Nombre: “; } #while }#if $name=<STDIN>; chomp($name); sub init_pairs { open (WORDLIST, “wordlist”) || if ($name =~ /^knuth\b/) { die “no se puede abrir: $!”; print “Bienvenido Don Knuth!”; while (defined ($name=<WORDLIST>)) { } else { chomp ($name); print “Hola $name”; $word = <WORDLIST>; $password=$pairs{$name}; chomp $word; print “Clave: “; $pairs{$name} = $word; $try=<STDIN>; chomp($try); while (!good_word($name,$try)) { print “Clave incorrecta”; } close (WORDLIST) || die “no pude cerrarlo: $!”; } $try = <STDIN>; Transcribalo completo y ejecutelo. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 23 Perl nos permite utilizar las bondades de los comandos UNIX, que han sido diseñados para ser reutilizados convenientemente por el cliente del sistema operativo. Palabras Reservadas Tipos |, close #!/usr/bin/perl –w sub good_word { %pairs = qw { my($somename, $someguess) = @_; turing sospecha $somename =~s/\W.*//; corbato misterio $somename =~tr/A-Z/a-z/; lampson intriga }; if ($someone eq “knuth”) print “Nombre:”; { return 1; $name=<STDIN>; } elsif ($pairs{$somename} eq $someguess) { chomp($name); if ($name =~ /^knuth\b/) { print “Bienvenido Don Knuth!”; } else { return 1; } else { open MAIL, “|mail root\@localhost”; print “Hola $name”; print MAIL “intento de fraude!\n”; $password=$pairs{$name}; close MAIL; … return 0; } } Transcribalo completo y ejecutelo. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 24 Ahora veamos como se hace para obtener las claves desde archivos con sufijo “ .secret” y que no tengan más de 7 dias. Por otro lado, veamos como se formatea un texto. Palabras Reservadas Tipos glob, -M, write, @<<<, format #!/usr/bin/perl format STDOUT = while(defined($filename = @<<<<<<<<<<<<< @<<<<<<< @<<<<<<<< glob(“*.secret”)) ) { open(WORDLIST, $filename) $filename, $name, $word . || die “no puedo abrir el archivo”; if (-M WORDLIST <= 7.0) { while ($name = <WORDLIST>) { format STDOUT_TOP = Pagina @<< chomp ($name); $% $word = <WORDLIST>; Filename chomp ($word); ============================== write; . Name Word } Transcribalo y ejecutelo. } close (WORDLIST) || die “no pude cerrarlo”; } Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 25 Ahora se desea mantener un registro del último momento en el que alguno de los usuarios hizo una entrada válida al sistema. Palabras Reservadas Tipos time, dbmopen, dbmclose #!/usr/bin/perl dbmopen(%last_login, “lastdb”, 0666) || die “no pude abrir la db: $!”; foreach $name (sort keys (%last_login)) { $when = $last_login{$name}; #agregar al final de algún programa dbmopen(%last_login, “lastdb”, 0666); $last_login{$name} = time; dbmclose(%last_login); $hours = (time()-$when) / 3600; write; } format STDOUT = Usuario:@<<<<<<<<<<<< entro hace @<<< horas. $name, $hours . Transcribalo y ejecutelo. Andrés Arcia. Septiembre 2004. Aproximación en espiral hacia Perl 26 Recapitulación: Hemos construido progresivamente un programa en Perl cada vez más complejo. Pasamos por los principales constructos que nos ofrece Perl. En la siguientes partes ahondaremos en cada una de las constructos que vimos someramente. Un programa Perl está compuesto de varias funciones y un código principal que funge de main() como en el lenguaje C. Las funciones pueden ir al estilo Pascal, es decir, final del programa ó, al estilo Tipos de 2004. datos disponibles Andrés Arcia. Septiembre PARTE IV: Aspectos básicos del lenguaje Perl ➢ ➢ Variables escalares ➢ Arreglos ➢ Arreglos asociativos ➢ Entrada y Salida Básica ➢ Manejadores de Archivos ➢ Expresiones Regulares ➢ Funciones ➢ Estructuras de control de flujo de programa ➢ Formatos ➢ Acceso y Manipulación de Directorios ➢ Procesos y Ejecución de Comandos de UNIX 27 Andrés Arcia. Septiembre 2004. 28 Aspectos básicos del lenguaje Perl Tipos EndePerldatos en Perl: existen pocos tipos de datos. Básicamente son tres: • Variables escalares. • Arreglos (vectores). • Arreglos Asociativos (hashes). En lugar de declarar las variables, esta van precedidas por un carácter especial: • $variable variable escalar normal. • @variable arreglo. • %variable arreglo asociativo. Es bueno recordar entonces que $variable, @variable y % variable son diferentes y completamente excluyentes. Compruebelo Variables escalares: Andrés Arcia. Septiembre 2004. 29 Aspectos básicos del lenguaje Perl Su función es almacenar un valor alfabético, numérico o alfanumérico. No hace falta declararla puesto que la primera vez que se utilice se esta implí citamente declarando. $nombre_variable=valor; Ejemplos de asignación a una variable escalar: $edad=29; Compruebelo # asignando un valor numérico $nombre=‘Andrés’; # asignando una cadena simple de texto. $nombre_edad=“$nombre tiene $edad años”; # cadena que contiene variables escalares. Algunas reglas importantes: ● Las cadenas pueden estar acotadas por comillas simples y existen dos caracteres especiales que se escriben de forma diferente: \’ la comilla y \\ el backslash. ● Las comillas dobles se utilizan para construir cadenas que llevan dentro otras variables. ● Los números octales se escriben precediéndolos de un cero, ej: 0874. ● Los números hexadecimales se escriben precediéndolos Compruebelo de 0x, ej: 0xFFF. ● El tipo númerico dentro del escalar permite todas las operaciones matemáticas comunes: +, Andrés Arcia. Septiembre 2004. 30 Aspectos básicos del lenguaje Perl La tabla que se encuentra a un lado corresponde a los valores especiales que pueden ser utilizados dentro de las cadenas de caracteres formadas con comillas simples o dobles. Diga las diferencias entre: \f \r \n Constructo \n Significado Nueva lí nea \r Retorno \t Tabulación \f Retorno de carro \b Retroceso (backspace) \a Campana \e Escape \006 Cualquier valor octal \x9f Cualquier valor hexadecimal \cC Cualquier caracter de control (^C o Ctrl-C) \\ Backslash \” Comilla doble \l Hacer minúscula la próxima letra. \L Hacer todas minúsculas hasta encontrar \E \u Hacer mayúscula la próxima letra. \U Hacer todas mayúsculas hasta encontrar \Q \E. Colocar limites con backslash a los caracteres \E no alfanuméricos hasta encontrar \E Terminar \L, \U o \Q Andrés Arcia. Septiembre 2004. 31 Aspectos Básicos del lenguaje Perl En la tabla adjunta se muestran los operadores más importantes Asociatividad No asociativo Operador ++ -- (autoincremetar y autodecrementar) utilizados en Perl. Están listados Derecha según el orden de asociatividad Izquierda =~ y precedencia. Izquierda correspondencia * / % x (multiplicación, división, modulo, Izquierda replica de cadenas). + - . (suma, resta, concatenación) No asociativo !~ correspondencia o no Operadores unarios como chomp y chop Izquierda && (y lógico) Izquierda || (o lógico) No asociativo Compruebelo ** (exponenciación) .. … (rangos) Derecha ? : (if – then –else) Derecha = += -= *= Ejemplos: 2 ** 2 ** 3 # 2 ** (2 ** 3), o 2 ** 8 = 256. 20 / 5 * 8 # (20 / 5) * 8 = 32 “el resultado es: “. (3*4) $a = $b + 2; ++$a; # lo mismo que: “el resultado es: “.12 Andrés Arcia. Septiembre 2004. 32 Aspectos Básicos del lenguaje Perl Arreglos y Listas: Una lista es un dato escalar ordenado compuesta de cero, uno o más elementos. Un arreglo asocia una variable con una lista de valores: @nombre_arreglo=(“elem1”,“elem2”,“...”,”elemn” ) Ejemplos: () # lista vacía. @colores=(“rojo”,”verde”,”azul”,2,4.5); # arreglo con cinco elementos. $colores[1]; # contenido del elemento Num.2 del arreglo (“verde”). $colores[3] = “naranja”; # agregando un elemento al arreglo. Constructor de una lista: (1..5) Compruebelo # lo mismo que (1,2,3,4,5) (1.2 .. 5.2) # lo mismo que (1, 2, 3, 4, 5) ($a .. $b) # rango determinado entre $a y $b. Una forma rápida de formar una lista de palabras es con el constructo qw (quoted word): @a = qw(uno dos tres cuatro); Andrés Arcia. Septiembre 2004. 33 Aspectos Básicos de Perl Arreglos y Listas: Algunas reglas importantes: • Una lista queda representada por dos parentesis ( ). • El separador entre un par de elementos es una coma “ ,” o un espacio. • Sobre las asignaciones: @num = (1,2,3); # asigna a @num la lista de tres elementos @otro = @num; @mas = (-2, -1, 0, @num, 4, 5); Compruebelo @masmas = (@num, “ya”); ($a,$b) = ($b,$a); Sobre los arreglos: $b = $mas[0]; # asigna -2 a $b Un elemento de una lista se accede como la variable escalar con el mismo nombre del arreglo seguido del subindice, que parte desde cero (0). Por otro lado también tenemos los cortes: @corte = @masmas[2,3]; • # asigna a @corte = (0,1); Los accesos fuera del rango devuelven undef. Andrés Arcia. Septiembre 2004. 34 Aspectos Básicos de Perl Arreglos y Listas: Algunas operaciones importantes: • Listas tratadas como pilas en el lado derecho de la lista: push(@lista, $valor); # equivalente a @lista = (@lista, $valor); $tope = pop(@lista); # equivalente a (@lista, $tope) = @lista; • Listas como pilas en el lado izquierdo de la pila: unshift(@lista, $a); # equivalente a @lista = ($a, @lista); $a = shift(@lista); # equivalente a ($a, @lista) = @lista; reverse (@lista); # invierte una lista sort(@lista); # ordena una lista según el orden alfabetico aún cuando se trata de números. <STDIN> también puede ser visto como un arreglo. @a = <STDIN> Compruebe el siguiente programa y expliquelo: #!/usr/bin/perl -w @linea = <STDIN>; chomp(@linea); print join(":",@linea)."\n"; Andrés Arcia. Septiembre 2004. 35 Aspectos básicos del lenguaje Perl Arreglos Asociativos (hashes) Estos arreglos están indizados por un valor escalar, a diferencia de los arreglos que están indizados por un valor entero no negativo. El valor escalar del í ndice sirve para posteriormente extraer el valor asociado. La sintaxis para definir un arreglo asociativo serí a: %nombre_del_hash=(‘clave1’,‘valor1’,‘clave2’,‘valor2’,...’claven’,valorn’); $nombre_del_hash{‘clave1’} = ‘valor1’; $nombre_del_hash{‘clave2’} = ‘valor2’; … $nombre_del_hash{‘claven’} = ‘valorn’; Ejemplos: Andrés Arcia. Septiembre 2004. 36 Aspectos básicos del lenguaje Perl %tabla=(120,2304,’abcd’,’efgh’); $data = $tabla{120}; # Asigna 2304 a $data Arreglo cliente con dos conjuntos de asociaciones $clave = “abcd”; # Asigna valor a futura clave. Compruebelo $tabla{$clave} = “ijk”; $otro_valor=$table{$clave}; # Genera valor para clave “abcd” El acceso a un arreglo asociativo es una función clave de todas rutinas CGI que decodifican formas HTML. Más adelante se verá esto con detalle. @clave = keys(%arreglo_asociativo); # Llama el arreglo @clave con todas las claves # de %arreglo-asociativo @valores = values(%arreglo_asociativo); # Llena @valores con valores de arregloasociativo • Iteraciones con hashes: while (($clave,$valor) = each(%tabla)) { print “La clave $clave tiene como valor $valor”; } Compruebelo • Para borrar un par especifico se utiliza la función delete: delete $tabla{”abcd”}; Andrés Arcia. Septiembre 2004. 37 Aspectos básicos del lenguaje Perl Estructuras de Control Bloques de sentencias Los bloques de sentencias que se ejecutan dentro de las estructuras de control van encerradas entre llaves ({}). Las condiciones o expresiones de las estructuras de control se evalúan verdadero o falso. El valor falso está dado por “0”, cadena vacia “” o el valor undef. - Condiciones if if (condición){ comandos }elsif (condición){ comandos }else{ comandos } - unless (el opuesto de if) unless (condición){ comandos }else{ comandos } Andrés Arcia. Septiembre 2004. 38 Aspectos Básicos del lenguaje Perl Estructuras de Control Un lenguaje de programación no estarí a completo si no existiese una forma de iteración. Perl; puede iterar utilizando el while. El while evalua la expresión y mientras sea verdadera continúa iterando. while (alguna_expresión) { sentencia_1; sentencia_2; … sentencia_n; } Otra forma de iterar es a través del until. El until itera de forma contraria al while, es decir, repite el bloque mientras la expresión sea falsa. until (alguna_expresión) { sentencias; } Andrés Arcia. Septiembre 2004. 39 Aspectos Básicos del Lenguaje Perl Estructuras de Control Sentencias evaluadas al final del ciclo de repetición: do { sentencia_1; sentencia_2; … sentencia_n; } while (alguna_expresión) Otra forma de iterar es a traves del until. El until itera de forma contraria al while, es decir, repite el bloque mientras la expresión sea falsa. do { … } until (alguna_expresión) Andrés Arcia. Septiembre 2004. 40 Aspectos Básicos del Lenguaje Perl Estructuras de Control Otras estructuras de repetición: for (exp_inicial; condición; exp_de_cambio) { sentencia_1; sentencia_2; … sentencia_3; } La estructura foreach: examina exhaustivamente todos los elementos de una lista: foreach $i (@lista) { sentencia_1; for ($i = 1; $i <=10; $i++) { sentencia_2; print “$i “; … } sentencia_n; Esta se mapea directamente a: expresión_inicial; while(condición) { sentencia_1; sentencia_2; … sentencia_n; expresión_de_cambio;} } Entrada/Salida Andrés Arcia. Septiembre 2004. 41 Aspectos básicos del lenguaje Perl • Imprimir valor de una variable: print • $var,”\n”; Imprimir cadena de caracteres: Compruebelo print “Que fácil es Perl !”; • Imprimir con formato: printf(“Me llamo %s y tengo %10d años.\n”, $nombre, $edad); • Leer entrada del teclado y asignarlo a una variable (sin carácter de fin de lí nea). chomp($var=<STDIN>); • • Escribir a la salida estandar (STDOUT). La función print escribe directamente sobre la salida estandar. Leer un archivo y procesarlo lí nea a lí nea: open (ENTRADA,”nombre_archivo”) || die ”No se pudo abrir nombre_archivo \n”; while (<ENTRADA>){ ejecutar_comandos; # La variable $_ contendrá el valor extraido. } Andrés Arcia. Septiembre 2004. 42 Aspectos básicos del lenguaje Perl Entrada y Salida • Leer archivo en un arreglo open (ENTRADA,”<archivo_entrada”)|| die “No se puede abrir archivo_entrada \n”; @arreglo = <ENTRADA>; close ENTRADA; • Compruebelo Salida hacia un archivo open (SALIDA,”>archivo_salida”)||die “No se puede abrir archivo para salida\n”; while (condición){ print SALIDA “Cualquier cosa”; } close SALIDA; Compruebelo Andrés Arcia. Septiembre 2004. Aspectos básicos del lenguaje Expresiones Regulares (ER) 43 Perl Una expresión regular es una representación abstracta de una cadena de caracteres. Se utiliza para buscar una o más ocurrencias de una cadena dentro de otra. Mediante las expresiones regulares también podemos hacer cambios dentro de una cadena. Operaciones con ER: • Búsqueda. Para buscar dentro de una cadena generalmente se utiliza la siguiente estructura: if ($var =~ /ER/) { … } Note que la instrucción completa está compuesta de una variable ($var), el operador de asignación de ER (=~) y un par de caracteres de división (//) que delimitan a la ER. Compruebelo Ej: $cadena = “abcdefghij”; if ($cadena =~ /def/) { … } En este ejemplo se pregunta si dentro de la variable $cadena se encuentra la subcadena “ def” ; lo que resulta cierto. Note que el valor devuelto es cierto o falso. Andrés Arcia. Septiembre 2004. 44 Aspectos básicos del lenguaje Perl Expresiones Regulares (ER) Sustitución. (ver tablas de las siguientes laminas) Por otro lado podemos sustituir una cadena por otra dentro de la cadena original; inclusive ¡ la cadena completa!. Para la sustitución se sigue el siguiente formato: $var =~ s/ER/cadena_de_reemplazo/; Ej: $cadena =~s/def/efd/; # la cadena resultante quedará “abcefdghij” Extracción. Muchas veces es necesario extraer subcadenas de alguna cadena más grande. Esta subcadena, como es de esperar, contiene un patrón que podemos expresar a través de expresiones regulares. $mensaje = “La dirección IP es 150.85.184.222”; @ip = ($mensaje =~ /(\d+\.\d+\.\d+\.\d+)/); print $ip[0]; # el primer IP que consiga en la cadena Compruebelo Andrés Arcia. Septiembre 2004. Patrones: 45 Aspectos básicos del lenguaje Perl Una expresión regular es un patrón. Un patrón esta compuesto por particiones de una cadena en caracteres y subcadenas. Patrones de un solo caracter: /[abcde]/ # coincide con cualquiera de las cinco primeras letras del alfabeto /[aeiouAEIOU]/ # coincide con cualquier vocal mayúscula o minúscula /[0123456789]/ # cualquier digito Compruebelo /[0-9]/ # lo mismo: cualquier digito /[0-9\-]/ # cualquier digito ó el signo menos /[a-zA-Z0-9_]/ # cualquier letra del alfabeto, digito ó el signo de subrayado Si añadimos el signo ^ de exponenciación, estamos negando la cadena que se interroga. /[^a-z]/ # cualquier carácter que no esté en las letras minúsculas del alfabeto Constructo \d digito \w carácter \s espacio Clase de Equivalencia [0-9] [a-zA-Z0-9_] [ \r\t\n\f] Cosntructo Negado \D sin digitos \W sin caracteres \S sin espacio Clase de Equivalencia Negada [^0-9] [^a-zA-Z0-9_] [^ \r\t\n\f] Andrés Arcia. Septiembre 2004. 46 Aspectos básicos del lenguaje Perl Patrones: Patrones de varios caracteres: Secuencias: secuencias simples de caracteres. /abc/ Multiplicadores: operadores que permiten replicar la cadena de caracteres sobre la que operan. $_ = “Este es un curso xxxxxxxx de Perl”; s/x+/introductorio/; quedaría: “Este es un curso introductorio de Perl”; Los multiplicadores son dos: * (asterisco) y + (mas). Con el asterisco puedo multiplicar cero o más veces a la cadena, mientras que con el más una o más veces. Por otro lado el punto “.“ sirve para indicar cualquier carácter excepto el fin de lí nea. Ej: La cadena “P xxxx e yyyy r zzzz l”, se corresponde con /P.*e.*r.*l/; También se puede forzar al operador a no ser tan voraz agregando un signo de interrogación (?) al asterisco: Ej: La cadena “P xxx e xxxxxxx e yyyyyyyy r zzzzzzzz l”, se corresponde con /P.*?e.*r.*l/; luego .*? será xxx y NO xxxxxx. Compruebelo Andrés Arcia. Septiembre 2004. Patrones: 47 Aspectos básicos del lenguaje Perl Patrones de varios caracteres: Memorias (Parentesis): Compruebelo Un operador paréntesis puede agrupar y recordar uno o varios caracteres. Con los paréntesis se puede tener memoria de patrones previamente encontrados. /a(.)b(.)c=a\1b\2c/; # Esta expresión encontraria un par de ecuaciones iguales, p.e. “a+b-c=a+b-c” Alternación: El operador de alternación sirve para escoger entre dos o más opciones. Es un OR entre varios patrones. /(kilo|mega)bytes/; # coincide con las palabras “kilobyte” o “megabyte”. Patrones de Anclas: Normalmente los patrones son evaluados sobre una cadena estrictamente de izquierda a derecha encontrando el primer patrón, esto a menos que se indique explí citamente que se haga de derecha a izquierda. Un ancla corresponde a puntos lí mites en la cadena. Un limite se define como el espacio entre un \w y un \W o viceversa. Esta diseñado, por ejemplo, para buscar dentro de expresiones aritmeticas por ejemplo. /Ana\b/; # Se corresponde con Ana pero no con Anaconda. Andrés Arcia. Septiembre 2004. 48 Aspectos básicos del lenguaje Perl COINCIDE CON: Cualquier carácter PATRON Cualquier número o carácter . El máximo de a’s consecutivas .* a* El mí nimo de a’s consecutivas a*? Uno o ninguno de cualquier carácter .? Uno o más de cualquier carácter .+ .{3,7} Entre 3 y 7 caracteres (el número máximo) .{3,} Al menos tres ocurrencias de cualquier carácter [ab] a ób [^ab] No a y no b [a-z] ^a Cualquier carácter de la a a la z \d a al comienzo de una cadena \s cualquier dí gito entre 0 y 9 (?#...) (F|f)rancia espacio o \t o \n Comentario Tabla 2: Patrones defrancia búsqueda Francia o Compruebelo Andrés Arcia. Septiembre 2004. 49 Aspectos básicos del lenguaje Perl QUE HACE COMANDO Sustituye la primera letra A en una cadena con B s/A/B/; Sustituye cada A con una B s/A/B/g; Sustituye varias a con una sola A s/A+/A/g; Borra el carácter # s/^#//; s/^/#/; s/A(\d+)/B$1/g; Agrega el carácter # al inicio de una cadena Sustituye una a seguida de un numero con una b seguida del mismo número s/(\d+)/$1*3/e; s/aquí fecha/$date/g; Sustituye el número encontrado con tres veces su valor s/(Mamá) (Papá)/$2 $1/g; Sustituye “ aquí fecha” con el valor de $date s/\00//g; Intercambia los dos términos s/$/\033/; Remueve los caracteres nulos en toda la cadena Agrega un ^M para hacerlo legible para DOS. Tabla 3: Patrones de sustitución Compruebelo Andrés Arcia. Septiembre 2004. 50 Aspectos básicos del lenguaje Perl Precedencia en los Patrones Los operadores sobre los patrones son evaluados según su precedencia. Representación Nombre Paréntesis ( ) (?: ) Multiplicadores ? + * {m,n} ?? +? *? {m,n}? Secuencias y Anclas abc ^ $ \A \Z Alternación | Tabla 4: Patrones abreviados ?: Agrupa como (...) pero no tiene memoria. Andrés Arcia. Septiembre 2004. 51 Aspectos básicos del lenguaje Perl Más ejemplos de ER Más ejemplos de patrones: /a./ # coincide con cualquier secuencia de dos letras que comience por a y no sea “a\n”. • • abc* # ab seguido de cero o más c. • (abc)* # cero o más veces abc • ^x|y # x al principio de la linea o cualquier y • ^(x|y) # x o y al principio de la linea • (a|b)(c|d) # cualquiera de estas: ac, ad, bc, bd. • $busqueda=“abcd”; if ($texto =~ /$busqueda/) print “Lo encontre…”; print “Desea continuar?”; $r = <STDIN>; if (!($r =~ /si\b|no\b/i)) MAY./min. #recuerde que la i no discrimina entre { print “por favor responda si o no”; } Uso de un delimitador diferente: El operador de expresiones regulares es la m, no obstante puede ser omitido. Compruebelo m@ab*c@ Andrés Arcia. Septiembre 2004. 52 Aspectos básicos del lenguaje Perl Ejemplos de uso de ER en programas: Ejemplo: Uso de la función split. Transcribalo completo y ejecutelo. expr_reg1.pl #!/usr/bin/perl -w $linea = “anabel::118:10:anabel:/home/anabel:/usr/bin/perl”; @campos = split(/:/,$linea); # se parte la $linea con : $i=0; foreach $campo (@campos) { $i++; $campo =~ s/^/$i/; #añadir el numero del campo al principio print “$campo\n”; } Ejercicio: La función join($delim, @lista) hace lo opuesto a split. Andrés Arcia. Septiembre 2004. 53 Aspectos básicos del lenguaje Perl Ejemplo: Sustituir todas las ocurrencias de una cadena en un archivo: (En el capí tulo IV se dan detalles de como manejar archivos) Transcribalo completo y ejecutelo. expr_reg2.pl #!/usr/bin/perl -w $sustituidas=0; open (ARCHIVO, “archivoxx.txt”); $linea=<ARCHIVO>; while(defined($linea)){ chomp($linea); if($linea=~s/WWW/World Wide Web/) { print(“$linea\n”); $sustituidas=$sustituidas+1; } $linea=<ARCHIVO>; } print(“Se hicieron $sustituidas sustituciones\n”); Andrés Arcia. Septiembre 2004. Aspectos del lenguaje Perl Ejemplo: Encontrar ocurrencias de básicos una cadena con caracteres especiales: Si queremos encontrar una cadena que contenga un URL, como éste: http://www.sun.com/ ...se necesitarí a elaborar el patrón de búsqueda siguiente: /http:\/\/www\.sun\.com\// lo que es un poco engorroso si hay muchos caracteres especiales en la cadena. Afortunadamente Perl permite al usuario definir su propio delimitador para una expresión regular. Usando esta caracterí stica, una forma elegante de hacerlo serí a la siguiente: m#http://www\.sun\.com/# Compruebelo 54 Andrés Arcia. Septiembre 2004. Subrutinas: 55 Aspectos básicos del lenguaje Perl Definir una Subrutina: sub misubrutina{ adquisición de argumentos; operaciones; retornar valor; Recibiendo argumentos: Como variables globales: sub misub{ @parametros_recibidos = @_; } Implicitamente dentro de cada subrutina se tiene # cuerpo de la función un arreglo @_ que permite acceder a cada uno return $valor_de_retorno; de los parámetros. También se tiene acceso a cada parámetro invocandolo asi: $_[i]. } sub misub{ Las variables declaradas fuera de la subrutina, ($parametro1,$parametro2) = @_; tienen validez dentro de cada subrutina en tanto # cuerpo de la función que no sean reemplazadas por un valor interno. return $valor_de_retorno; } Invocación de una subrutina: &misubrutina (@argumentos); &missubrutina (); Andrés Arcia. Septiembre 2004. 56 Aspectos básicos del lenguaje Perl Subrutinas: Variables de alcance local trascendente: Mediante el constructo local se pueden crear Variables de alcance local: Mediante el constructo my se pueden versiones locales aún de las variables globales, por supuesto, en caso de coincidir los nombres el valor global crear versiones locales aún de las variables será conservado y restaurado cuando la rutina culmine. La globales, por supuesto, en caso de coincidir los diferencia con my nombres el valor global será conservado y conservar el valor a través de las llamadas que se hacen restaurado cuando la rutina culmine. desde la rutina donde se declaro. sub suma { $valor = “ uno” ; my ($suma_total) &cual(); $suma_total = 0; &ejemplo(); foreach $_ (@_) &cual(); radica en que con local se puede { $suma_total += $_;} return $suma_total; sub ejemplo { } local ($valor) = “ dos” ; otras maneras de capturar los valores de entrada cual(); es: } my ($n, @valores) = @_; sub cual { print “ valor es $valor\n” ; Compruebelo Andrés Arcia. Septiembre 2004. 57 Aspectos básicos del lenguaje Apuntadores a Archivos Perl Un apuntador a archivo es una variable Perl que sirve de interfaz entre el lenguaje y la entrada/salida del sistema. Existen tres archivos básicos heredados en todo programa. Estos archivos tienen que ver directamente con la forma como se interactúa con el computador. STDIN representa un archivo que abstrae la entrada por teclado, es por naturaleza un archivo solo de entrada. STDOUT abstrae la salida en un archivo para salida, generalmente la pantalla y STDERR abstrae una salida, probablemente por pantalla o disco de los mensajes de error. STDOUT STDERR STDIN Andrés Arcia. Septiembre 2004. Apuntadores a Archivos Aspectos básicos del lenguaje 58 Perl Las operaciones sobre archivos son las siguientes: open (NOMBRE_APUNTADOR, “ nombre_en_disco” ); Asigna un apuntador a un nombre fí sico desde donde se manejará en adelante el archivo. Los archivos pueden ser abiertos en varias modalidades: Lectura: open(LECTURA, “<archivo”); Escritura: open(ESCRITURA, “>archivo”); Añadir: open(LOGGING, “>>log”); Para cerrar un archivo utilizamos: close(APUNTADOR); Para mostrar los mensajes de error que ocurran durante las operaciones anteriores utilizaremos die. Ej: open(ARCHIVO_DE_DATOS, “ /tmp/datos.txt” ) || die (“ No pude abrir el archivo. Error $!” ); Hacer un programa donde se lea de un archivo y se escriba en otro. Las lí neas escritas en el archivo de salida debe aplicarle algun filtro, p.e. remover todas las “ x” . Andrés Arcia. Septiembre 2004. 59 Aspectos básicos del lenguaje Perl Algunas Preguntas sobre los Archivos: Es posible mediante algunos modificadores efectuar preguntas del estado de los archivos: Significado permisologí a, existencia, propietario, etc. El archivo es de lectura Prueba Ej: print “¿Cuál archivo?”; -r El archivo es de escritura El archivo o directorio es ejecutable –w chomp($archivo = <STDIN>); -x if (-r $archivo && -w $archivo) -o { ... #busque en la tabla} -e -z Compruebelo El archivo o directorio es propio del usuario El archivo o directorio existe El archivo existe y tiene tamaño cero El archivo o directorio existe y no tiene tamaño cero -s -f La entrada es un simple archivo -d La entrada es un directorio -l La entrada es un enlace simbolico -p -b La entrada es un pipe (fifo) -T La entrada es un dispositivo por bloques (I/O) -B El archivo es tipo texto -M El archivio es binario -A -C Modificación en dias Acceso en dias Andrés Arcia. Septiembre 2004. 60 Aspectos básicos del lenguaje Perl Formatos Recordemos que significa Perl: Practical extraction and Report Language. Hasta ahora hemos lidiado con la mitad del significado, faltan los reportes. . Los formatos se hacen en tres pasos: 1) Definición del formato 2) Cargar la data dentro de las variables del formato 3) Invocar el formato Definificón del formato: format nombre_del_formato = linea_del_campo valor_uno, valor_dos, valor_tres linea del_campo valor_uno . Ej. format REPORTE = Mi nombre es @<<<<<<<<<< $nombre Andrés Arcia. Septiembre 2004. 61 Aspectos básicos del lenguaje Perl Formatos Para invocar un formato se utilza la función write. Esta función toma por omisión la salida estandar STDOUT, sin embargo puede ser cambiada. format ETIQUETA = -----------------------| Nombre: @<<<<<<<<<<<<| $nombre | Telefono: @<<<<<<<<<<| $telefono -----------------------. open (ETIQUETA, “>etiquetas“) || die “no pude abrir el archivo”; open (BASE_DE_DATOS, “direcciones” ) || die “no pude abrir el archivo”; while(<BASE_DE_DATOS>) { chomp $_; ($nombre, $telefono) = split(/:/, $_); write (ETIQUETA); } Compruebelo Andrés Arcia. Septiembre 2004. 62 Aspectos básicos del lenguaje Perl Formatos • Campos de Texto: Para la longitud se cuenta el @ más la cantidad de indicadores de posición. @<<<<<< Alineación hacia la izquierda. @>>>>>>> Alineación hacia la derecha. @||||||||||||||| Alineción centrada. • Campos Numerico: @#####.## • Los textos largos: @* • Tope de la página: format ETIQUETA_TOP = Esta es una etiqueta – Pagina @< $% . Para cambiar el formato por omisión se utiliza select(NOMBRE_DEL_FORMATO);. El formato por omisión es STDOUT. Andrés Arcia. Septiembre 2004. 63 Aspectos básicos del lenguaje Perl Acceso a Directorios En Perl existen equivalentes a los comandos operativo para operar sobre los archivos. chdir(“/tmp”); utilizados en el sistema # cambia de directorio @arreglo = glob(“/dir1/patron”); # selecciona un conjunto de archivos según el patrón @arreglo = </etc/host*>; while ($proximo = </etc/host*>) Compruebelo { $proximo =~ s#.+/##; print “archivo: $proximo”; } unlink($archivo); # borra un archivo o un conjunto unlink(“*.o”, “core*”); rename(“nombre_viejo”,”nombre_nuevo”); dispositivo. # renombra un archivo dentro del mismo link (“enlace”,”archivo”); # crea un enlace duro symlink(“enlace”,”archivo”); # crea un enlace suave mkdir(“nombre_directorio”, 0777); # crea un directorio con la permisología indicada. rmdir(“nombre_directorio”); # borra un directorio. chmod(0666, “archivo1”, “archivo2”); utime($hora_acceso_segs, $hora_modif_segs, “archivo”); # las estampillas de acceso y modificación. Andrés Arcia. Septiembre 2004. 64 Aspectos básicos del lenguaje Perl Manejo de Procesos Ejecutar un comando UNIX sin importar la salida: system(¨comando_unix¨, ¨arg1¨, ¨arg2¨); # retorna 0 si todo fue Ok. • Otra forma, asignando la salida a una variable (con “backticks”) $salida = `comando_unix`; • Se puede utilizar variables dentro de las invocaciones a system $archivo = “arch.”.++$i; # hacer el nombre del archivo. system “(date; who) >$archivo &”; • • Para reemplazar la ejecución del programa Perl por otro UNIX: (termina la ejecución del programa Perl) exec otro_programa_unix; Las variables de ambiente se guardan en el arreglo asociativo %ENV. foreach $key (sort keys %ENV) { print “$key=$ENV{$key}\n”; } Se pueden utilizar los pipes para pasar o extraer información de los procesos: • open (PROCESOWHO, “who|”); # abre la salida como archivo de lectura open (MAIL, “|mail amoret\@cemisid.ing.ula.ve”); # abre la entrada como archivo de escritura. Andrés Arcia. Septiembre 2004. 65 Aspectos básicos del lenguaje Perl Ejemplos • Guarda el resultado de la ejecución en una variable si la salida es solo una lí nea: chomp($date = qx!/usr/bin/date!); # El caracter separador es “!” # chomp remueve el caracter \n # “qx” significa: quote for execution Si la salida es una serie de lí neas ésta se guarda en un arreglo: chomp(@líneas_salida = qx!/usr/bin/who!); • Para cambiar el path: $ENV{“PATH”} = “/bin:/usr/bin:/usr/local/bin”; • Otra manera de crear procesos es con la instrucción fork. Una vez ejecutada esta instrucción se crea una copia identica al proceso donde se invoco. Luego este nuevo proceso llamado hijo, puede tomar cualquier otra forma. if (!defined($pid = fork()) { die “no puedo hacer fork: $!”; } elsif ($pid) { # Soy el padre, se retorna el PID del hijo } else { # Soy el hijo. PID = 0 } Para hacer al proceso hijo otro proceso utilizamos exec($ejecutable); Andrés Arcia. Septiembre 2004. 66 Aspectos Importantes para Recordar de Perl Variables predefinidas de Perl: $_ es el argumento por omisión. $@ es el arreglo de argumentos por omisión. $! variable que contiene el último error encontrado. Conductas: • Toda variable se inicializa en undef. • “ ” (vacio) está al principio y final de cada cadena. • Las listas tienen un operador copia versatil: ($a, $b) = ($b, $a); • Perl pasa desapercibido (a menos que estemos en modo depuracion –w) todos los errores de acceso a memoria desconocida o asignación fuera del rango. • Por omisión <> es <STDIN> y print imprime a STDOUT. • Hay operaciones de unión, eliminación, etc. implicitas ($a,@arreglo)=(@arreglo). • @ARGV almacena los parámetros de entrada al programa • @ENV almacena las variables de ambiente Resumen de funciones pre-construidas Andrés Arcia. Septiembre 2004. Aspectos A continuación se describen algunas de las básicos funcionesdel máslenguaje utilizadasPerl en la programación de un perl script, sin pretender ser un manual de referencia. Para una descripción del formato correcto se puede usar el comando: man perl abs: devuelve el valor absoluto de la expresión pasada. chmod 0777, 'arch': cambia los permisos de los archivos dados. chop: recorta y retorna el último carácter de una cadena. cown $uid, $gid, 'arch': cambia el propietario de los archivos dados. close : cierra un archivo. cos: devuelve el coseno del ángulo dado en radianes. defined: sirve para comprobar si existe una variable,formato, subrutina,etc.. delete: borra un valor de un array asociativo a través de su clave. die:imprime en la salida del error estándar un mensaje pasado como parámetro cuando ocurre un error en la ejecución de una sentencia. eof: retorna verdadero si el final del archivo dado. exec: ejecuta lo que pasemos como parámetro y sale del programa. exit: hace que salgamos del perl script devolviendo al sistema operativo el valor pasado como argumento. exp: retorna el numero e elevado a la potencia pasada como parametro. fileno: devuelve el descriptor del manejador del archivo pasado como parámetro. getc: lee el siguiente caracter del archivo especificado. hex: devuelve el valor decimal del numero hexadecimal pasado como parámetro. index: devuelve la posición de la primera ocurrencia de una cadena en otra. 67 Andrés Arcia. Septiembre 2004. Aspectos del básicos del pasado. lenguaje Perl length: devuelve la longitud en caracteres parámetro local: declara como locales las variables pasadas como argumentos. log: devuelve el logaritmo del numero dado. mkdir: crea un directorio en el camino dado. oct: devuelve el valor decimal del numero octal pasado como parámetro open: abre el archivo archivo dado asociandole un manejador de archivo especificado también como parámetro. pop: retorna y borra el ultimo elemento del array dado. print: muestra en la salida standard o en el archivo especificado la expresión dada. push: añade el valor dado al final del array pasado como parámetro. rand: devuelve un numero aleatorio entre 0 y el valor pasado como argumento. read: lee un determinado numero de caracteres desde el archivo pasado como argumento. rename: sirve para renombrar un archivo. return: devuelve un valor desde una subrutina. rmdir: borra un directorio. select: sirve para seleccionar el manejador de archivo que será utilizado por defecto para la salida de los comandos o funciones que no especifiquen un determinado manejador de archivo como parámetro. shift: devuelve el primer valor del array dado borrandolo posteriormente. sin: devuelve el seno del ángulo pasado en radianes. sleep: causa que el perl script o guión se detenga el numero de segundos especificados. sort: ordena el array dado. split: divide una cadena en subcadenas según el separador especificado. sqrt: devuelve la raí z cuadrada del numero pasado. system: igual que exec pero no se sale del perl script. write: escribe un registro con formato en el archivo asociado a ese formato. 68 Andrés Arcia. Septiembre 2004. 69 Ejercicios - Perl 6 y ejecutarlo en cualquier ventana 1) Transcribir el programa “ hola_mundo” de la lamina de comandos (tener cuidado con los permisos de lectura y ejecución en UNIX). 2) Transcribir, ejecutar y explicar el funcionamiento del siguiente programa perl: #!/usr/local/bin/perl print “Introduzca un valor entero y positivo”; $var1=<STDIN>; chop $var1; print “Introduzca otro valor”; $var2=<STDIN>; chop $var2; $var3=$var1+$var2; print “La suma de $var1 y $var2 es: $var3\n”; 3) Crear un programa que muestre en pantalla los números del 1 al 100. 4) Modificar el programa anterior para que sume los números pares del 1 al 100. 5) Transcribir, ejecutar y estudiar el siguiente código: #!/usr/local/bin/perl @var=(1,2,3,4,5); $indice=1; while($indice<=5); print(“Elemento $indice : $var[$indice-1]\n”; $indice=$indice+1; Andrés Arcia. Septiembre 2004. 70 ...Ejercicios 6) Realizar un programa que llene un arreglo con 5 cadenas de caracteres, lo ordene y lo imprima. 7) Transcribir, ejecutar y explicar el funcionamiento del siguiente programa: #!/usr/local/bin/perl $cadena=“Esto:es:una:prueba”; @arreglo=split(“:”, $cadena); print(@arreglo); 8) Crear un programa que cuente el número de palabras de un texto introducido por teclado (enter para finalizar). 9) Transcribir, ejecutar y explicar el funcionamiento del sig. programa: #!/usr/local/bin/perl if(open(ARCHIVO,”datos.txt”)){ $linea=<ARCHIVO>; while($linea ne “”){ print $linea; $linea=<ARCHIVO>; } } # fin de if Previamente se debe haber creado el archivo datos.txt, y debe contener algunas lí neas de Andrés Arcia. Septiembre 2004. 10) Modificar el prog. anterior para que ...Ejercicios imprima un mensaje de error en el caso que el archivo no exista o no se pueda abrir. 11) Leer el mismo archivo anterior dentro de un arreglo, ordenarlo e imprimirlo. 12) Crear un programa que cuente las veces que aparece la palabra “ Perl” en un archivo texto que contiene lo siguiente (crearlo): Perl es maravilloso El lenguaje Perl es facil y rapido de aprender. De ahora en adelante usare perl 13) Transcribir, ejecutar y estudiar el siguiente programa #!/usr/local/bin/perl print (“Teclee 5 numeros enteros:\n”); # enter entre ellos $sumar; print $valor; sub suma{ $valor=0; for($contador=1;$contador<=5;$contador++){ $num=<STDIN>; $valor=$valor+$num; } $valor; # Linea que se devuelve al programa } 14) Leer 3 números enteros del teclado y llamar a una subrutina que los sume e imprima 71 Andrés Arcia. Septiembre 2004. PARTE III: CGI - Aspectos generales • Qué es CGI • Usos generales y especí ficos • Ejemplos de Gateways • Lenguajes de programación para CGI 72 Andrés Arcia. Septiembre 2004. 73 Programación CGI: Aspectos Generales • Qué es CGI: Common Gateway Interface Protocolo de comunicación que permite a un servidor Web comunicarse con otros programas corriendo en el servidor. • Usos generales • Invocar programas en un servidor y recibir y desplegar la respuesta. • • Recibir y procesar datos de formas HTML. • Generar paginas Web Dinámicas (generados al vuelo). • Servir de Gateways a otros programas Usos especí ficos: • Motores de búsqueda Andrés Arcia. Septiembre 2004. 74 Programación CGI: Aspectos Generales Figura1: Ejemplo de Gateway hacia una Base de Datos Andrés Arcia. Septiembre 2004. 75 Lenguajes para CGI Lenguajes de programación que se pueden utilizar para una aplicación CGI: • C/C++ • FORTRAN • Perl • TCL • Phyton • Cualquier Shell de UNIX • Visual Basic • AppleScript, etc. Andrés Arcia. Septiembre 2004. 76 ...Lenguajes para CGI Condiciones para escoger lenguaje para CGI • Disponibilidad • Eficiencia/rapidez • Complejidad del problema • Número de corridas • Complejidad del lenguaje Andrés Arcia. Septiembre 2004. PARTE III: Configuración del servidor Web para CGI • Instrucciones Generales para Apache • Archivos de configuración global • Archivos de configuración por directorios • Definición de tipos de documentos 77 Andrés Arcia. Septiembre 2004. 78 Configuración del servidor Web para CGI Instrucciones generales para Apache Web Server: • Programas CGI residen en directorios especiales designados por el WebMaster. Por omisión tiene el nombre cgi-bin • Se puede configurar permisologí a de acceso y ejecución de programas CGI a través de archivos de configuración del servidor Web: Archivos en el ServerRoot /conf/srm.conf /conf/httpd.conf /conf/access.conf Archivo en directorios del DocumentRoot (y del usuario) .htaccess Tabla 1: Archivos de configuración necesarios Andrés Arcia. Septiembre 2004. 79 ...Configuración del servidor Web para CGI Configuración Global: (válida para todo el servidor Web) Archivo de configuración del servidor Web que se necesita modificar: [DocumentRoot]/ conf/srm.conf Pasos a seguir: • Designar un directorio como cgi-bin. • De ser necesario, designar otros directorios para ejecutar programas CGI. • Definir que tipo de documentos se ejecutaran como CGI’s (otras extensiones de archivos). Andrés Arcia. Septiembre 2004. 80 ...Configuración del servidor Web para CGI Ejemplo de archivo de configuración global: (parte de él) srm.conf . . Se designa a los directorios /urs/local/www/bin/ y /usr/ing/jlopez/public_html/cgi/ para contener programas CGI . ScriptAlias /cgi-bin/ /usr/local/www/bin/ ScriptAlias /bin/ /usr/ing/jlopez/public_html/cgi/ . . . Se define a los documentos con la extensión .cgi, .sh, .pl como programas CGI que deben ser ejecutados en vez de solo enviados. AddType application/x-httpd-cgi .cgi AddType application/x-httpd-cgi .sh AddType application/x-httpd-cgi .pl Configuración por directorios: (válida solo para un usuario particular) Andrés Arcia. Septiembre 2004. 81 ...Configuración del servidor Web para CGI • Un usuario puede colocar en sus directorios un archivo de configuración que contiene algunas instrucciones que le permiten ejecutar programas CGI. • Por omisión, el archivo donde se colocan las directivas que permiten esto, se llama: • .htaccess El WebMaster puede deshabilitar cualquier sobreescritura de la configuración global del servidor Web, o cambiarle el nombre al archivo de configuración por directorios, lo que implicarí a tener que pedir permiso para colocar los programas CGI donde el WebMaster lo indique. Andrés Arcia. Septiembre 2004. 82 ...Configuración del servidor Web para CGI Ejemplo de archivo de configuración por directorios: .htaccess Directiva que controla que clientes pueden accesar un directorio Orden en que se procesaran las directivas deny y allow Hosts que pueden acceder a este directorio (en este caso todos) <limit POST> order deny, allow allow from all </limit> Controla que opciones del servidor están disponibles en este directorio. En este caso se Options ExecCGI permite la ejecución de scripts CGI. Añade tipos de datos de extensiones a Addtype application/x-httpd-cgi .cgi ser manejados por el servidor Addtype application/x-httpd-cgi .pl Andrés Arcia. Septiembre 2004. PARTE IV: Técnicas de Programación CGI con Perl • Pasos para construir un script CGI • Entrada de un programa CGI • Variables de ambiente CGI • Procesando datos provenientes de formas HTML • Trabajando con archivos 83 Andrés Arcia. Septiembre 2004. 84 Pasos para construir un Script CGI 1.- Leer la entrada proveniente del usuario (de formas y/o variables de ambiente) 2.- Procesar los datos. 3.- Escribir la respuesta (HTML, texto, gráficos, etc.) en la salida estandar o en un archivo Figura 2: Etapas de un Script CGI Andrés Arcia. Septiembre 2004. 85 Técnicas de Programación CGI con Perl En las secciones subsiguientes iremos dando detalles de cada uno de estos pasos. Un programa Perl sencillo que ilustra los pasos descritos anteriormente se muestra a continuación: hola_cgi.pl Lugar en donde esta el ejecutable de perl en su sistema Cabecera requerida por el Browser. Capturando entrada del usuario Salida #!/usr/local/bin/perl print “Content-type:text/html”,”\n\n”; $query_string = $ENV{`QUERY_STRING`}; print “Salida de mi primer programa CGI \n”; print “Su entrada fue: $query_string \n”; Andrés Arcia. Septiembre 2004. 86 Entrada de un programa CGI Entrada de un Programa CGI Cuando un programa CGI es llamado, la información que se enví a a éste puede provenir de 3 fuentes: 1- Variables de ambiente CGI: información sobre el cliente, el servidor y el usuario. 2- Datos de una forma HTML: datos que el cliente llenó en una forma. 3- Información adicional (pathname). Andrés Arcia. Septiembre 2004. 87 Variables de ambiente CGI Variables de Ambiente CGI Debido a la importancia de las variables de ambiente a continuación se mostrará una lista de las más usadas, así como un ejemplo de cómo utilizarlas en un programa CGI. SERVER_NAME REQUEST_METHOD Nombre del host o su dirección IP Método con que la información fue enviada (GET o POST) PATH_INFO Información extra enviada en el path QUERY_STRING Información pasada al programa. Se añade al URL después del sí mbolo “ ?” REMOTE_HOST Nombre del host del usuario que esta solicitando un documento o programa CONTENT_TYPE Tipo MIME de los datos como por ej.: “ text/html” CONTENT_LENGTH Tamaño de los datos enviados al programa CGI a través de la entrada estandar HTTP_USER_AGENT Browser que el cliente está usando para la solicitud HTTP_REFERER URL del documento que activo el programa CGI Tabla5: Variables de ambiente CGI Andrés Arcia. Septiembre 2004. 88 ...Variables de ambiente CGI Programa que muestra algunas variable de ambiente VarAmbiente.pl #!/usr/local/bin/perl print “Content-type:text/html”,”\n\n”; print “<HTML><HEAD><TITLE>variables CGI</TITLE></HEAD>”,”\n”; print “<BODY><H1>variables CGI </H1>\n”; print “<HR><PRE>”; print “Nombre del Servidor:”, $ENV{‘SERVER_NAME’}, “<BR>\n”; print “Su Browser:”, $ENV{‘HTTP_USER_AGENT’}, “<BR>\n”; print “Software Servidor:”, $ENV{‘SERVER_SOFTWARE’}, “<BR>\n”; print “<HR></PRE>\n”; print “</BODY></HTML>\n”; exit (0); La salida de este programa serí a más o menos así : <HTML> <HEAD><TITLE> Nombre del Servidor: mozart.ing.ula.ve Su Browser: Microsoft Internet Explorer Software Servidor: NCSA/1.4.2 </BODY></HTML> Andrés Arcia. Septiembre 2004. 89 Procesando datos provenientes de formas HTML Uno de los principales usos de un programa CGI, es de recibir datos de una forma HTML desde un Web Browser, procesarlos y responder al usuario de forma adecuada. En la siguiente figura se ilustra la forma como un usuario interactúa con un programa CGI: www browser servidor (en el cliente) Aplicación CGI Usuario Usuario solicita Forma 1 Usuario llena Recupera Forma Se enví a forma 2 forma t 3 al cliente Se enví an datos a programas CGI 4 Usuario enví a forma Salida recibida 6 Enví a Salida a cliente INTERNET / LAN Interacción con programa CGI 5 Procesa Enví a salida a Servidor los datos Andrés Arcia. Septiembre 2004. 90 ...Procesando datos provenientes de formas HTML Enviando datos al programa CGI en el URL Una de las maneras de enviar datos a un programa CGI es añadir la información como parte del URL, después de un signo de interrogación, como en el siguiente ejemplo: http://una.maquina.com/cgi-bin/programa.pl?dato URL de la máquina Query String camino y nombre del servidora programa CGI recibe1.pl #!usr/local/bin/perl print “Content-Type: text/plain”,”\n\n”; $query_string = $ENV{‘QUERY_STRING’}; if ($query_string eq “Andrés”){ print “Hola Andrés!”;} elsif ($query_string eq “Knuth”){ print “Hola Knuth”; }else {print “$query_string”;} exit(0); Andrés Arcia. Septiembre 2004. CGI 91 ...Procesando datos provenientes de formas HTML Pasos para decodificar datos provenientes de formas HTML A continuación enumeramos los pasos necesarios para que un programa CGI pueda completar la tarea de decodificación de datos provenientes de una forma HTML: 1.- Determinar el protocolo de solicitud (GET o POST) revisando la variable REQUEST_METHOD. 2.- Si el protocolo es GET, leer los datos enviados a través de la variable QUERY_STRING (PATHINFO) 3.- Si el protocolo es POST, determinar el tamaño de los datos a recibir usando la variable CONTENT_LENGTH y leer dicha cantidad de datos desde la entrada estándar. 4.- Separar de QUERY_STRING las cadenas unidas con el carácter “ &” el cual separa los pares “ nombre - valor” . El formato de QUERY_STRING es: nombre1=valor1&nombre2=valor2... nombren=valorn) 5.- Decodificar los valores hexadecimales y “ +” dentro de cada par “ nombre-valor” 6.- Crear una tabla de nombres y valores con el nombre como í ndice (usando Andrés Arcia. Septiembre 2004. 92 ...Procesando datos provenientes de formas HTML El siguiente código HTML crea una forma de solicitud de información: mi_forma1.html <HTML> <HEAD><TITLE>Mi Primera Forma! </TITLE></HEAD> <BODY> <H1>Forma Sencilla </H1> <HR> <FORM ACTION= “/cgi-bin/procesa-forma1.pl” METHOD=“GET”> Escriba su nombre:<INPUT TYPE=“TEXT” NAME=“nombre” SIZE=30> <p> <INPUT TYPE=“submit” VALUE=“Enviar Forma!”> <INPUT TYPE=“reset” VALUE=“Limpiar Forma”> </FROM> </BODY> </HTML> Andrés Arcia. Septiembre 2004. 93 ...Procesando datos provenientes de formas HTML El siguiente programa maneja los datos de la forma descrita anteriormente: leeforma.pl Se lee la entrada desde variable QUERY_STRING Se leen los datos desde la entrada estándar Se separan los datos Se enví an los datos a la salida #!/usr/local/bin/perl $request_method = $ENV{‘REQUEST_METHOD’}; if ($request_method eq “GET”){ $entrada_forma = $ENV{‘QUERY_STRING’}; }else{ $tamaño_entrada=$ENV{‘CONTENT_LENGTH’}; read (STDIN, $entrada_forma,$tamaño_entrada); } ($nombre,$entrada) = split (/=/, $entrada_forma); print “Content-Type: text/plain”,”\n\n”; print “Hola $entrada”; Andrés Arcia. Septiembre 2004. 94 ...Procesando datos provenientes de formas HTML En el ejemplo anterior se realizó el proceso básico de decodificación; la lí nea. Decodificando los datos de la forma ($nombre, $entrada)=split (/=/,$entrada_forma); separó la entrada (de la variable $entrada_forma), en 2 variables ($nombre y $entrada). El problema surge cuando se enví a caracteres especiales (%,/,$.etc) Los cuales son enviados al servidor codificados en formato hexadecimal. Si en la forma de entrada hubiéramos escrito: “Andrés Arcia/Hola” la variable $entrada_forma tomarí a el valor “nombre=Andrés+Arcia%2FHola” por lo que necesitamos “ decodificar” dichos datos para reponer los datos enviados a su forma original. En las notas se muestra una subrutina que extrae y decodifica los datos de una forma. Andrés Arcia. Septiembre 2004. 95 ...Procesando datos provenientes de formas HTML Existe una los técnicadatos que permite salidacorreode un programa Enviando deredireccionar formas lapor hacia el interpretador e de comandos “ prompt” de cualquier programa UNIX que reciba ordenes desde su propio (mail,gruplot,maple,etc). A esta técnica se le da el nombre de: “ Pipe output” (abrir “ pipe” de comandos o gateways hacia programas UNIX). (Ver ejemplo de mail gateway en [1] pp 215) Revisar y estudiar en el siguiente URL, el listado completo de un programa genérico que enví a datos de una forma HTML por correo electrónico: http://www.cecalc.ula.ve/documentacion/cursos-talleres/CGI/formmail.pl.txt (a los participantes se les facilitara este archivo) Andrés Arcia. Septiembre 2004. 96 Abriendo archivosTrabajando con archivos En programación CGI, es muy frecuente el uso de archivos del file system del servidor: archivos temporales, archivos de usuario, de contadores de acceso, de estadí sticas del servidor Web, de errores, de bases de datos, de configuración. etc. En Perl, la función open abre un archivo y crea un filehandle (manejador) o nombre asociado, con el cual va a manipular y referirse al archivo. Este filehandle es solo un nombre que se le da al archivo, dispositivo, socket o pipe (punto anterior), que ayuda a recordar a cual archivo se esta uno refiriendo. La sintaxis de la función open (para leer un archivo existente) es la siguiente: open(NOMBRE_MANEJADOR, “nombre_de_archivo”); Andrés Arcia. Septiembre 2004. 97 ...Trabajando con archivos Es muy útil y sencillo, traspasar el contenido de un archivo a un arreglo. El siguiente ejemplo imprime la lista de empleados del ejemplo anterior ordenada alfabéticamente por sus nombres: empleados2.pl #!/usr/local/bin/perl print “Content-Type: text/plain”,”\n\n”; open (EMPLEADOS, “/usr/BD/empleados.txt”) or die “No se puede abrir empleado.txt:$!\n”; while ($linea=<EMPLEADOS> { ($nombre,$edad,$cedula) = split(“::”,$linea); $arreglo_empleados{$nombre} .= $edad . “” . $cedula; } foreach $nombre (sort keys %arreglo_empleados){ ($edad,$cedula) = split (“$”, $arreglo_empleados{$nombre}); print “$nombre\t $edad\t $cedula\n”); } Andrés Arcia. Septiembre 2004. 98 ...Trabajando con archivos Una solución más sencilla serí a: empleados3.pl #!/usr/local/bin/perl print “Content-Type: text/plain”,”\n\n”; if (open(EMPLEADOS, “/usr/BD/empleados.txt”)){ @arreglo_empleados=<EMPLEADOS>; } print (@arreglo_empleado); (No sale ordenada la lista de empleados) Andrés Arcia. Septiembre 2004. 99 Ejercicios propuestos - CGI A continuación se proponen una serie de problemas prácticos para ser resueltos independientemente (bajo supervisión del instructor). 1.- Llenado, consulta y modificación de bases de datos de texto: • Glosario de términos y definiciones • Base de datos de personal 2.- Análisis de archivos log del Sitio Web (estadí sticas de acceso al sitio web) 3.- Enví o de planillas HTML por Correo Electrónico 4.- Gateways a otros programas: • Interface al correo electrónico (o a otra aplicación) 5.- Libro de sugerencias o de visitas (guestbook) 6.- Encuesta electrónica. 7.- Herramienta de búsqueda. 8.- Generador dinámico de gráficos. Andrés Arcia. Septiembre 2004. • [1] Referencias Shishir Gundavaram. CGI Programming on the World Wide Web. O’Reilly, 1996 http://www.ora.com/catalog/cgi/noframes.html • [2] Randal Schwartz & Tom Christansen. Learning Perl. O’Reilly. 1997 http://www.ora.com/catalog/lperl2/ • [3] Larry Wall et al. Programming Perl. O’Reilly.1996 http://www.ora.com/catalog/pperl2/noframes.html • [4] Stephen Spainhour & Valerie Quercia. WebMaster in a Nutshell. O’Reilly.1996 http://www.ora.com/catalog/webmaster/noframes.html • [5] Servidor Web Apache: http://apache.org/ • [6] Sitio oficial de Perl: http://www.perl.com/ • [7] CGI Programming FAQ: http://www.webthing.com/tutorials/cgifaq.html • [8] Matt's Script Archive: http://www.worldwidemart.com/scripts/ • [9] The CGI Resource Index: http://www.cgi-resources.com/ • [10] Perl FAQ Index: http://language.perl.com/faq/ 100 Andrés Arcia. Septiembre 2004. 101 Responsable del Curso Introductorio a Perl: Andrés Arcia Moret • Teléfono/Fax: 0274-2402914 (oficina) • e-mail: [email protected]