You are here:
Wiki-SL
>
TWikiBar Web
>
TWikiBarConversa002
(03 Feb 2008,
JulioNeves
)
(raw view)
E
dit
A
ttach
---+!! Conversación de Bar Parte II %TOC% - Mozo! Trae un "chopps" y dos "pastel". Mi amigo hoy no va a beber porque finalmente le está siendo presentado un verdadero sistema operativo y todavia tiene muchas cosas que aprender!%BR% - Y entonces, amigo, estas entendiendo todo lo que te expliqué hasta ahora?%BR% - Entendiendo estoy, pero no vi nada práctico en eso...%BR% - Calma, lo que te dije hasta ahora, sirve como base para lo que ha de venir de aquí en adelante. Vamos a usar estas herramientas que vimos para montar programas estructurados, que el _Shell_ te permite. Entonces verás por qué hasta en la TV hubo un programa llamado "El _Shell_ es el Límite".%BR% - Para comenzar vamos a hablar de los comandos de la familia =grep=.%BR% - =grep=? No conozco ningún término en inglés con este nombre...%BR% - Por supuesto, =grep= es un acrónimo *Global Regular Expression Print*, que usa expresiones regulares para buscar la ocurrencia de cadenas de caracteres en la entrada definida (has de saber que hay una leyenda sobre como fue bautizado este comando: en el editor de textos "ed", el abuelo del "vim", el comando usado para buscar era g/_expresión regular_/p, en inglés g/_re_/p). Por hablar en expresiones regulares (o *regexp*), el portal <a href="http://bulma.net/body.phtml?nIdNoticia=770" target="_blank">BULMA - Bisoños Usuarios de GNU/Linux de Mallorca y Alrededores</a> tiene todos los enlaces en su página (inclusive tutoriales) que abordan el tema. Si realmente tienes ganas de aprender a programar en *Shell*, *Perl*, *Python*, ... debes leer estos artículos que te ayudarán a resolver lo que nos espera más adelante. ---++ Me quedo con el =grep=, tú con la gripe Eso de la gripe es un sólo un decir! Simplemente un pretexto para pedir unas "Caipirinhas" (o caipiriñas, el coctel oficial del carnaval brasileño ;) - <a href="http://www.afuegolento.com/noticias/40/reportajes/1585/" target="_blank">vea cómo prepararlas</a>). Volviendo a nuestro tema, te dije que el =grep= busca cadenas de caracteres dentro de una entrada definida, pero en realidad... que viene a ser una "entrada definida"? Bueno, existen varias formas de definir la entrada del comando =grep=. Veamos: Buscando en un archivo: %TERMINAL_INI% $ grep rafael /etc/passwd %TERMINAL_FIM% buscando en varios archivos: %TERMINAL_INI% $ grep grep *.sh %TERMINAL_FIM% Buscando en la salida de un comando: %TERMINAL_INI% $ who | grep Pelegrino %TERMINAL_FIM% En el 1º ejemplo, el más simple, busqué la palabra rafael en cualquier lugar del archivo =/etc/passwd=. Si quisiera buscarla como un login name, o sea, solamente en el principio de los registros de este archivo, debería hacer: %TERMINAL_INI% $ grep '^rafael' /etc/passwd %TERMINAL_FIM% Y para que sirve este acento circunflejo y los apostrofes? me vas a preguntar. Si hubieras leído los artículos anteriores sobre expresiones regulares que te dije, sabrías que el circunflejo (=^=) sirve para limitar la búsqueda al inicio de cada línea, y los apostrofes (='=) sirven para que el _Shell_ no interprete este circunflejo, dejándolo pasar intacto para el comando =grep=. Mira que bien! El =grep= acepta como entrada, la salida de otro comando redireccionado por un =pipe= (esto es muy común en _Shell_ y es un tremendo acelerador de la ejecución de comandos, ya que actúa como si la salida de un programa fuera guardada en disco y el segundo programa leyera este archivo generado), de esta forma, en el 3º ejemplo, el comando =who= listó las personas "logadas" en la misma máquina que tú (no te olvides jamás: el _Linux_ es multiusuario) y el =grep= fue usado para verificar si Pelegrino estaba trabajando o simplemente "haciendo sebo". ---+++ La familia =grep= Este comando =grep= es muy conocido, pues es usado con mucha frecuencia. Algo que muchas personas desconocen es que existen tres comandos en la familia =grep=, que son: * =grep= * =egrep= * =fgrep= Las principales diferencias entre los 3 son: * El =grep= puede o no, usar expresiones regulares simples, sin embargo en caso de no usarlas, el =fgrep= es mejor, por ser más rápido; * El =egrep= ("e" de extended, extendido) es muy poderoso en el uso de expresiones regulares. Por ser el más lento de la familia, solo debe ser usado cuando sea necesario la construcción de una expresión regular que no sea aceptada por el =grep=; * El =fgrep= ("f" de fast, rápido, o de "file", archivo) como el nombre dice, es el rapidito de la familia, ejecuta el servicio de forma muy veloz (a veces es cerca de 30% más rápido que el grep y 50% más que el egrep), sin embargo no permite el uso de expresiones regulares en la búsqueda. %ATENCION_INI% Todo lo que dije arriba sobre la velocidad, solamente se aplica a la familia de comandos =grep= del _Unix_. En _Linux_ el =grep= es siempre más veloz, ya que los otros dos (=fgrep= y =egrep=) son _scripts_ en _Shell_ que llaman al primero y, ya me estoy adelantando, *no me gusta* nada esta solución. %ATENCION_FIM% - Ahora que ya conoces las diferencias entre los miembros de la familia, dime: que te parecen los tres ejemplos que te dí antes de las explicaciones?%BR% - Me pareció que el =fgrep= resolvería tu problema de forma más veloz que el =grep=.%BR% - Perfecto! Estoy notando que estás bien atento! Estás entendiendo lo que te estoy explicando! Entonces vamos a ver más ejemplos, para aclarar de una vez por todas las diferencias del uso de los miembros de esta familia. %BR% Ejemplos Yo sé que en un archivo existe un texto hablando sobre =Linux= solo que no sé si está escrito con =L= mayúscula o =l= minúscula. Puedo hacer la búsqueda de dos formas: %TERMINAL_INI% $ egrep (Linux | linux) archivo.txt %TERMINAL_FIM% o %TERMINAL_INI% $ grep [Ll]inux archivo.txt %TERMINAL_FIM% En el primer caso, la expresión regular compleja ="(Linux | linux)"= usa los paréntesis para agrupar las opciones y la barra vertical (=|=) como un "o" lógico, o sea, estoy buscando =Linux= o =linux=. En el segundo, la expresión regular =[Ll]inux= significa: comenzando por =L= o =l= seguido de =inux=. Como esta expresión es más simple, el =grep= consigue resolverla, por lo tanto creo que es mejor usar la segunda forma, ya que el =egrep= haría la búsqueda más lenta. Otro ejemplo. Para listar todos los subdirectorios del directorio actual, basta hacer: %TERMINAL_INI% $ ls -l | grep '^d'%OUT_INI% drwxr-xr-x 3 root root 4096 Dec 18 2000 doc drwxr-xr-x 11 root root 4096 Jul 13 18:58 freeciv drwxr-xr-x 3 root root 4096 Oct 17 2000 gimp drwxr-xr-x 3 root root 4096 Aug 8 2000 gnome drwxr-xr-x 2 root root 4096 Aug 8 2000 idl drwxrwxr-x 14 root root 4096 Jul 13 18:58 locale drwxrwxr-x 12 root root 4096 Jan 14 2000 lyx drwxrwxr-x 3 root root 4096 Jan 17 2000 pixmaps drwxr-xr-x 3 root root 4096 Jul 2 20:30 scribus drwxrwxr-x 3 root root 4096 Jan 17 2000 sounds drwxr-xr-x 3 root root 4096 Dec 18 2000 xine%OUT_FIM% %TERMINAL_FIM% En el ejemplo que acabamos de ver, el circunflejo (=^=) sirvió para limitar la busqueda a la primera posición de la salida del =ls= detallado. los apostrofes fueron colocados para que el _Shell_ no "viera" el circunflejo (=^=). Vamos a ver otro. Sabemos que las cuatro primeras posiciones posibles de un =ls -l= de un archivo común (archivo común!, No directorio, ni _link_, ni ...) deben ser: <center> %TABLE{ databg="#ffffff" headerrows="1" }% | *Posición* | * 1ª * | * 2ª * | * 3ª * | * 4ª * | | Valores Posibles | =-= | =r= | =w= | =x= | |^| | =-= | =-= | =s= (suid) | |^| | | | =-= | </center> Así, para descubrir todos los archivos ejecutables en un determinado directorio debería hacer: %TERMINAL_INI% $ ls -la | egrep '^-..(x|s)'%OUT_INI% -rwxr-xr-x 1 root root 2875 Jun 18 19:38 rc -rwxr-xr-x 1 root root 857 Aug 9 22:03 rc.local -rwxr-xr-x 1 root root 18453 Jul 6 17:28 rc.sysinit%OUT_FIM% %TERMINAL_FIM% Donde nuevamente usamos el circunflejo (=^=) para limitar la búsqueda al inicio de cada línea, entonces las líneas listadas serán las que comienzan por un trazo (=-=), seguido de cualquier cosa (el punto cuando es usado como una expresión regular significa cualquier cosa), nuevamente seguido de cualquier cosa, y siguiendo un =x= o un =s=. Obtendríamos el mismo resultado si hiciéramos: %TERMINAL_INI% $ ls -la | grep '^-..[xs]' %TERMINAL_FIM% y agilizaríamos la búsqueda. ---++ Vamos a montar una "CDteca" Vamos a comenzar a desarrollar programas, me parece que montar un banco de datos de músicas es muy útil y didáctico (y además práctico, en estos tiempos de _downloads_ de mp3 y "quemadores" de CDs). No te olvides que, de la misma forma vamos a desarrollar una cantidad de programas para organizar tus CDs de música, con pequeñas adaptaciones, puedes hacer lo mismo con los CDs de _software_ que vienen con la __Linux Magazine__ y otros que compres o quemes, si compartes este banco de _software_ para todos los que trabajan contigo (el _Linux_ es multiusuario, y como tal debe ser explotado), ganarás muchos puntos con tu adorado jefe. - Un momento! De donde voy la recibir los datos de los CDs? %BR% - Inicialmente, te voy a mostrar como tu programa puede recibir parámetros de quién lo esté ejecutando y en breve, te enseñaré a leer los datos por la pantalla o de un archivo. %BR% ---+++ Pasando parámetros El visual del archivo músicas será el siguiente: =nombre del álbum^intérprete1~nombre de la música1:..:intérprete~nombre de la música= o sea, el nombre del álbum será separado por un circunflejo (=^=) del resto del registro, que está formado por diversos grupos compuestos por el intérprete de cada música del CD y la respectiva música interpretada. Estos grupos son separados entre sí por dos-puntos (=:=) e internamente, el intérprete será separado por una tilde (=~=) del nombre de la música. Escribiré un programa llamado =musinc=, que incluirá registros en mi archivo músicas. Pasaré el contenido de cada álbum como parâmetro en la llamada del programa de la siguiente forma: %TERMINAL_INI% $ musinc "álbum^interprete~música:interprete~música:..." %TERMINAL_FIM% De esta forma el programa =musinc= estará recibiendo los datos de cada álbum como si fuera una variable. La única diferencia entre un parámetro recibido y una variable es que los primeros reciben nombres numéricos (nombre numérico suena algo raro, no?). Lo que quise decir es que sus nombres son formados por un y solamente un algarismo), el sea =$1, $2, $3, ..., $9=. Vamos, antes de todo, hacer un test: Ejemplos %TERMINAL_INI% $ cat test %OUT_INI%#!/bin/bash # Programa para verificar el pasaje de parámetros echo "1o. param -> $1" echo "2o. param -> $2" echo "3o. param -> $3"%OUT_FIM% %TERMINAL_FIM% Vamos a ejecutarlo: %TERMINAL_INI% $ test pasando parámetros para verificar %OUT_INI%bash: test: cannot execute%OUT_FIM% %TERMINAL_FIM% Opa! Me olvidé de hacerlo ejecutable. Voy a hacerlo de forma que permita que todos puedan ejecutarlo y en seguida voy a testearlo: %TERMINAL_INI% $ chmod 755 test $ test pasando parámetros para verificar %OUT_INI%1o. param -> pasando 2o. param -> parámetros 3o. param -> para%OUT_FIM% %TERMINAL_FIM% Repara que la palabra =verificar=, que sería el cuarto parámetro, no fue listada. Esto sucedió justamente porque el programa test solo listaba los tres primeros parámetros. Vamos ejecutarlo de otra forma: %TERMINAL_INI% $ test "pasando parámetros" para verificar%OUT_INI% 1o. param -> pasando parámetros 2o. param -> para 3o. param -> verificar%OUT_FIM% %TERMINAL_FIM% Las comillas no dejaron que el =Shell= viese el espacio en blanco entre las palabras y las consideró como un único parámetro. ---+++ Observaciones sobre parámetros Ya que estamos hablando de pasar parámetros observa bien lo siguiente: <center> %TABLE{ databg="#ffffff" headerrows="1" }% | *Significado de las Principales Variables Referentes a los Parámetros* || | *Variable* | *Significado* | | =$0= | Contiene el nombre del programa | | =$#= | Contiene la cuantidad de parámetros pasados | | =$*= | Contiene el conjunto de todos los parámetros (muy parecido con =$@=) | </center> Ejemplos Vamos a alterar el programa =test= para usar las variables que acabamos de ver. Vamos hacerlo así: %TERMINAL_INI% $ cat test %OUT_INI%#!/bin/bash # Programa para verifivar el paso de parámetros (2a. Versao) echo El programa $0 recibió $# parámetros echo "1o. param -> $1" echo "2o. param -> $2" echo "3o. param -> $3" echo Todos de una sola \"bolada\": $*%OUT_FIM% %TERMINAL_FIM% Repare que antes de las comillas usé una barra invertida para esconderlas de la interpretación del _Shell_ (si no usase las contrabarras las comillas no aparecerian). Vamos a ejecutarlo: %TERMINAL_INI% $ test pasando parámetros para verificar %OUT_INI%El programa test recibió 4 parámetros 1o. param -> pasando 2o. param -> parámetros 3o. param -> para Todos de una sola "bolada": pasando parámetros para verificar%OUT_FIM% %TERMINAL_FIM% Como ya dije, los parámetros reciben números de =1= a =9=, pero eso no significa que no puedo usar más de 9 parámetros, significa solamente que solo puedo direccionar 9. Vamos a verificar eso: Ejemplo: %TERMINAL_INI% $ cat test %OUT_INI%#!/bin/bash # Programa para verificar el pasaje de parámetros (3a. Versión) echo El programa $0 recebió $# parámetros echo "11o. param -> $11" shift echo "2o. param -> $1" shift 2 echo "4o. Param -> $1"%OUT_FIM% %TERMINAL_FIM% Vamos a ejecutarlo: %TERMINAL_INI% $ test pasando parámetros para verificar %OUT_INI%El programa test recibió 4 parámetros que son: 11o. param -> pasando1 2o. param -> parámetros 4o. param -> verificar%OUT_FIM% %TERMINAL_FIM% Dos cosas muy interesantes en este _script_: 1 Para mostrar que los nombres de los parámetros varían de =$1= a =$9= hice un echo =$11= y que pasó? El _Shell_ interpretó como que era =$1= seguido del algarismo =1= y listó =pasando1=; 2 El comando =shift= cuya sintáxis es =shift n=, pudiendo el =n= asumir cualquier valor numérico (sin embargo su _default_ es =1=, como en el ejemplo dado), desprecia los =n= primeros parámetros, devolviendo el parámetro de orden =n+1=, el primero o sea, el =$1=. Bueno, ahora que ya sabes más sobre pasar parámetros que yo mismo, vamos a volver a nuestra "CDteca" para hacer el _script_ que incluira los CDs en mi banco llamado =musicas=. El programa es muy simple (como todo en _Shell_) y voy a listarlo para que lo veas: Ejemplos %TERMINAL_INI% $ cat musinc %OUT_INI%#!/bin/bash # Incluye CDs (versión 1) # echo $1 >> musicas%OUT_FIM% %TERMINAL_FIM% El _script_ es fácil y funcional, me limito a añadir al final del archivo =musicas= el parámetro recibido. Vamos a incluir 3 álbumes para ver si funciona (y para no hacerlo muy aburrido, voy a suponer que en cada CD existem solamente 2 músicas): %TERMINAL_INI% $ musinc "album 3^Artista5~Musica5:Artista6~Musica5" $ musinc "album 1^Artista1~Musica1:Artista2~Musica2" $ musinc "album 2^Artista3~Musica3:Artista4~Musica4" %TERMINAL_FIM% Muestro ahora el contenido de musicas. %TERMINAL_INI% $ cat musicas %OUT_INI%album 3^Artista5~Musica5:Artista6~Musica6 album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4%OUT_FIM% %TERMINAL_FIM% No es tan funcional como esperaba que quedase... podía haber quedado mejor. Los álbumes están fuera de orden, dificultando la búsqueda. Vamos a alterar nuestro _script_ y después a probarlo nuevamente: %TERMINAL_INI% $ cat musinc %OUT_INI%#!/bin/bash # Incluye CDs (versión 2) # echo $1 >> musicas sort musicas -o musicas%OUT_FIM% %TERMINAL_FIM% Vamos a incluir un álbum más: %TERMINAL_INI% $ musinc "album 4^Artista7~Musica7:Artista8~Musica8" %TERMINAL_FIM% Ahora vamos a ver lo que pasó con el archivo =musicas=: %TERMINAL_INI% $ cat musicas %OUT_INI%album 1^Artista1~Musica1:Artista2~Musica2 album 2^Artista3~Musica3:Artista4~Musica4 album 3^Artista5~Musica5:Artista6~Musica5 album 4^Artista7~Musica7:Artista8~Musica8%OUT_FIM% %TERMINAL_FIM% Simplemente incluí una línea que clasifica el archivo =musicas= dándole la salida sobre si mismo (para eso sirve la opción =-o=), después de que cada álbum fue incluído. Opa! Ahora está quedando bien y casi funcional. Pero atención, no te desesperes! Esta no es la versión final. El programa quedará mucho mejor y más amigable, en una nueva versión que haremos después que aprendamos la adquirir los datos de la pantalla y a formatear la entrada Ejemplos Usar el comando =cat= para listar no es una buena idea, vamos a hacer un programa llamado=muslist=, para listar un álbum cuyo nombre será pasado como un parámetro: %TERMINAL_INI% $ cat muslist %OUT_INI%#!/bin/bash # Consulta CDs (versión 1) # grep $1 musicas%OUT_FIM% %TERMINAL_FIM% Vamos a ejecutarlo, buscando el =album 2=. Como ya vimos anteriormente, para pasar la cadena de caracteres =album 2= es necesario protegerla de la interpretación del _Shell_, así él no la interpreta como dos parámetros separados. Vamos a hacerlo de la siguiente forma: %TERMINAL_INI% $ muslist "álbum 2" %OUT_INI%grep: can't open 2 musicas: album 1^Artista1~Musica1:Artista2~Musica2 musicas: album 2^Artista3~Musica3:Artista4~Musica4 musicas: album 3^Artista5~Musica5:Artista6~Musica6 musicas: album 4^Artista7~Musica7:Artista8~Musica8%OUT_FIM% %TERMINAL_FIM% Que desorden! Donde está el error?. Tuve buen cuidado de colocar el parámetro pasado entre comillas, para que el _Shell_ no lo diviera en dos! Si, pero advierte ahora como el =grep= está siendo ejecutado: =grep $1 musicas= Aunque coloque =álbum 2= entre comillas, para que fuera visto como un único parámetro, cuando el =$1= fue pasado por el _Shell_ hacia el comando =grep=, lo transformó en dos argumentos. Así, el contenido final de la línea que el comando =grep= ejecutó fue el siguiente: =grep album 2 musicas= Como la sintáxis del =grep= es: <verbatim> grep <cadena de caracteres> [arch1, arch2, ..., archn] </verbatim> el =grep= entendió que debería recuperar la cadena de caracteres =album= en los =archivos 2= y =musicas=, Al no existir el =archivo 2= generó el error, y como encontro la palabra =album= en todos los registros de =musicas=, los listo todos. %DICA_INI% Siempre que la =cadena de caracteres= a ser pasada hacia el comando =grep= posea blancos o =TAB=, y lo mismo que dentro de variables, colóquela siempre entre comillas para evitar que las palabras después del primer espacio en blanco o =TAB= sean interpretadas como nombres de archivos. %DICA_FIM% Por otro lado, es mejor ignorar las mayúsculas y minúsculas en la búsqueda. Resolveríamos los dos problemas si el programa tuviera la siguiente forma: %TERMINAL_INI% $ cat muslist %OUT_INI%#!/bin/bash # Consulta CDs (versión 2) # grep -i "$1" musicas%OUT_FIM% %TERMINAL_FIM% En este caso, usamos la opción =-i= del =grep=, que como vimos, sirve para ignorar mayúsculas y minúsculas, y colocamos el =$1= entre comillas, para que el =grep= continue viendo la cadena de caracteres resultante de la expansión de la línea por el =Shell= como un único argumento de búsqueda. %TERMINAL_INI% $ muslist "album 2"%OUT_INI% album2^Artista3~Musica3:Artista4~Musica4%OUT_FIM% %TERMINAL_FIM% Ahora, nota que el =grep= localiza la cadena buscada en cualquier lugar del registro, entonces de la forma que estamos lo haciendo, podemos buscar por álbum, por música, por intérprete o hasta por un pedazo de cualquiera de estos. Cuando conozcamos los comandos condicionales, montaremos una nueva versión de =muslist= que permitirá especificar por que campo buscar. Ahora me vas a decir: - Si, todo bien, pero es muy tedioso tener que colocar el argumento de búsqueda entre comillas cuando tengo que pasar el nombre del álbum. Esta forma no es nada amigable! %BR% - Tienes toda la razón, y es por eso que te voy a mostrar otra forma de hacer lo que me pediste: %BR% %TERMINAL_INI% $ cat muslist %OUT_INI%#!/bin/bash # Consulta CDs (versión 3) # grep -i "$*" musicas $ muslist album 2 album 2^Artista3~Musica3:Artista4~Musica4%OUT_FIM% %TERMINAL_FIM% De esta forma, el =$*=, que significa todos los parámetros, será substituído por la cadena =album 2= (de acuerdo con el ejemplo anterior), haciendo lo que tu querias. No te olvides que el problema del _Shell_ no es si él puede o no hacer una determinada cosa. El problema es decidir cuál es la mejor forma de hacerla, ya que para realizar cualquier tarea, la cantidad de opciones es enorme. Recuerdas aquel dia de verano fuiste a la playa?, olvidaste el CD en el automóbil, y entonces aquel "solecito" de 40 grados dobló tu CD y ahora necesitas una herramienta para borrarlo del banco de datos. No hay ningún problema, vamos a desarrollar un _script_ llamado =musexc=, para excluir estos CDs. Antes de desarrollar el programa te quiero presentar una opción bastante útil de la familia de comandos =grep=. Es la opción =-v=, que cuando es usada, lista todos los registros de la entrada, excepto el(los) localizado(s) por el comando. Veamos: Ejemplos %TERMINAL_INI% $ grep -v "album 2" musicas %OUT_INI%album 1^Artista1~Musica1:Artista2~Musica2 album 3^Artista5~Musica5:Artista6~Musica6 album 4^Artista7~Musica7:Artista8~Musica8%OUT_FIM% %TERMINAL_FIM% De acuerdo con lo que te expliqué antes, el =grep= del exemplo listó todos los registros de músicas excepto los referentes al =album 2=, porque atendía al argumento del comando. Estamos entonces preparados para desarrollar un _script_ para retirar aquél CD doblado de tu "CDteca". Este _script_ tiene la forma siguiente: %TERMINAL_INI% $ cat musexc %OUT_INI%#!/bin/bash # Borra CDs (versión 1) # grep -v "$1" musicas > /tmp/mus$$ mv -f /tmp/mus$$ musicas%OUT_FIM% %TERMINAL_FIM% En la primera línea mandé hacia =/tmp/mus$$= el archivo musicas, sin los registros que tuviesen la consulta hecha por el comando =grep=. En seguida, moví (que, en realidad, equivale a renombrarlo) =/tmp/mus$$= al antiguo =musicas=. Usé el archivo =/tmp/mus$$= como archivo de trabajo, porque como ya habia citado en el artículo anterior, el =$$= contiene el =PID= (_Process Identification_ o identificación del proceso) y de esta forma cada uno que edite el archivo =musicas= lo hará en un archivo de trabajo diferente, de esta forma evitamos choques en su uso. - Y entonces, amigo, estos programas que hicimos hasta aquí son muy rústicos en virtud de la falta de herramientas que todavia tenemos. Pero están bien, mientras me tomo otro "chopp", puedes ir para casa a praticar en los ejemplos dados porque, te prometo, llegaremos a desarrollar un sistema bien bonito para el control de tus CDs. %BR% - Cuando nos encontremos la próxima vez, te voy a enseñar como funcionan los comandos condicionales y mejoraremos otro poco estos _scripts_. %BR% - Por hoy es suficiente! Ya hablé demasiado y necesito mojar las palabras porque estoy con la garganta seca! %BR% - Mozo! Otro sin y espuma! Cualquer duda o falta de compañia para tomar una cerveza o hasta para hablar mal de los políticos, lo único que tienes que hacer es mandarme un e-mail para <a href="mailto:julio.neves@gmail.com?Subject=Dudas Conversas de bar botequim">julio.neves@gmail.com</a>. Voy aprovechar tambiém para mandar mi aviso publicitario: puedes decirle a los amigos que quien quiera hacer un curso nota diez de programación en _Shell_, que mande un e-mail para <a href="mailto:julio.neves@uniriotec.br?Subject=Curso de Shell con Julio Neves">julio.neves@uniriotec.br</a> para informarse. Gracias y hasta la <a href="https://twiki.softwarelivre.org/bin/view/TWikiBar/TWikiBarConversa003">próxima</a> -- Main.HumbertoPina - 13 Sep 2006
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r10
<
r9
<
r8
<
r7
<
r6
|
B
acklinks
|
V
iew topic
|
M
ore topic actions
Topic revision: r10 - 03 Feb 2008 - 14:08:28 -
JulioNeves
TWikiBar
Página Inicial
Últimas alterações
Índice
Procurar
Estatísticas de Uso
Aviso de Atualização
Configurações Gerais
Projeto Gráfico
Mapa do Site
Quem Somos
Registre-se
?
Regras de Formatação
Biblioteca Gráfica
?
Carinhas Gráficas
Webs Wiki-SL
Amadeu
Anapolivre
ArquivoLivre
Arte
BahiaSocial
BeaBa
BibliotecaLivre
Blogs
BrasilDigital
BrasilELivre
BSM
Ccsa
CESL
CoberturaWiki
Cooperativas
Curriculo
DarvinMarosin
DiaD
Dinamicoop
Economia
EconomiaSolidaria
EducacaoLivre
Ekaaty
Emacsbr
ENSL
Fatos
Festival3
Festival4
Flisol
Fmpb
Formatos
Foswikibr
FSM2005
GNOMEBR
GTTemario2004
GTWeb
Guialivre
HDC
Incubus
InkscapeBrasil
Jogos
KdeBR
KSP
LGM
LinuxStokDoc
Livros
Main
Mentores
MHHOB
MinuanoDigital
MoradiaECidadania
OlhosDagua
Olimpo
OLPC
OOPTQ
Papers
PCLivre
PentahoBrasil
Pessoas
Portal
Prefeituras
PSLAL
PSLBA
PSLBancarios
PSLBrasil
PSLGO
PSLMA
PSLMG
PSLMIP
PSLMT
PSLMulheres
PSLPI
PubFisl10
PubFisl7
PubFisl8
PubFisl9
QuilomboDoSopapo
RadioSL
RedeMesh
RedePopular
RobotWars
Sandbox
Saudelivre
Scribus
Sementes
Shakya
SLRJ
SoftwareLivreIrece
SoftwareLivreVS
SoLiSC
SuporteLivre
System
Telecentros
TeseSA
TextoLivre
TV
TWikiBar
TWikiPtbr
UNELivre
UNIMIX
VilaTorres
WebNordeste
WTRD2004
Este Menu
?skin=free
English
Español
Português brasileiro
Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki-SL?
Send feedback