Difference: TWikiBarConversa007 (1 vs. 9)

Revision 906 Feb 2008 - CollonsTorre

Line: 1 to 1
 

Conversación de Bar Parte VII



     - Como dijiste? Repite que no te entiendo! Se te derritieron los pensamientos para hacer el scriptiziño que te pedí?
Changed:
<
<
     - Si, realmente tuve que colocar mucha materia gris en la pantalla, pero creo que conseguí! Bueno, por lo menos en los tests que hice la cosa funcionó, pero tu siempre me colocas piedras en el camino!
>
>
     - Si, realmente tuve que colocar mucha materia gris en la pantalla, pero creo que lo conseguí! Bueno, por lo menos en los tests que hice la cosa funcionó, pero tu siempre me colocas piedras en el camino!
 
Changed:
<
<
     - No es tan así, programar en shell es muy fácil, lo que vale son los consejos y los detalles de programación que te doy, que no son triviales. Las correcciones que te hago, son justamente para mostrarlos. Pero vamos a pedir dos chopps en cuanto doy una miradita en tu script.
>
>
     - No sera tanto, programar en shell es muy fácil, lo que vale son los consejos y los detalles de programación que te doy, que no son triviales. Las correcciones que te hago, son justamente para mostrarlos. Pero vamos a pedir dos "chopps" y le echo una ojeada a tu script.
 
Changed:
<
<
     - Mozo, trae dos. No se olvide que uno es sin espuma!
>
>
     - Mozo, trae dos. No te olvides que uno es sin espuma!
 
$ cat restaura #!/bin/bash #
Changed:
<
<
# Restaura archivos borrados via erreeme
>
>
# Restaura archivos borrados vía erreeme
 #

if [ $# -eq 0 ]

Line: 34 to 34
 
Changed:
<
<
     - Un momento, dejame ver se entendí. Primero colocas en la variable Dir la última línea del archivo cuyo nombre está formado por /tmp/nombre del operador ($LOGNAME)/parámetro pasado con el nombre del archivo a ser restaurado ($1). Enseguida el grep -v que montaste borra esa línea en que estaba el nombre del directorio, o sea, siempre es la última y manda lo que resta del archivo, que sería el archivo ya limpio, para el directório original y después borra el archivo de la "lata de basura"; S E N S A C I O N A L! Impecable! Cero error! Viste? ya le estás agarrando las mañas al shell!
>
>
     - Un momento, déjame ver se lo entendí. Primero colocas en la variable Dir la última línea del archivo cuyo nombre está formado por /tmp/nombre del operador ($LOGNAME)/parámetro pasado con el nombre del archivo a ser restaurado ($1). Enseguida el grep -v que montaste borra esa línea en que estaba el nombre del directorio, o sea, siempre es la última y manda lo que resta del archivo, que sería el archivo ya limpio, hacia el directorio original para después borrar el archivo del "cubo de la basura"; S E N S A C I O N A L! Impecable! Ningun error! Lo viste? ya le estás tomando las medidas al shell!
 
Changed:
<
<
     - Entonces vamos a continuar, basta de bla-bla-bla, de que vas a hablar hoy?
>
>
     - Entonces vamos a continuar, basta ya de bla-bla-bla, de que vas a hablar hoy?
 
Changed:
<
<
     - Ah! estoy viendo que el bichito del Shell se te contagió. Que bueno, vamos a ver como se puede (y debe) leer datos y formatar pantallas y primero vamos a entender un comando que te dá todas las herramientas para que formates tu pantalla de entrada de datos.
>
>
     - Ah! estoy viendo que el bichito del Shell se te contagió. Que bueno, vamos a ver como se pueden (y deben) leer datos y formatear pantallas, pero primero vamos a conocer un comando que te da todas las herramientas para que formatees tu pantalla de entrada de datos.
 

El comando tput

Changed:
<
<
El mayor uso de este comando es para posicionar el cursor en la pantalla, sin embargo también es muy usado para borrar datos de la pantalla, saber la cantidad de líneas y columnas para poder posicionar correctamente un campo, borrar un campo cuya crítica detectó como error. En fin, casi toda la formatación de la pantalla es hecha por este comando.
>
>
Este comando se usa principalmente para posicionar el cursor en la pantalla, sin embargo también es muy usado para borrar datos de la pantalla, saber la cantidad de líneas y columnas de la pantalla, posicionar correctamente un campo, borrar un campo cuya entrada se detectó como error. En fin, casi toda la formatación de la pantalla es hecha por este comando.
  Unos pocos atributos del comando tput pueden eventualmente no funcionar, esto en el caso de que el modelo de terminal definido por la variable $TERM, no tenga esta posibilidad incorporada.
Changed:
<
<
En la tabla a seguir, se presentan los principales atributos del comando y los efectos ejecutados sobre la pantalla, pero debes saber que existen muchos más de que esos, ve sino:
>
>
En la tabla siguiente, se presentan los principales atributos del comando y los efectos ejecutados sobre la pantalla, pero debes saber que existen muchos más que esos, mira sino:
 
$ tput it 8
Changed:
<
<
En este ejemplo recebí el tamaño inicial de la <TAB> ( Initial T ab), pero dime una cosa: para que quiero saber eso? Si quieres saber todo sobre el comando tput (y mira que es de nunca acabar), vea en: http://www.cs.utah.edu/dept/old/texinfo/tput/tput.html#SEC4.
>
>
Este ejemplo devolvió el tamaño inicial del <TAB> ( Initial T ab), y dime una cosa: para que quiero saber eso? Si quieres saber todo sobre el comando tput (y mira que es de nunca acabar), vea a: http://www.cs.utah.edu/dept/old/texinfo/tput/tput.html#SEC4.
 
Principales Opciones del Comando tput
Opciones de tput   Efecto
Changed:
<
<
cup lin col   CUrsor Position - Posiciona el cursor en la línea lin y coluna col. El origen es cero
>
>
cup lin col   CUrsor Position - Posiciona el cursor en la línea lin y columna col. El origen es cero
 
bold   Coloca la pantalla en modo de realce
Changed:
<
<
rev   Coloca la pantalla en modo de video inverso
>
>
rev   Coloca la pantalla en modo de vídeo inverso
 
smso   Idéntico al anterior
Changed:
<
<
reset   Limpia la pantalla y restaura sus definiciones de acuerdo con el terminfo o sea, la pantalla vuelve al padrón definido por la variable $TERM  
smul   A partir de esta instrución, los caracteres tecleados aparecerán sublineados en la pantalla
blink   Los caracteres tecleados aparecerán piscando
sgr0   Después de usar uno de los atributos de arriba, use éste es para restaurar la pantalla a su modo normal
>
>
reset   Limpia la pantalla y restaura sus definiciones de acuerdo con el terminfo o sea, la pantalla vuelve al patrón definido por la variable $TERM  
smul   A partir de esta instrucción, los caracteres tecleados aparecerán sublineados en la pantalla
blink   Los caracteres tecleados aparecerán intermitentes
sgr0   Después de usar uno de los atributos de arriba, se usa este para restaurar la pantalla a su modo normal
 
il n   Insert Lines - Introduce n líneas a partir de la posición del cursor
lines   Devuelve la cantidad de líneas de la pantalla en el momento de la instrucción
cols   Devuelve la cantidad de columnas de la pantalla en el momento de la instrucción
el   Erase Line - Borra la línea a partir de la posición del cursor
ed   Erase Display - Borra la pantalla a partir de la posición del cursor
Changed:
<
<
dl n   Delete Lines - Retira n líneas a partir de la posición del cursor
>
>
dl n   Delete Lines - Borra n líneas a partir de la posición del cursor
 
rc   Restore Cursor position - Coloca el cursor en la posición marcada por el último sc
ech n   Erase CHaracters - Borra n caracteres a partir de la posición del cursor
sc   Save Cursor position - Graba la posición del cursor
Changed:
<
<
Vamos a hacer un programa bien sencillo para mostrar algunos atributos de este comando. Es el famoso usado y abusado Hola Mundo, sólo que esta frase será escrita en el centro de la pantalla y en video inverso y después de eso, el cursor volverá para la posición en que estaba antes de escribir esta frase tan creativa. Vea:
>
>
Vamos a hacer un programa bien sencillo para mostrar algunos atributos de este comando. Es el famoso usado y abusado Hola Mundo, sólo que esta frase será escrita en el centro de la pantalla y en vídeo inverso y después de eso, el cursor volverá hasta la posición en que estaba antes de escribir esta frase tan creativa. Observa:
 
$ cat hola.sh
Line: 87 to 87
 # Script bobo para testar # el comando tput (versión 1)
Changed:
<
<
Colunas=`tput cols` # Grabando cantidad colunas
>
>
Columnas=`tput cols` # Grabando cantidad columnas
 Líneas=`tput lines` # Grabando cantidad líneas Línea=$((Líneas / 2)) # Cual es la línea del medio de la pantalla? Columna=$(((Columnas - 11) / 2)) # Centrando el mensaje en la pantalla tput sc # Grabando posición del cursor tput cup $Línea $Columna # Posicionándose para escribir
Changed:
<
<
tput rev # Video inverso
>
>
tput rev # Vídeo inverso
 echo Hola Mundo!
Changed:
<
<
tput sgr0 # Restaura video a normal tput rc # Restaura cursor en posición original
>
>
tput sgr0 # Restaura el vídeo a normal tput rc # Restaura el cursor a la posición original
 
Changed:
<
<
Como el programa ya está todo comentado, creo que la única explicación necesaria sería para la línea en que es creada la variable Columna y lo estraño allí es aquél número 11, él es el tamaño de la cadena que pretendo escribir (Hola Mundo).
>
>
Como el programa ya está todo comentado, creo que la única explicación necesaria sería para la línea en que es creada la variable Columna y lo extraño allí es aquél número 11, este numero es el tamaño de la cadena que pretendo escribir (Hola Mundo).
 
Changed:
<
<
De esta forma, este programa solamente conseguiría centrar cadenas de 11 caracteres, sin embargo, ve esto:
>
>
De esta forma, este programa solamente conseguiría centrar cadenas de 11 caracteres, sin embargo, mira esto:
 
$ var=Conversa
Line: 112 to 112
 15
Changed:
<
<
Ahhh, mejoró! Entonces ahora sabemos que la construcción ${#variable} devuelve la cantidad de caracteres de variable. De esta forma, vamos a optimizar nuestro programa para que escriba en video reverso y en el centro de la pantalla, la cadena pasada como parámetro y que después el cursor vuelva a la posición en que estaba antes de la ejecución del script.
>
>
Ahhh, mejoró! Entonces ahora sabemos que la construcción ${#variable} devuelve la cantidad de caracteres de variable. De esta forma, vamos a optimizar nuestro programa para que escriba en vídeo inverso y en el centro de la pantalla, la cadena pasada como parámetro y que después el cursor vuelva a la posición en que estaba antes de la ejecución del script.
 
$ cat hola.sh
Line: 120 to 120
 # Script bobo para testar # el comando tput (versión 2)
Changed:
<
<
Columnas=`tput cols` # Grabando cantidad colunas
>
>
Columnas=`tput cols` # Grabando cantidad columnas
 Líneas=`tput lines` # Grabando cantidad líneas Línea=$((Líneas / 2)) # Cual es la línea del medio de la pantalla? Columna=$(((Columnas - ${#1}) / 2)) #Centrando el mensaje en la pantalla put sc # Grabando posición del cursor tput cup $Línea $Columna # Posicionándose para escribir
Changed:
<
<
tput rev # Video inverso
>
>
tput rev # Vídeo inverso
 echo $1
Changed:
<
<
tput sgr0 # Restaura video a normal
>
>
tput sgr0 # Restaura vídeo a normal
 tput rc # Restaura cursor en la posición original
Changed:
<
<
Este script es igual al anterior, sólo que cambiamos el valor fijo de la versión anterior (9), por ${#1}, donde éste 1 es el $1 o sea, esta construcción devuelve el tamaño del primer parámetro pasado para el programa. Si el parámetro que yo quisiese pasar tuviese espacios en blanco, tendría que colocarlo todo entre comillas, sino el $1 sería solamente el primer pedazo. Para evitar este problema, es solo substituir el $1 por $*, que como sabemos es el conjunto de todos los parámetros. Entonces aquella línea quedaría así:
>
>
Este script es igual al anterior, sólo que cambiamos el valor fijo de la versión anterior (9), por ${#1}, donde éste 1 es el $1 o sea, esta construcción devuelve el tamaño del primer parámetro pasado para el programa. Si el parámetro que yo quisiese pasar tuviese espacios en blanco, tendría que colocarlo todo entre comillas, sino el $1 sería solamente el primer pedazo. Para evitar este problema, es solo necesario substituir el $1 por $*, que como sabemos es el conjunto de todos los parámetros. Entonces aquella línea quedaría así:
 

    Columna=`$(((Columnas - ${#*}) / 2))` #Centrando el mensaje en la pantalla
Changed:
<
<
y la línea echo $1 pasaría a ser echo $*. Pero no se olvide de que cuando lo ejecute, tiene que pasar la frase que deseas centrar como un parámetro.
>
>
y la línea echo $1 pasaría a ser echo $*. Pero no te olvides de que cuando lo ejecutes, tienes que pasar la frase que deseas centrar como un parámetro.
 

Y ahora podemos leer los dados de la pantalla

Changed:
<
<
Bien, a partir de ahora vamos a aprender todo sobre lectura, solo no te puedo enseñar a leer las cartas o los buzios, porque sino estaria rico en un pub de Londres, tomando scotch y no en un bar tomando chopp. Pero vamos a continuar.
>
>
Bien, a partir de ahora vamos a aprender todo sobre lectura, solo que no te puedo enseñar a leer las cartas o el futuro, porque sino ya seria rico, estaria en un pub de Londres, tomando scotch y no en un bar tomando "chopp". Pero vamos a continuar.
 
Changed:
<
<
La última vez que nos encontramos aqui ya te dí una introducción sobre el comando read. Para comenzar su análisis más detallada. ve esto:
>
>
La última vez que nos encontramos aquí ya te dí una introducción sobre el comando read. Para comenzar su análisis más detallada. fíjate en esto:
 
$ read var1 var2 var3
Line: 166 to 166
  Como viste, el read recibe una lista separada por espacios en blanco y coloca cada ítem de esta lista en una variable. Si la cantidad de variables es menor que la cantidad de ítems, la última variable recibe el resto de los parámetros.
Changed:
<
<
Yo mencioné una lista separada por espacios en blanco? Ahora que ya conoces todo sobre el $IFS (Inter Field Separator) que te presenté cuando hablamos del comando for, será que todavia crees eso? Vamos a verificar directo en el prompt:
>
>
Yo mencioné una lista separada por espacios en blanco? Pero ahora que ya lo conoces todo sobre el $IFS (Inter Field Separator) que te presenté cuando hablamos del comando for, todavía crees eso? Vamos a verificarlo directamente en el prompt:
 
$ oIFS="$IFS"
Line: 190 to 190
 $ IFS="$oIFS"
Changed:
<
<
Viste, estava equivocado! La verdad es que el read lee una lista, así como el for, separada por los caracteres de la variable $IFS. Entonces vea como eso puede facilitarte la vida:
>
>
Te diste cuenta, estaba equivocado! La verdad es que el read lee una lista, así como el for, separada por los caracteres de la variable $IFS. Fíjate entonces como esto puede facilitarte la vida:
 
$ grep julio /etc/passwd
Line: 208 to 208
 $ IFS="$oIFS" # Restaurando IFS
Changed:
<
<
Como viste, la salda del grep fuei redireccionada para el comando read que leyó todos los campos de una sola vez. La opción -e del echo fue usada para que el \n fuera entendido como un salto de línea (new line), y no como un literal.
>
>
Como viste, la salda del grep fue redireccionada hacia el comando read que leyó todos los campos de una sola vez. La opción -e del echo fue usada para que el \n fuera entendido como un salto de línea (new line), y no como un literal.
 
Changed:
<
<
En el Bash existen diversas opciones del read que sirven para facilitarte la vida. Ve la tabla a seguir:
>
>
En el Bash existen diversas opciones del read que sirven para facilitarte la vida. Observa la siguiente tabla:
 
Line: 218 to 218
 
  -n num     Lee hasta num caracteres  
  Opción     Acción
  -p prompt     Escribe el prompt antes de hacer la lectura  
Changed:
<
<
  -t seg     Espera seg segundos para que la lectura sea concluída  
>
>
  -t seg     Espera seg segundos para que concluya la lectura  
 
  -s     Lo que está siendo tecleado no aparece en la pantalla  
Line: 253 to 253
 678
Changed:
<
<
En este ejemplo hicimos dos read: uno para la primera parte del CEP y otra para su complemento y de este modo formatamos la entrada de datos. El signo de pesos ($) después del último número tecleado, es porque el read no tiene el new-line implicito por default como lo tiene el echo.
>
>
En este ejemplo hicimos dos read: uno para la primera parte del CEP y otra para su complemento y de este modo formateamos la entrada de datos. El signo de pesos ($) después del último número tecleado, es porque el read no tiene el new-line implicito por default como lo tiene el echo.
  Para leer hasta que un determinado tiempo termine (conocido como time out):

$ read -t2 -p "Digite su nombre completo: " Nom || echo 'Ah perezoso!'
Changed:
<
<
Digite su nombre completo: JAh perezoso!
>
>
Escriba su nombre completo: JAh perezoso!
 $ echo $Nom

$

Changed:
<
<
Obviamente esto fue una broma, ya que solo tenía 3 segundos para digitar mi nombre completo y sólo me dio tiempo de teclear una J (aquella pegado en el Ah), pero sirvió para mostrar dos cosas:
>
>
Obviamente esto fue una broma, ya que solo tenía 3 segundos para escribir mi nombre completo y sólo me dio tiempo de teclear una J (aquella pegada al Ah), pero me sirvió para mostrar dos cosas:
 
Changed:
<
<
  1. El comando después del par de barras verticales (||) (el o lógico, te acuerdas?) será ejecutado en el caso que la digitación no haya sido concluída en el tiempo estipulado;
  2. La variable Nom permaneció vacía. Ella tendrá valores solamente quando el <ENTER> sea tecleado.
>
>
  1. El comando después del par de barras verticales (||) (el o lógico, te acuerdas?) será ejecutado en el caso que la escritura no haya terminado en el tiempo estipulado;
  2. La variable Nom permaneció vacía. Esta tendrá valores solamente cuando el <ENTER> sea tecleado.
 
Changed:
<
<
Para leer un dato sin ser exhibido en la pantalla:
>
>
Para leer un dato sin ser mostrado en la pantalla:
 
$ read -sp "Seña: "
Line: 278 to 278
 secreto :)
Changed:
<
<
Aprovecho un error para mostrarte un detalle de programación. Cuando escribi l primera línea, me olvidé de colocar el nombre de la variable que iría a recibir la seña, y sólo noté eso cuando fui a listar su valor. Por suerte la variable $REPLY del Bash, posee la última cadena leída y me aproveché de esto para no perder el viaje. Verifica tu mismo lo que acabé de hacer.
>
>
Aprovecho un error para mostrarte un detalle de programación. Cuando escribi la primera línea, me olvidé de colocar el nombre de la variable que iría a recibir la contraseña, y sólo noté eso cuando fui a listar su valor. Por suerte la variable $REPLY del Bash, posee la última cadena leída y me aproveché de esto para no perder el viaje. Verifica tu mismo lo que acabo de hacer.
 
Changed:
<
<
Pero el ejemplo que dí, era para mostrar que la opción -s impide que lo que está siendo tecleado vaya para la pantalla. Como en el ejemplo anterior, la falta del new-line hizo con que el prompt del comando ($) permaneciese en la misma línea.
>
>
Pero el ejemplo que dí, era para mostrar que la opción -s impide que lo que está siendo tecleado se vea en la pantalla. Como en el ejemplo anterior, la falta del new-line hizo con que el prompt del comando ($) permaneciese en la misma línea.
  Bien, ahora que sabemos leer de la pantalla, veamos como se leen los datos de los archivos.

Vamos a leer archivos?

Changed:
<
<
Como ya te habia dicho y te debes de acordar, el while verifica un comando y ejecuta un bloque de instrucciones en cuanto este comando sea bien ejecutado. Cuando estás leyendo un archivo que te dá permiso de lectura, el read sólo será mal ejecutado quando alcanze el EOF (end of file), de esta forma podemos leer un archivo de dos maneras:
>
>
Como ya te habia dicho y te debes de acordar, el while verifica un comando y ejecuta un bloque de instrucciones mientras este comando de una respuesta correcta. Cuando estás leyendo un archivo que te dá permiso de lectura, el read sólo dará una respuesta errónea cuando alcance el EOF (end of file), de esta forma podemos leer un archivo de dos maneras:
 
Changed:
<
<
1 - Redireccionando la entrada del archivo para el bloque del while así:
>
>
1 - Redireccionando la entrada del archivo hacia el bloque del while así:
 
    while read Línea
Line: 297 to 297
  done < archivo
Changed:
<
<
2 - Redireccionando la salida de un cat para el while, de la siguiente forma:
>
>
2 - Redireccionando la salida de un cat hacia el while, de la siguiente forma:
 
    cat archivo |
Line: 316 to 316
  Desventaja del primer proceso:
Changed:
<
<
  • en un bloque de instrucciones grande, el redireccionamento queda poco visible, lo que a veces perjudica la vizualización del código;
>
>
  • en un bloque de instrucciones grande, el redireccionamento queda poco visible, lo que a veces perjudica la visualización del código;
  Ventaja del segundo proceso:
Changed:
<
<
  • Como el nombre del archivo está antes del while, es más fácil la vizualización del código.
>
>
  • Como el nombre del archivo está antes del while, es más fácil la visualización del código.
  Desventajas del segundo proceso:
Changed:
<
<
  • El Pipe (|) llama un subshell para interpretarlo, volviendo el proceso más lento, pesado y a veces problemático (vea los ejemplos que siguen).
>
>
  • El Pipe (|) llama un subshell para interpretarlo, volviendo el proceso más lento, pesado y a veces problemático (mira los ejemplos que siguen).
 
$ cat readpipe.sh
Line: 361 to 361
 Acabó, Último=:(vacío):
Changed:
<
<
Como viste, el script lista todas sus própias líneas con un signo de menos (-) antes y otro después y en el final exhibe el contenido de la variable $Ultimo. Sin embargo, nota que el contenido de esta variable permanece como (vacío).
>
>
Como viste, el script lista todas sus própias líneas con un signo de menos (-) antes y otro después y al final muestra el contenido de la variable $Ultimo. Sin embargo, observa que el contenido de esta variable permanece como (vacío).
       - Será que la variable no fue actualizada?
Changed:
<
<
     - Fue, y eso puede ser comprobado porque la línea echo "-$Ultimo-" lista correctamente las líneas.
>
>
     - Lo fue, y eso puede ser comprobado porque la línea echo "-$Ultimo-" lista correctamente las líneas.
 
Changed:
<
<
     - Entonces porque pasó eso?
>
>
     - Entonces que paso?
 
Changed:
<
<
     - Por que como ya te dije, el bloque de instrucciones redireccionado por el pipe (|) es ejecutado en un subshell y allí las variables son actualizadas. Cuando este subshell termina, las actualizaciones de las variables van junto con él, para los quintos infiernos. Nota que voy a hacer un pequeño cambio pasando el archivo por redireccionamento de entrada (<) y las cosas pasarán a funcionar en la forma más perfecta:
>
>
     - Pues que como ya te dije, el bloque de instrucciones redireccionado por el pipe (|) es ejecutado en un subshell y allí las variables son actualizadas. Cuando este subshell termina, las actualizaciones de las variables se van junto con él, para los quintos infiernos. Observa que voy a hacer un pequeño cambio pasando el archivo por redireccionamento de entrada (<) y así las cosas pasarán a funcionar de una forma más perfecta:
 
$ cat redirread.sh
Line: 386 to 386
 echo "Acabó, Último=:$Ultimo:"
Changed:
<
<
Y vé su ejecución sin errores:
>
>
Y mira su ejecución sin errores:
 
$ redirread.sh
Line: 404 to 404
 Acabó, Último=:echo "Acabó, Último=:$Ultimo:":
Changed:
<
<
Bien amigos de la Red Shell, para finalizar el comando read sólo falta un pequeño e importante detalle que voy a mostrar utilizando un ejemplo práctico. Supone que quieres listar en pantalla un archivo y a cada diez registros esta lista pararía para que el operador pudiese leer el contenido de la pantalla y sólo volviera a funcionar (scroll) después que el operador digitase cualquier tecla. Para no gastar un absurdo de papel (de la Linux Magazine), voy a hacer esta lista en la horizontal y mi archivo (numeros), tiene 30 registros solamente con números secuenciales. Ve:
>
>
Bien amigos de la Red Shell, para finalizar el comando read sólo falta un pequeño e importante detalle que voy a mostrar utilizando un ejemplo práctico. Imagina que quieres listar en pantalla un archivo y que cada diez registros esta lista se detenga para que el operador pueda leer el contenido de la pantalla y sólo volverá a funcionar (scroll) después que el operador pulse cualquier tecla. Para no gastar absurdamente papel (de la Linux Magazine), voy a hacer esta lista en la horizontal y mi archivo (numeros), que tiene 30 registros solamente con números secuenciales. Mira:
 
$ seq 30 > numeros
Line: 422 to 422
 done < numeros
Changed:
<
<
Como forma de hacer un programa genérico creamos la variable $ContLin (por que en la vida real, los registros no son solamente números secuenciales) y pararemos para leer cuando el resto de la división por 10 sea cero (mandando la salida para /dev/null de forma de que no aparezca en la tela, ensuciandola). Sin embargo, cuando fui a ejecutarlo dió el siguiente error:
>
>
Como forma de hacer un programa genérico creamos la variable $ContLin (por que en la vida real, los registros no son solamente números secuenciales) y pararemos para leer cuando el resto de la división por 10 sea cero (mandando la salida para /dev/null de forma de que no aparezca en la pantalla, ensuciandola). Sin embargo, cuando fui a ejecutarlo me dio el siguiente error:
 
$ 10porpag.sh 1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30
Changed:
<
<
Nota que faltó el número 11 y que la lista no paró en el read. Lo que pasó es que la entrada del loop estaba redireccionada del archivo numeros y de esta forma, la lectura fue hecha en cima de este archivo, así perdimos el 11 (y tambiém el 22).
>
>
Fíjate que falta el número 11 y que la lista no se paro en el read. Lo que paso es que la entrada del loop estaba redireccionada desde el archivo numeros y de esta forma, la lectura fue hecha encima de este archivo, así perdimos el 11 (y tambiém el 22).
  Vamos a mostrar entonces como debería quedar para funcionar correctamente:
Line: 448 to 448
 done < numeros
Changed:
<
<
Observe que ahora la entrada del read fue redireccionada para /dev/tty, que no es nada más que el terminal corriente, explicitando de esta forma que aquella lectura seria hecha del teclado y no de números. Es bueno resaltar que esto no sucede solamente cuando usamos el redireccionamento de entrada, se hubieramos usado el redireccionamento via pipe (|), habría pasado lo mismo.
>
>
Observa que ahora la entrada del read fue redireccionada desde /dev/tty, que no es nada más que el terminal corriente, forzando de esta forma que la lectura sera hecha del teclado y no de números. Es bueno resaltar que esto no sucede solamente cuando usamos el redireccionamento de entrada, se hubieramos usado el redireccionamento via pipe (|), habría pasado lo mismo.
 
Changed:
<
<
Ve ahora su ejecución:
>
>
Observa ahora su ejecución:
 
$ 10porpag.sh
Line: 459 to 459
 21 22 23 24 25 26 27 28 29 30
Changed:
<
<
Esto está casi bien, pero falta un poco para quedar excelente. Vamos a mejorar un poco el ejemplo para que lo reproduzas y verifiques (pero antes de verificar, aumenta el número de registros de numeros o reduze el tamaño de la pantalla, para que haya una quiebra de página).
>
>
Esto está casi bien, pero falta un poco para quedar excelente. Vamos a mejorar un poco el ejemplo para que lo reproduzcas y verifiques (pero antes de verificar, aumenta el número de registros de numeros o reduce el tamaño de la pantalla, para que haya un salto de página).
 
$ cat 10porpag.sh
Line: 481 to 481
 done < numeros
Changed:
<
<
El cambio principal hecho en este ejemplo, es con relación a la quiebra de página, ya que es hecha a cada cantidad-de-líneas-de-pantalla (tput lines) menos (-) 3, o sea, si la pantalla tiene 25 líneas, listará 22 registros y parará para lectura. En el comando read también fue hecha una alteración, incluindo un -n1 para leer solamente un caracter sin ser necesariamente un <ENTER> y la opción -p para dar el mensaje.
>
>
El cambio principal hecho en este ejemplo, es con relación al salto de página, ya que esta hecho en cada cantidad-de-líneas-de-pantalla (tput lines) menos (-) 3, o sea, si la pantalla tiene 25 líneas, listará 22 registros y parará para su lectura. En el comando read también fue hecha una alteración, incluyendo un -n1 para leer solamente un caracter sin ser necesariamente un <ENTER> y la opción -p para dar el mensaje.
 
Changed:
<
<
     - Bien mi amigo, por hoy es todo porque me parece que estás lleno de esto...
>
>
     - Bien amigo mio, por hoy ya basta porque me parece que estás saturado de esto...
 
Changed:
<
<
     - No estoy, realmente puede continuar...
>
>
     - No, no lo estoy, realmente puede continuar...
 
Changed:
<
<
     - Si tu no estás, yo sí... Pero ya que estás tan entusiasmado com el Shell, te voy a dejar un ejercicio de aprendizaje que mejorar tu CDteca que es bastante simple. Reescribe tu programa que catastra CDs para montar toda la pantalla com un único echo y después vá posicionandose frente a cada campo para recibir los valores que serán tecleados por el operador.
>
>
     - Si tu no lo estás, yo sí... Pero ya que estás tan entusiasmado con el Shell, te voy a dejar un ejercicio de aprendizaje que mejorara tu CDteca y que es bastante simple. Reescribe tu programa que registra CDs para montar toda la pantalla con un único echo y que después vaya posicionandose frente a cada campo para recibir los valores que serán tecleados por el operador.
 
Changed:
<
<
Y no te olvides, cualquer duda o falta de compañia para tomar un chopp o hasta para hablar mal de los políticos lo único que tienes que hacer es mandarme un e-mail para julio.neves@gmail.com. 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 julio.neves@uniriotec.br para informarse.
>
>
Y no te olvides, 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 julio.neves@gmail.com. Voy aprovechar también 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 julio.neves@uniriotec.br para informarse.
  Gracias y hasta la próxima

Revision 803 Feb 2008 - JulioNeves

Line: 1 to 1
Changed:
<
<

Conversa de Bar Parte VII

>
>

Conversación de Bar Parte VII

 


Revision 713 Feb 2007 - JulioNeves

Line: 1 to 1
 

Conversa de Bar Parte VII


Line: 491 to 491
  Y no te olvides, cualquer duda o falta de compañia para tomar un chopp o hasta para hablar mal de los políticos lo único que tienes que hacer es mandarme un e-mail para julio.neves@gmail.com. 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 julio.neves@uniriotec.br para informarse.
Changed:
<
<
Gracias y hasta la próxima!
>
>
Gracias y hasta la próxima
 

-- HumbertoPina - 17 Jan 2007

Revision 603 Feb 2007 - JulioNeves

Line: 1 to 1
 

Conversa de Bar Parte VII


Line: 194 to 194
 
$ grep julio /etc/passwd
Changed:
<
<
julio:x:500:544:Julio C. Neves � 7070:/home/julio:/bin/bash
>
>
julio:x:500:544:Julio C. Neves - 7070:/home/julio:/bin/bash
 $ oIFS="$IFS" # Grabando IFS $ IFS=: $ grep julio /etc/passwd | read lname lixo uid gid coment home shell
Line: 202 to 202
 julio 500 544
Changed:
<
<
Julio C. Neves � 7070
>
>
Julio C. Neves - 7070
 /home/julio /bin/bash $ IFS="$oIFS" # Restaurando IFS

Revision 517 Jan 2007 - Main.HumbertoPina

Line: 1 to 1
Changed:
<
<

Conversa de Bar Parte VII En construcción...

>
>

Conversa de Bar Parte VII

 


Line: 7 to 7
       - Si, realmente tuve que colocar mucha materia gris en la pantalla, pero creo que conseguí! Bueno, por lo menos en los tests que hice la cosa funcionó, pero tu siempre me colocas piedras en el camino!
Changed:
<
<
     - No es tan así, programar en shell es muy fácil, lo que vale son los consejos y macetes que no son triviales. Las correcciones que te hago, son justamente para mostrarlos. Pero vamos a pedir dos chopps en cuanto doy una miradita en tu script.
>
>
     - No es tan así, programar en shell es muy fácil, lo que vale son los consejos y los detalles de programación que te doy, que no son triviales. Las correcciones que te hago, son justamente para mostrarlos. Pero vamos a pedir dos chopps en cuanto doy una miradita en tu script.
       - Mozo, trae dos. No se olvide que uno es sin espuma!
Line: 62 to 62
 
bold   Coloca la pantalla en modo de realce
Opciones de tput   Efecto
cup lin col   CUrsor Position - Posiciona el cursor en la línea lin y coluna col. El origen es cero
Changed:
<
<
rev   Coloca la pantalla en modo de video invertido
>
>
rev   Coloca la pantalla en modo de video inverso
 
blink   Los caracteres tecleados aparecerán piscando
smso   Idéntico al anterior
smul   A partir de esta instrución, los caracteres tecleados aparecerán sublineados en la pantalla
Line: 79 to 79
 
rc   Restore Cursor position - Coloca el cursor en la posición marcada por el último sc
Changed:
<
<
Vamos a hacer un programa bien sencillo para mostrar algunos atributos de este comando. Es el famoso usado y abusado Hola Mundo sólo que esta frase será escrita en el centro de la pantalla y en video reverso y después de eso, el cursor volverá para la posición en que estaba antes de escribir esta frase tan creativa. Vea:
>
>
Vamos a hacer un programa bien sencillo para mostrar algunos atributos de este comando. Es el famoso usado y abusado Hola Mundo, sólo que esta frase será escrita en el centro de la pantalla y en video inverso y después de eso, el cursor volverá para la posición en que estaba antes de escribir esta frase tan creativa. Vea:
 
$ cat hola.sh
Line: 93 to 93
 Columna=$(((Columnas - 11) / 2)) # Centrando el mensaje en la pantalla tput sc # Grabando posición del cursor tput cup $Línea $Columna # Posicionándose para escribir
Changed:
<
<
tput rev # Video reverso
>
>
tput rev # Video inverso
 echo Hola Mundo! tput sgr0 # Restaura video a normal tput rc # Restaura cursor en posición original
Line: 126 to 126
 Columna=$(((Columnas - ${#1}) / 2)) #Centrando el mensaje en la pantalla put sc # Grabando posición del cursor tput cup $Línea $Columna # Posicionándose para escribir
Changed:
<
<
tput rev # Video reverso
>
>
tput rev # Video inverso
 echo $1 tput sgr0 # Restaura video a normal tput rc # Restaura cursor en la posición original
Line: 233 to 233
 12345
Changed:
<
<
Ou simplificando com a opção -p:
>
>
O simplificando con la opción -p:
 
$ read -p "Matricula: " Mat
Line: 278 to 278
 secreto :)
Changed:
<
<
Aproveché un error para mostrar un macete. Cuando escribi l primera línea, me olvidé de colocar el nombre de la variable que iría a recibir la seña, y sólo noté eso cuando fui a listar su valor. Por suerte la variable $REPLY del Bash, posee la última cadena leída y me aproveché de esto para no perder el viaje. Verifica tu mismo lo que acabé de hacer.
>
>
Aprovecho un error para mostrarte un detalle de programación. Cuando escribi l primera línea, me olvidé de colocar el nombre de la variable que iría a recibir la seña, y sólo noté eso cuando fui a listar su valor. Por suerte la variable $REPLY del Bash, posee la última cadena leída y me aproveché de esto para no perder el viaje. Verifica tu mismo lo que acabé de hacer.
  Pero el ejemplo que dí, era para mostrar que la opción -s impide que lo que está siendo tecleado vaya para la pantalla. Como en el ejemplo anterior, la falta del new-line hizo con que el prompt del comando ($) permaneciese en la misma línea.
Line: 320 to 320
  Ventaja del segundo proceso:
Changed:
<
<
  • Como el nombre del archivo está antes del while, es más fácil l vizualización del código.
>
>
  • Como el nombre del archivo está antes del while, es más fácil la vizualización del código.
  Desventajas del segundo proceso:
Line: 361 to 361
 Acabó, Último=:(vacío):
Changed:
<
<
Como viste, el script lista todas sus própias líneas con un signo de menos (-) antes y otro después y en el final exihbe el contenido de la variable $Ultimo. Nota sin embargo que el contenido de esta variable permanece como (vacío).
>
>
Como viste, el script lista todas sus própias líneas con un signo de menos (-) antes y otro después y en el final exhibe el contenido de la variable $Ultimo. Sin embargo, nota que el contenido de esta variable permanece como (vacío).
       - Será que la variable no fue actualizada?
Line: 369 to 369
       - Entonces porque pasó eso?
Changed:
<
<
     - Por que como te dije, el bloque de instrucciones redireccionado por el pipe (|) es ejecutado en un subshell y allí las variables son actualizadas. Cuando este subshell termina, las actualizaciones de las variables van para los quintos infiernos, junto con él. Nota que voy a hacer un pequeño cambio pasando el archivo por redireccionamento de entrada (<) y las cosas pasarán a funcionar en la forma mas perfecta:
>
>
     - Por que como ya te dije, el bloque de instrucciones redireccionado por el pipe (|) es ejecutado en un subshell y allí las variables son actualizadas. Cuando este subshell termina, las actualizaciones de las variables van junto con él, para los quintos infiernos. Nota que voy a hacer un pequeño cambio pasando el archivo por redireccionamento de entrada (<) y las cosas pasarán a funcionar en la forma más perfecta:
 
$ cat redirread.sh
Line: 386 to 386
 echo "Acabó, Último=:$Ultimo:"
Changed:
<
<
Y vé su ejecución perfecta:
>
>
Y vé su ejecución sin errores:
 
$ redirread.sh
Line: 404 to 404
 Acabó, Último=:echo "Acabó, Último=:$Ultimo:":
Changed:
<
<
Bem amigos da Rede Shell, para finalizar o comando read só falta mais um pequeno e importante macete que vou mostrar utilizando um exemplo prático. Suponha que você queira listar na tela um archivo e a cada dez registros esta listagem pararia para que o operador pudesse ler o conteúdo da tela e ela só voltasse a rolar (scroll) após o operador digitar qualquer tecla. Para não gastar papel (da Linux Magazine) pra chuchu, vou fazer esta listagem na horizontal e o meu archivo (numeros), tem 30 registros somente com números seqüênciais. Veja:
>
>
Bien amigos de la Red Shell, para finalizar el comando read sólo falta un pequeño e importante detalle que voy a mostrar utilizando un ejemplo práctico. Supone que quieres listar en pantalla un archivo y a cada diez registros esta lista pararía para que el operador pudiese leer el contenido de la pantalla y sólo volviera a funcionar (scroll) después que el operador digitase cualquier tecla. Para no gastar un absurdo de papel (de la Linux Magazine), voy a hacer esta lista en la horizontal y mi archivo (numeros), tiene 30 registros solamente con números secuenciales. Ve:
 
$ seq 30 > numeros $ cat 10porpag.sh #!/bin/bash
Changed:
<
<
# Prg de teste para escrever # 10 líneas e parar para ler # Versão 1
>
>
# Prg de test para escribir # 10 líneas y parar para leer # Versión 1
  while read Num do let ContLin++ # Contando...
Changed:
<
<
echo -n "$Num " # -n para nao saltar línea
>
>
echo -n "$Num " # -n para no saltar línea
  ((ContLin % 10)) > /dev/null || read done < numeros
Changed:
<
<
Na tentativa de fazer um programa genérico criamos a variável $ContLin (por que na vida real, os registros não são somente números seqüenciais) e parávamos para ler quando o resto da divisão por 10 fosse zero (mandando a saída para /dev/null de forma a não aparecer na tela, sujando-a). Porém, quando fui executar deu a seguinte zebra:
>
>
Como forma de hacer un programa genérico creamos la variable $ContLin (por que en la vida real, los registros no son solamente números secuenciales) y pararemos para leer cuando el resto de la división por 10 sea cero (mandando la salida para /dev/null de forma de que no aparezca en la tela, ensuciandola). Sin embargo, cuando fui a ejecutarlo dió el siguiente error:
 
$ 10porpag.sh 1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30
Changed:
<
<
Repare que faltou o número 11 e a listagem não parou no read. O que houve foi que toda a entrada do loop estava redirecionada do archivo numeros e desta forma, a leitura foi feita encima deste archivo, desta forma perdendo o 11 (e também o 22).
>
>
Nota que faltó el número 11 y que la lista no paró en el read. Lo que pasó es que la entrada del loop estaba redireccionada del archivo numeros y de esta forma, la lectura fue hecha en cima de este archivo, así perdimos el 11 (y tambiém el 22).
 
Changed:
<
<
Vamos mostrar então como deveria ficar para funcionar a contento:
>
>
Vamos a mostrar entonces como debería quedar para funcionar correctamente:
 
$ cat 10porpag.sh #!/bin/bash
Changed:
<
<
# Prg de teste para escrever # 10 líneas e parar para ler # Versão 2
>
>
# Prg de test para escribir # 10 líneas y parar para leer # Versión 2
  while read Num do let ContLin++ # Contando...
Changed:
<
<
echo -n "$Num " # -n para nao saltar línea
>
>
echo -n "$Num " # -n para no saltar línea
  ((ContLin % 10)) > /dev/null || read < /dev/tty done < numeros
Changed:
<
<
Observe que agora a entrada do read foi redirecionada por /dev/tty, que nada mais é senão o terminal corrente, explicitando desta forma que aquela leitura seria feita do teclado e não de numeros. É bom realçar que isto não acontece somente quando usamos o redirecionamento de entrada, se houvéssemos usado o redirecionamento via pipe (|), o mesmo teria ocorrido.
>
>
Observe que ahora la entrada del read fue redireccionada para /dev/tty, que no es nada más que el terminal corriente, explicitando de esta forma que aquella lectura seria hecha del teclado y no de números. Es bueno resaltar que esto no sucede solamente cuando usamos el redireccionamento de entrada, se hubieramos usado el redireccionamento via pipe (|), habría pasado lo mismo.
 
Changed:
<
<
Veja agora a sua execução:
>
>
Ve ahora su ejecución:
 
$ 10porpag.sh
Line: 459 to 459
 21 22 23 24 25 26 27 28 29 30
Changed:
<
<
Isto está quase bom mas falta um pouco para ficar excelente. Vamos melhorar um pouco o exemplo para que você o reproduza e teste (mas antes de testar aumente o número de registros de numeros ou reduza o tamanho da tela, para que haja quebra).
>
>
Esto está casi bien, pero falta un poco para quedar excelente. Vamos a mejorar un poco el ejemplo para que lo reproduzas y verifiques (pero antes de verificar, aumenta el número de registros de numeros o reduze el tamaño de la pantalla, para que haya una quiebra de página).
 
$ cat 10porpag.sh #!/bin/bash
Changed:
<
<
# Prg de teste para escrever # 10 líneas e parar para ler # Versão 3
>
>
# Prg de test para escribir # 10 líneas y parar para leer # Versión 3
  clear while read Num
Line: 475 to 475
  echo "$Num" ((ContLin % (`tput lines` - 3))) || {
Changed:
<
<
read -n1 -p"Tecle Algo " < /dev/tty # para ler qq caractere clear # limpa a tela apos leitura
>
>
read -n1 -p"Teclee Algo " < /dev/tty # para leer cualquier caracter clear # limpia la pantalla despues de la lectura
  } done < numeros
Changed:
<
<
A mudança substancial feita neste exemplo é com relação à quebra de página, já que ela é feita a cada quantidade-de-líneas-da-tela (tput lines) menos (-) 3, isto é, se a tela tem 25 línea, listará 22 registros e parará para leitura. No comando read também foi feita uma alteração, inserido um -n1 para ler somente um caractere sem ser necessariamente um <ENTER> e a opção -p para dar a mensagem.
>
>
El cambio principal hecho en este ejemplo, es con relación a la quiebra de página, ya que es hecha a cada cantidad-de-líneas-de-pantalla (tput lines) menos (-) 3, o sea, si la pantalla tiene 25 líneas, listará 22 registros y parará para lectura. En el comando read también fue hecha una alteración, incluindo un -n1 para leer solamente un caracter sin ser necesariamente un <ENTER> y la opción -p para dar el mensaje.
 
Changed:
<
<
     - Bem meu amigo, por hoje é só porque acho que você já está de saco cheio...
>
>
     - Bien mi amigo, por hoy es todo porque me parece que estás lleno de esto...
 
Changed:
<
<
     - Num tô não, pode continuar...
>
>
     - No estoy, realmente puede continuar...
 
Changed:
<
<
     - Se você não estiver eu estou... Mas já que você está tão empolgado com o Shell, vou te deixar um exercício de apredizagem para você melhorar a sua CDteca que é bastante simples. Reescreva o seu programa que cadastra CDs para montar toda a tela com um único echo e depois vá posicionando à frente de cada campo para receber os valores que serão teclados pelo operador.
>
>
     - Si tu no estás, yo sí... Pero ya que estás tan entusiasmado com el Shell, te voy a dejar un ejercicio de aprendizaje que mejorar tu CDteca que es bastante simple. Reescribe tu programa que catastra CDs para montar toda la pantalla com un único echo y después vá posicionandose frente a cada campo para recibir los valores que serán tecleados por el operador.
 
Changed:
<
<
Não se esqueça, qualquer dúvida ou falta de companhia para um chope é só mandar um e-mail para julio.neves@gmail.com. Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação enShell (de 40 horas) que mande um e-mail para julio.neves@uniriotec.br para informar-se. Valeu!
>
>
Y no te olvides, cualquer duda o falta de compañia para tomar un chopp o hasta para hablar mal de los políticos lo único que tienes que hacer es mandarme un e-mail para julio.neves@gmail.com. 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 julio.neves@uniriotec.br para informarse.
 
Added:
>
>
Gracias y hasta la próxima!
 
Changed:
<
<
-- HumbertoPina - 16 Jan 2007
>
>
-- HumbertoPina - 17 Jan 2007

Revision 416 Jan 2007 - Main.HumbertoPina

Line: 1 to 1
 

Conversa de Bar Parte VII En construcción...


Line: 139 to 139
  Columna=`$(((Columnas - ${#*}) / 2))` #Centrando el mensaje en la pantalla
Changed:
<
<
y la línea echo $1 pasaría a ser echo $*. Pero no se olvide de que cuando lo ejecute, tiene que pasar la frase que desea centrar como parámetro.
>
>
y la línea echo $1 pasaría a ser echo $*. Pero no se olvide de que cuando lo ejecute, tiene que pasar la frase que deseas centrar como un parámetro.
 
Changed:
<
<

E agora podemos ler os dados da tela

>
>

Y ahora podemos leer los dados de la pantalla

 
Changed:
<
<
Bem a partir de agora vamos aprender tudo sobre leitura, só não posso ensinar a ler cartas e búzios porque se eu soubesse, estaria rico, num pub londrino tomando scotch e não enum boteco desses tomando chope. Mas vamos enfrente.
>
>
Bien, a partir de ahora vamos a aprender todo sobre lectura, solo no te puedo enseñar a leer las cartas o los buzios, porque sino estaria rico en un pub de Londres, tomando scotch y no en un bar tomando chopp. Pero vamos a continuar.
 
Changed:
<
<
Da última vez que nos encontramos aqui eu já dei uma palínea sobre o comando read. Para começarmos a sua analise mais detalhada. veja só isso:
>
>
La última vez que nos encontramos aqui ya te dí una introducción sobre el comando read. Para comenzar su análisis más detallada. ve esto:
 
$ read var1 var2 var3
Changed:
<
<
Papo de Botequim
>
>
Conversa de Bar
 $ echo $var1
Changed:
<
<
Papo
>
>
Conversa
 $ echo $var2 de $ echo $var3
Changed:
<
<
Botequim
>
>
Bar
 $ read var1 var2
Changed:
<
<
Papo de Botequim
>
>
Conversa de Bar
 $ echo $var1
Changed:
<
<
Papo
>
>
Conversa
 $ echo $var2
Changed:
<
<
de Botequim
>
>
de Bar
 
Changed:
<
<
Como você viu, o read recebe uma lista separada por espaços enbranco e coloca cada item desta lista enuma variável. Se a quantidade de variáveis for menor que a quantidade de itens, a última variável recebe o restante.
>
>
Como viste, el read recibe una lista separada por espacios en blanco y coloca cada ítem de esta lista en una variable. Si la cantidad de variables es menor que la cantidad de ítems, la última variable recibe el resto de los parámetros.
 
Changed:
<
<
Eu disse lista separada por espaços enbranco? Agora que você já conhece tudo sobre o $IFS (Inter Field Separator) que eu te apresentei quando falávamos do comando for, será que ainda acredita nisso? Vamos testar direto no prompt:
>
>
Yo mencioné una lista separada por espacios en blanco? Ahora que ya conoces todo sobre el $IFS (Inter Field Separator) que te presenté cuando hablamos del comando for, será que todavia crees eso? Vamos a verificar directo en el prompt:
 
$ oIFS="$IFS" $ IFS=: $ read var1 var2 var3
Changed:
<
<
Papo de Botequim
>
>
Conversa de Bar
 $ echo $var1
Changed:
<
<
Papo de Botequim
>
>
Conversa de Bar
 $ echo $var2

$ echo $var3

$ read var1 var2 var3

Changed:
<
<
Papo:de:Botequim
>
>
Conversa:de:Bar
 $ echo $var1
Changed:
<
<
Papo
>
>
Conversa
 $ echo $var2 de $ echo $var3
Changed:
<
<
Botequim
>
>
Bar
 $ IFS="$oIFS"
Changed:
<
<
Viu, estava furado! O read lê uma lista, assim como o for, separada pelos caracteres da variável $IFS. Então veja como isso pode facilitar a sua vida:
>
>
Viste, estava equivocado! La verdad es que el read lee una lista, así como el for, separada por los caracteres de la variable $IFS. Entonces vea como eso puede facilitarte la vida:
 
$ grep julio /etc/passwd julio:x:500:544:Julio C. Neves � 7070:/home/julio:/bin/bash
Changed:
<
<
$ oIFS="$IFS" # Salvando IFS
>
>
$ oIFS="$IFS" # Grabando IFS
 $ IFS=: $ grep julio /etc/passwd | read lname lixo uid gid coment home shell $ echo -e "$lname\n$uid\n$gid\n$coment\n$home\n$shell"
Line: 208 to 208
 $ IFS="$oIFS" # Restaurando IFS
Changed:
<
<
Como você viu, a saída do grep foi redirecionada para o comando read que leu todos os campos de uma só tacada. A opção -e do echo foi usada para que o \n fosse entendido como um salto de línea (new line), e não como um literal.
>
>
Como viste, la salda del grep fuei redireccionada para el comando read que leyó todos los campos de una sola vez. La opción -e del echo fue usada para que el \n fuera entendido como un salto de línea (new line), y no como un literal.
 
Changed:
<
<
Sob o Bash existem diversas opções do read que servem para facilitar a sua vida. Veja a tabela a seguir:
>
>
En el Bash existen diversas opciones del read que sirven para facilitarte la vida. Ve la tabla a seguir:
 
Changed:
<
<
Opções do comando read no Bash
  -s     O que está sendo teclado não aparece na tela  
  Opção     Ação
  -p prompt     Escreve o prompt antes de fazer a leitura  
  -n num     Lê até num caracteres  
  -t seg     Espera seg segundos para que a leitura seja concluída  
>
>
Opciones del comando read en Bash
  -s     Lo que está siendo tecleado no aparece en la pantalla  
  Opción     Acción
  -p prompt     Escribe el prompt antes de hacer la lectura  
  -n num     Lee hasta num caracteres  
  -t seg     Espera seg segundos para que la lectura sea concluída  
 
Changed:
<
<
E agora direto aos exemplos curtos para demonstrar estas opções.
>
>
Y ahora directo a los ejemplos cortos para demostrar estas opciones.
 
Changed:
<
<
Para ler um campo "Matrícula":
>
>
Para leer un campo "Matrícula":
 
Changed:
<
<
$ echo -n "Matricula: "; read Mat # -n nao salta línea
>
>
$ echo -n "Matricula: "; read Mat # -n no salta línea
 Matricula: 12345 $ echo $Mat 12345
Line: 242 to 242
 12345
Changed:
<
<
Para ler uma determinada quantidade de caracteres:
>
>
Para leer una determinada cantidad de caracteres:
 
$ read -n5 -p"CEP: " Num ; read -n3 -p- Compl
Line: 253 to 253
 678
Changed:
<
<
Neste exemplo fizemos dois read: um para a primeira parte do CEP e outra para o seu complemento, deste modo formatando a entrada de dados. O cifrão ($) após o último algarismo teclado, é porque o read não tem o new-line implícito por default como o tem o echo.
>
>
En este ejemplo hicimos dos read: uno para la primera parte del CEP y otra para su complemento y de este modo formatamos la entrada de datos. El signo de pesos ($) después del último número tecleado, es porque el read no tiene el new-line implicito por default como lo tiene el echo.
 
Changed:
<
<
Para ler que até um determinado tempo se esgote (conhecido como time out):
>
>
Para leer hasta que un determinado tiempo termine (conocido como time out):
 
Changed:
<
<
$ read -t2 -p "Digite seu nome completo: " Nom || echo 'Eta moleza!' Digite seu nome completo: JEta moleza!
>
>
$ read -t2 -p "Digite su nombre completo: " Nom || echo 'Ah perezoso!' Digite su nombre completo: JAh perezoso!
 $ echo $Nom

$

Changed:
<
<
Obviamente isto foi uma brincadeira, pois só tinha 3 segundos para digitar o meu nome completo e só me deu tempo de teclar um J (aquele colado no Eta), mas serviu para mostrar duas coisas:
>
>
Obviamente esto fue una broma, ya que solo tenía 3 segundos para digitar mi nombre completo y sólo me dio tiempo de teclear una J (aquella pegado en el Ah), pero sirvió para mostrar dos cosas:
 
Changed:
<
<
  1. O comando após o par de barras verticais (||) (o ou lógico, lembra-se?) será executado caso a digitação não tenha sido concluída no tempo estipulado;
  2. A variável Nom permaneceu vazia. Ela será valorada somente quando o <ENTER> for teclado.
>
>
  1. El comando después del par de barras verticales (||) (el o lógico, te acuerdas?) será ejecutado en el caso que la digitación no haya sido concluída en el tiempo estipulado;
  2. La variable Nom permaneció vacía. Ella tendrá valores solamente quando el <ENTER> sea tecleado.
 
Changed:
<
<
Para ler um dado sem ser exibido na tela:
>
>
Para leer un dato sin ser exhibido en la pantalla:
 
Changed:
<
<
$ read -sp "Senha: " Senha: $ echo $REPLY segredo :)
>
>
$ read -sp "Seña: " Seña: $ echo $REPLY secreto :)
 
Changed:
<
<
Aproveitei um erro para mostrar um macete. Quando escrevi a primeira línea, esqueci de colocar o nome da variável que iria receber a senha, e só notei quando ia listar o seu valor. Felizmente a variável $REPLY do Bash, possui a última cadeia lida e me aproveitei disso para não perder a viagem. Teste você mesmo o que acabei de fazer.
>
>
Aproveché un error para mostrar un macete. Cuando escribi l primera línea, me olvidé de colocar el nombre de la variable que iría a recibir la seña, y sólo noté eso cuando fui a listar su valor. Por suerte la variable $REPLY del Bash, posee la última cadena leída y me aproveché de esto para no perder el viaje. Verifica tu mismo lo que acabé de hacer.
 
Changed:
<
<
Mas o exemplo que dei, era para mostrar que a opção -s impede o que está sendo teclado de ir para a tela. Como no exemplo anterior, a falta do new-line fez com que o prompt de comando ($) permanecesse na mesma línea.
>
>
Pero el ejemplo que dí, era para mostrar que la opción -s impide que lo que está siendo tecleado vaya para la pantalla. Como en el ejemplo anterior, la falta del new-line hizo con que el prompt del comando ($) permaneciese en la misma línea.
 
Changed:
<
<
Bem, agora que sabemos ler da tela vejamos como se lê os dados dos archivos.
>
>
Bien, ahora que sabemos leer de la pantalla, veamos como se leen los datos de los archivos.
 
Changed:
<
<

Vamos ler archivos?

>
>

Vamos a leer archivos?

 
Changed:
<
<
Como eu já havia lhe dito, e você deve se lembrar, o while testa um comando e executa um bloco de instruções enquanto este comando for bem sucedido. Ora quando você está lendo um archivo que lhe dá permissão de leitura, o read só será mal sucedido quando alcançar o EOF (end of file), desta forma podemos ler um archivo de duas maneiras:
>
>
Como ya te habia dicho y te debes de acordar, el while verifica un comando y ejecuta un bloque de instrucciones en cuanto este comando sea bien ejecutado. Cuando estás leyendo un archivo que te dá permiso de lectura, el read sólo será mal ejecutado quando alcanze el EOF (end of file), de esta forma podemos leer un archivo de dos maneras:
 
Changed:
<
<
1 - Redirecionando a entrada do archivo para o bloco do while assim:
>
>
1 - Redireccionando la entrada del archivo para el bloque del while así:
 
    while read Línea
Line: 297 to 297
  done < archivo
Changed:
<
<
2 - Redirecionando a saída de um cat para o while, da seguinte maneira:
>
>
2 - Redireccionando la salida de un cat para el while, de la siguiente forma:
 
    cat archivo |
Line: 307 to 307
  done
Changed:
<
<
Cada um dos processos tem suas vantagens e desvantagens:
>
>
Cada uno de los procesos tiene sus ventajas y desventajas:
 
Changed:
<
<
Vantagens do primeiro processo:
>
>
Ventajas del primer proceso:
 
Changed:
<
<
  • É mais rápido;
  • Não necessita de um subshell para assisti-lo;
>
>
  • Es más rápido;
  • No necesita de un subshell para asistirlo;
 
Changed:
<
<
Desvantagem do primeiro processo:
>
>
Desventaja del primer proceso:
 
Changed:
<
<
  • enum bloco de instruções grande, o redirecionamento fica pouco visível o que por vezes prejudica a vizualização do código;
>
>
  • en un bloque de instrucciones grande, el redireccionamento queda poco visible, lo que a veces perjudica la vizualización del código;
 
Changed:
<
<
Vantagem do segundo processo:
>
>
Ventaja del segundo proceso:
 
Changed:
<
<
  • Como o nome do archivo está antes do while, é mais fácil a vizualização do código.
>
>
  • Como el nombre del archivo está antes del while, es más fácil l vizualización del código.
 
Changed:
<
<
Desvantagens do segundo processo:
>
>
Desventajas del segundo proceso:
 
Changed:
<
<
  • O Pipe (|) chama um subshell para interpretá-lo, tornando o processo mais lento, pesado e por vezes problemático (veja o exemplo a seguir).

Para ilustrar o que foi dito, veja estes exemplos a seguir:

>
>
  • El Pipe (|) llama un subshell para interpretarlo, volviendo el proceso más lento, pesado y a veces problemático (vea los ejemplos que siguen).
 
$ cat readpipe.sh #!/bin/bash # readpipe.sh
Changed:
<
<
# Exemplo de read passando archivo por pipe.
>
>
# Ejemplo de read pasando archivo por pipe.
 
Changed:
<
<
Ultimo="(vazio)" cat $0 | # Passando o arq. do script ($0) p/ while
>
>
Ultimo="(vacío)" cat $0 | # Pasando el arch. del script ($0) p/ while
 while read Línea do Ultimo="$Línea" echo "-$Ultimo-" done
Changed:
<
<
echo "Acabou, Último=:$Ultimo:"
>
>
echo "Acabó, Último=:$Ultimo:"
 
Changed:
<
<
Vamos ver sua execução:
>
>
Vamos a ver su ejecución:
 
$ readpipe.sh -#!/bin/bash- -# readpipe.sh-
Changed:
<
<
-# Exemplo de read passando archivo por pipe.-
>
>
-# Ejemplo de read pasando archivo por pipe.-
 --
Changed:
<
<
-Ultimo="(vazio)"- -cat $0 | # Passando o arq. do script ($0) p/ while-
>
>
-Ultimo="(vacío)"- -cat $0 | # Pasando el arch. del script ($0) p/ while-
 -while read Línea- -do- -Ultimo="$Línea"- -echo "-$Ultimo-"- -done-
Changed:
<
<
-echo "Acabou, Último=:$Ultimo:"- Acabou, Último=:(vazio):
>
>
-echo "Acabó, Último=:$Ultimo:"- Acabó, Último=:(vacío):
 
Changed:
<
<
Como você viu, o script lista todas as suas próprias líneas com um sinal de menos (-) antes e outro depois de cada, e no final exibe o conteúdo da variável $Ultimo. Repare no entanto que o conteúdo desta variável permanece como (vazio).
>
>
Como viste, el script lista todas sus própias líneas con un signo de menos (-) antes y otro después y en el final exihbe el contenido de la variable $Ultimo. Nota sin embargo que el contenido de esta variable permanece como (vacío).
 
Changed:
<
<
     - Ué será que a variável não foi atualizada?
>
>
     - Será que la variable no fue actualizada?
 
Changed:
<
<
     - Foi, e isso pode ser comprovado porque a línea echo "-$Ultimo-" lista corretamente as líneas.
>
>
     - Fue, y eso puede ser comprobado porque la línea echo "-$Ultimo-" lista correctamente las líneas.
 
Changed:
<
<
     - Então porque isso aconteceu?
>
>
     - Entonces porque pasó eso?
 
Changed:
<
<
     - Por que como eu disse, o bloco de instruções redirecionado pelo pipe (|) é executado enum subshell e lá as variáveis são atualizadas. Quando este subshell termina, as atualizações das variáveis vão para os píncaros do inferno junto com ele. Repare que vou fazer uma pequena mudança nele, passando o archivo por redirecionamento de entrada (<) e as coisas passarão a funcionar na mais perfeita ordem:
>
>
     - Por que como te dije, el bloque de instrucciones redireccionado por el pipe (|) es ejecutado en un subshell y allí las variables son actualizadas. Cuando este subshell termina, las actualizaciones de las variables van para los quintos infiernos, junto con él. Nota que voy a hacer un pequeño cambio pasando el archivo por redireccionamento de entrada (<) y las cosas pasarán a funcionar en la forma mas perfecta:
 
$ cat redirread.sh #!/bin/bash # redirread.sh
Changed:
<
<
# Exemplo de read passando archivo por pipe.
>
>
# Ejemplo de read pasando archivo por redireccionamento de entrada (<).
 
Changed:
<
<
Ultimo="(vazio)"
>
>
Ultimo="(vacío)"
 while read Línea do Ultimo="$Línea" echo "-$Ultimo-"
Changed:
<
<
done < $0 # Passando o arq. do script ($0) p/ while echo "Acabou, Último=:$Ultimo:"
>
>
done < $0 # Pasando el arch. del script ($0) p/ while echo "Acabó, Último=:$Ultimo:"
 
Changed:
<
<
E veja a sua perfeita execução:
>
>
Y vé su ejecución perfecta:
 
$ redirread.sh -#!/bin/bash- -# redirread.sh-
Changed:
<
<
-# Exemplo de read passando archivo por pipe.-
>
>
-# Ejemplo de read pasando archivo por redireccionamento de entrada (<).-
 --
Changed:
<
<
-Ultimo="(vazio)"-
>
>
-Ultimo="(vacío)"-
 -while read Línea- -do- -Ultimo="$Línea"- -echo "-$Ultimo-"-
Changed:
<
<
-done < $0 # Passando o arq. do script ($0) p/ while- -echo "Acabou, Último=:$Ultimo:"- Acabou, Último=:echo "Acabou, Último=:$Ultimo:":
>
>
-done < $0 # Pasando el arch. del script ($0) p/ while- -echo "Acabó, Último=:$Ultimo:"- Acabó, Último=:echo "Acabó, Último=:$Ultimo:":
 

Bem amigos da Rede Shell, para finalizar o comando read só falta mais um pequeno e importante macete que vou mostrar utilizando um exemplo prático. Suponha que você queira listar na tela um archivo e a cada dez registros esta listagem pararia para que o operador pudesse ler o conteúdo da tela e ela só voltasse a rolar (scroll) após o operador digitar qualquer tecla. Para não gastar papel (da Linux Magazine) pra chuchu, vou fazer esta listagem na horizontal e o meu archivo (numeros), tem 30 registros somente com números seqüênciais. Veja:

Line: 494 to 492
 Não se esqueça, qualquer dúvida ou falta de companhia para um chope é só mandar um e-mail para julio.neves@gmail.com. Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação enShell (de 40 horas) que mande um e-mail para julio.neves@uniriotec.br para informar-se. Valeu!
Changed:
<
<
-- HumbertoPina - 12 Jan 2007
>
>
-- HumbertoPina - 16 Jan 2007

Revision 315 Jan 2007 - Main.HumbertoPina

Line: 1 to 1
 

Conversa de Bar Parte VII En construcción...


Line: 79 to 79
 
rc   Restore Cursor position - Coloca el cursor en la posición marcada por el último sc
Changed:
<
<
Vamos fazer um programa bem besta (e portanto fácil) para mostrar alguns atributos deste comando. É o famoso e famigerado Alô Mundo só que esta frase será escrita no centro da tela e envídeo reverso e após isso, o cursor voltará para a posição enque estava antes de escrever esta tão criativa frase. Veja:
>
>
Vamos a hacer un programa bien sencillo para mostrar algunos atributos de este comando. Es el famoso usado y abusado Hola Mundo sólo que esta frase será escrita en el centro de la pantalla y en video reverso y después de eso, el cursor volverá para la posición en que estaba antes de escribir esta frase tan creativa. Vea:
 
Changed:
<
<
$ cat alo.sh
>
>
$ cat hola.sh
 #!/bin/bash # Script bobo para testar
Changed:
<
<
# o comando tput (versao 1)
>
>
# el comando tput (versión 1)
 
Changed:
<
<
Colunas=`tput cols` # Salvando quantidade colunas Líneas=`tput lines` # Salvando quantidade líneas Línea=$((Líneas / 2)) # Qual eh a línea do meio da tela? Coluna=$(((Colunas - 9) / 2)) # Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Línea $Coluna # Posicionando para escrever
>
>
Colunas=`tput cols` # Grabando cantidad colunas Líneas=`tput lines` # Grabando cantidad líneas Línea=$((Líneas / 2)) # Cual es la línea del medio de la pantalla? Columna=$(((Columnas - 11) / 2)) # Centrando el mensaje en la pantalla tput sc # Grabando posición del cursor tput cup $Línea $Columna # Posicionándose para escribir
 tput rev # Video reverso
Changed:
<
<
echo Alô Mundo tput sgr0 # Restaura video ao normal tput rc # Restaura cursor aa posição original
>
>
echo Hola Mundo! tput sgr0 # Restaura video a normal tput rc # Restaura cursor en posición original
 
Changed:
<
<
Como o programa já está todo comentado, acho que a única explicação necessária seria para a línea enque é criada a variável Coluna e o estranho ali é aquele número 9, mas ele é o tamanho da cadeia que pretendo escrever (Alô Mundo).
>
>
Como el programa ya está todo comentado, creo que la única explicación necesaria sería para la línea en que es creada la variable Columna y lo estraño allí es aquél número 11, él es el tamaño de la cadena que pretendo escribir (Hola Mundo).
 
Changed:
<
<
Desta forma este programa somente conseguiria centrar cadeias de 9 caracteres, mas veja isso:
>
>
De esta forma, este programa solamente conseguiría centrar cadenas de 11 caracteres, sin embargo, ve esto:
 
Changed:
<
<
$ var=Papo
>
>
$ var=Conversa
 $ echo ${#var}
Changed:
<
<
4 $ var="Papo de Botequim"
>
>
8 $ var="Conversa de Bar"
 $ echo ${#var}
Changed:
<
<
16
>
>
15
 
Changed:
<
<
Ahhh, melhorou! Então agora sabemos que a construção ${#variavel} devolve a quantidade de caracteres de variavel. Assim sendo, vamos otimizar o nosso programa para que ele escreva envídeo reverso, no centro da tela a cadeia passada como parâmetro e depois o cursor volte à posição que estava antes da execução do script.
>
>
Ahhh, mejoró! Entonces ahora sabemos que la construcción ${#variable} devuelve la cantidad de caracteres de variable. De esta forma, vamos a optimizar nuestro programa para que escriba en video reverso y en el centro de la pantalla, la cadena pasada como parámetro y que después el cursor vuelva a la posición en que estaba antes de la ejecución del script.
 
Changed:
<
<
$ cat alo.sh
>
>
$ cat hola.sh
 #!/bin/bash # Script bobo para testar
Changed:
<
<
# o comando tput (versao 2)
>
>
# el comando tput (versión 2)
 
Changed:
<
<
Colunas=`tput cols` # Salvando quantidade colunas Líneas=`tput lines` # Salvando quantidade líneas Línea=$((Líneas / 2)) # Qual eh a línea do meio da tela? Coluna=$(((Colunas - ${#1}) / 2)) #Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Línea $Coluna # Posicionando para escrever
>
>
Columnas=`tput cols` # Grabando cantidad colunas Líneas=`tput lines` # Grabando cantidad líneas Línea=$((Líneas / 2)) # Cual es la línea del medio de la pantalla? Columna=$(((Columnas - ${#1}) / 2)) #Centrando el mensaje en la pantalla put sc # Grabando posición del cursor tput cup $Línea $Columna # Posicionándose para escribir
 tput rev # Video reverso echo $1
Changed:
<
<
tput sgr0 # Restaura video ao normal tput rc # Restaura cursor aa posição original
>
>
tput sgr0 # Restaura video a normal tput rc # Restaura cursor en la posición original
 
Changed:
<
<
Este script é igual ao anterior, só que trocamos o valor fixo da versão anterior (9), por ${#1}, onde este 1 é o $1 ou seja, esta construção devolve o tamanho do primeiro parâmetro passado para o programa. Se o parâmetro que eu quiser passar tiver espaços enbranco, teria que colocá-lo todo entre aspas, senão o $1 seria somente o primeiro pedaço. Para evitar este aborrecimento, é só substituir o $1 por $*, que como sabemos é o conjunto de todos os parâmetros. Então aquela línea ficaria assim:
>
>
Este script es igual al anterior, sólo que cambiamos el valor fijo de la versión anterior (9), por ${#1}, donde éste 1 es el $1 o sea, esta construcción devuelve el tamaño del primer parámetro pasado para el programa. Si el parámetro que yo quisiese pasar tuviese espacios en blanco, tendría que colocarlo todo entre comillas, sino el $1 sería solamente el primer pedazo. Para evitar este problema, es solo substituir el $1 por $*, que como sabemos es el conjunto de todos los parámetros. Entonces aquella línea quedaría así:
 
Changed:
<
<
Coluna=`$(((Colunas - ${#*}) / 2))` #Centrando a mensagem na tela
>
>
Columna=`$(((Columnas - ${#*}) / 2))` #Centrando el mensaje en la pantalla
 
Changed:
<
<
e a línea echo $1 passaria a ser echo $*. Mas não esqueça de qdo executar, passar a frase que vc desja centrar como parâmetro.
>
>
y la línea echo $1 pasaría a ser echo $*. Pero no se olvide de que cuando lo ejecute, tiene que pasar la frase que desea centrar como parámetro.
 

E agora podemos ler os dados da tela

Revision 215 Jan 2007 - Main.HumbertoPina

Line: 1 to 1
Changed:
<
<

Conversa de Bar Parte VII

>
>

Conversa de Bar Parte VII En construcción...

 


Line: 34 to 34
 
Changed:
<
<
     - Peraí, deixa ver se entendi. Primeiramente você coloca na variável Dir a última línea do archivo cujo nome é formado por /tmp/nome do operador ($LOGNAME)/parâmetro passado com nome do archivo a ser restaurado ($1). enseguida o grep -v que você montou exclui a línea enque estava o nome do diretório, isto é, sempre a última e manda o restante do archivo, que seria assim o archivo já limpo, para o diretório original e depois remove o archivo da "lixeira"; S E N S A C I O N A L! Impecável! Zero erro! Viu? você já está pegando as manhas do shell!
>
>
     - Un momento, dejame ver se entendí. Primero colocas en la variable Dir la última línea del archivo cuyo nombre está formado por /tmp/nombre del operador ($LOGNAME)/parámetro pasado con el nombre del archivo a ser restaurado ($1). Enseguida el grep -v que montaste borra esa línea en que estaba el nombre del directorio, o sea, siempre es la última y manda lo que resta del archivo, que sería el archivo ya limpio, para el directório original y después borra el archivo de la "lata de basura"; S E N S A C I O N A L! Impecable! Cero error! Viste? ya le estás agarrando las mañas al shell!
 
Changed:
<
<
     - Então vamulá chega de lesco-lesco e blá-blá-blá, de que você vai falar hoje?
>
>
     - Entonces vamos a continuar, basta de bla-bla-bla, de que vas a hablar hoy?
 
Changed:
<
<
     - É tô vendo que o bichinho do Shell te pegou. Que bom, mas vamos ver como se pode (e deve) ler dados e formatar telas e primeiramente vamos entender um comando que te dá todas as ferramentas para você formatar a sua tela de entrada de dados.
>
>
     - Ah! estoy viendo que el bichito del Shell se te contagió. Que bueno, vamos a ver como se puede (y debe) leer datos y formatar pantallas y primero vamos a entender un comando que te dá todas las herramientas para que formates tu pantalla de entrada de datos.
 
Changed:
<
<

O comando tput

>
>

El comando tput

 
Changed:
<
<
O maior uso deste comando é para posicionar o cursor na tela, mas também é muito usado para apagar dados da tela, saber a quantidade de líneas e colunas para poder posicionar corretamente um campo, apagar um campo cuja crítica detectou como errado. Enfim, quase toda a formatação da tela é feita por este comando.
>
>
El mayor uso de este comando es para posicionar el cursor en la pantalla, sin embargo también es muy usado para borrar datos de la pantalla, saber la cantidad de líneas y columnas para poder posicionar correctamente un campo, borrar un campo cuya crítica detectó como error. En fin, casi toda la formatación de la pantalla es hecha por este comando.
 
Changed:
<
<
Uns poucos atributos do comando tput podem eventualmente não funcionar se o modelo de terminal definido pela variável $TERM não tiver esta facilidade incorporada.
>
>
Unos pocos atributos del comando tput pueden eventualmente no funcionar, esto en el caso de que el modelo de terminal definido por la variable $TERM, no tenga esta posibilidad incorporada.
 
Changed:
<
<
Na tabela a seguir, apresenta os principais atributos do comando e os efeitos executados sobre o terminal, mas veja bem existem muito mais do que esses, veja só:
>
>
En la tabla a seguir, se presentan los principales atributos del comando y los efectos ejecutados sobre la pantalla, pero debes saber que existen muchos más de que esos, ve sino:
 
$ tput it 8
Changed:
<
<
Neste exemplo eu recebi o tamanho inicial da <TAB> ( Initial T ab), mas me diga: para que eu quero saber isso? Se você quiser saber tudo sobre o comando tput (e olha que é coisa que não acaba mais), veja em: http://www.cs.utah.edu/dept/old/texinfo/tput/tput.html#SEC4.
>
>
En este ejemplo recebí el tamaño inicial de la <TAB> ( Initial T ab), pero dime una cosa: para que quiero saber eso? Si quieres saber todo sobre el comando tput (y mira que es de nunca acabar), vea en: http://www.cs.utah.edu/dept/old/texinfo/tput/tput.html#SEC4.
 
Changed:
<
<
Principais Opções do Comando tput
rc   Restore Cursor position - Coloca o cursor na posição marcada pelo último sc
Opções do tput   Efeito
cup lin col   CUrsor Position - Posiciona o cursor na línea lin e coluna col. A origem é zero
bold   Coloca a tela enmodo de ênfase
rev   Coloca a tela enmodo de vídeo reverso
smso   Idêntico ao anterior
smul   A partir desta instrução, os caracteres teclados aparecerão sublíneados na tela
blink   Os caracteres teclados aparecerão piscando
sgr0   Após usar um dos atributos acima, use este para restaurar a tela ao seu modo normal
reset   Limpa o terminal e restaura suas definições de acordo com o terminfo ou seja, o terminal volta ao padrão definido pela variável $TERM  
lines   Devolve a quantidade de líneas da tela no momento da instrução
cols   Devolve a quantidade de colunas da tela no momento da instrução
el   Erase Line - Apaga a línea a partir da posição do cursor
ed   Erase Display - Apaga a tela a partir da posição do cursor
il n   Insert Lines - Insere n líneas a partir da posição do cursor
dl n   Delete Lines - Remove n líneas a partir da posição do cursor
ech n   Erase CHaracters - Apaga n caracteres a partir da posição do cursor
sc   Save Cursor position - Salva a posição do cursor
>
>
Principales Opciones del Comando tput
rc   Restore Cursor position - Coloca el cursor en la posición marcada por el último sc
Opciones de tput   Efecto
cup lin col   CUrsor Position - Posiciona el cursor en la línea lin y coluna col. El origen es cero
bold   Coloca la pantalla en modo de realce
rev   Coloca la pantalla en modo de video invertido
smso   Idéntico al anterior
smul   A partir de esta instrución, los caracteres tecleados aparecerán sublineados en la pantalla
blink   Los caracteres tecleados aparecerán piscando
sgr0   Después de usar uno de los atributos de arriba, use éste es para restaurar la pantalla a su modo normal
reset   Limpia la pantalla y restaura sus definiciones de acuerdo con el terminfo o sea, la pantalla vuelve al padrón definido por la variable $TERM  
lines   Devuelve la cantidad de líneas de la pantalla en el momento de la instrucción
cols   Devuelve la cantidad de columnas de la pantalla en el momento de la instrucción
el   Erase Line - Borra la línea a partir de la posición del cursor
ed   Erase Display - Borra la pantalla a partir de la posición del cursor
il n   Insert Lines - Introduce n líneas a partir de la posición del cursor
dl n   Delete Lines - Retira n líneas a partir de la posición del cursor
ech n   Erase CHaracters - Borra n caracteres a partir de la posición del cursor
sc   Save Cursor position - Graba la posición del cursor
 

Vamos fazer um programa bem besta (e portanto fácil) para mostrar alguns atributos deste comando. É o famoso e famigerado Alô Mundo só que esta frase será escrita no centro da tela e envídeo reverso e após isso, o cursor voltará para a posição enque estava antes de escrever esta tão criativa frase. Veja:

Revision 112 Jan 2007 - Main.HumbertoPina

Line: 1 to 1
Added:
>
>

Conversa de Bar Parte VII



     - Como dijiste? Repite que no te entiendo! Se te derritieron los pensamientos para hacer el scriptiziño que te pedí?

     - Si, realmente tuve que colocar mucha materia gris en la pantalla, pero creo que conseguí! Bueno, por lo menos en los tests que hice la cosa funcionó, pero tu siempre me colocas piedras en el camino!

     - No es tan así, programar en shell es muy fácil, lo que vale son los consejos y macetes que no son triviales. Las correcciones que te hago, son justamente para mostrarlos. Pero vamos a pedir dos chopps en cuanto doy una miradita en tu script.

     - Mozo, trae dos. No se olvide que uno es sin espuma!


$ cat restaura #!/bin/bash # # Restaura archivos borrados via erreeme #

if [ $# -eq 0 ] then echo "Uso: $0 " exit 1 fi # Lee el nombre del directorio original en la última línea Dir=`tail -1 /tmp/$LOGNAME/$1` # O grep -v borra la última línea y crea el # archivo con directorio y nombres originales grep -v $Dir /tmp/$LOGNAME/$1 > $Dir/$1 # Borra el archivo que ya estaba moribundo rm /tmp/$LOGNAME/$1

     - Peraí, deixa ver se entendi. Primeiramente você coloca na variável Dir a última línea do archivo cujo nome é formado por /tmp/nome do operador ($LOGNAME)/parâmetro passado com nome do archivo a ser restaurado ($1). enseguida o grep -v que você montou exclui a línea enque estava o nome do diretório, isto é, sempre a última e manda o restante do archivo, que seria assim o archivo já limpo, para o diretório original e depois remove o archivo da "lixeira"; S E N S A C I O N A L! Impecável! Zero erro! Viu? você já está pegando as manhas do shell!

     - Então vamulá chega de lesco-lesco e blá-blá-blá, de que você vai falar hoje?

     - É tô vendo que o bichinho do Shell te pegou. Que bom, mas vamos ver como se pode (e deve) ler dados e formatar telas e primeiramente vamos entender um comando que te dá todas as ferramentas para você formatar a sua tela de entrada de dados.

O comando tput

O maior uso deste comando é para posicionar o cursor na tela, mas também é muito usado para apagar dados da tela, saber a quantidade de líneas e colunas para poder posicionar corretamente um campo, apagar um campo cuja crítica detectou como errado. Enfim, quase toda a formatação da tela é feita por este comando.

Uns poucos atributos do comando tput podem eventualmente não funcionar se o modelo de terminal definido pela variável $TERM não tiver esta facilidade incorporada.

Na tabela a seguir, apresenta os principais atributos do comando e os efeitos executados sobre o terminal, mas veja bem existem muito mais do que esses, veja só:

$ tput it 8

Neste exemplo eu recebi o tamanho inicial da <TAB> ( Initial T ab), mas me diga: para que eu quero saber isso? Se você quiser saber tudo sobre o comando tput (e olha que é coisa que não acaba mais), veja em: http://www.cs.utah.edu/dept/old/texinfo/tput/tput.html#SEC4.

Principais Opções do Comando tput
rc   Restore Cursor position - Coloca o cursor na posição marcada pelo último sc
Opções do tput   Efeito
cup lin col   CUrsor Position - Posiciona o cursor na línea lin e coluna col. A origem é zero
bold   Coloca a tela enmodo de ênfase
rev   Coloca a tela enmodo de vídeo reverso
smso   Idêntico ao anterior
smul   A partir desta instrução, os caracteres teclados aparecerão sublíneados na tela
blink   Os caracteres teclados aparecerão piscando
sgr0   Após usar um dos atributos acima, use este para restaurar a tela ao seu modo normal
reset   Limpa o terminal e restaura suas definições de acordo com o terminfo ou seja, o terminal volta ao padrão definido pela variável $TERM  
lines   Devolve a quantidade de líneas da tela no momento da instrução
cols   Devolve a quantidade de colunas da tela no momento da instrução
el   Erase Line - Apaga a línea a partir da posição do cursor
ed   Erase Display - Apaga a tela a partir da posição do cursor
il n   Insert Lines - Insere n líneas a partir da posição do cursor
dl n   Delete Lines - Remove n líneas a partir da posição do cursor
ech n   Erase CHaracters - Apaga n caracteres a partir da posição do cursor
sc   Save Cursor position - Salva a posição do cursor

Vamos fazer um programa bem besta (e portanto fácil) para mostrar alguns atributos deste comando. É o famoso e famigerado Alô Mundo só que esta frase será escrita no centro da tela e envídeo reverso e após isso, o cursor voltará para a posição enque estava antes de escrever esta tão criativa frase. Veja:

$ cat alo.sh #!/bin/bash # Script bobo para testar # o comando tput (versao 1)

Colunas=`tput cols` # Salvando quantidade colunas Líneas=`tput lines` # Salvando quantidade líneas Línea=$((Líneas / 2)) # Qual eh a línea do meio da tela? Coluna=$(((Colunas - 9) / 2)) # Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Línea $Coluna # Posicionando para escrever tput rev # Video reverso echo Alô Mundo tput sgr0 # Restaura video ao normal tput rc # Restaura cursor aa posição original

Como o programa já está todo comentado, acho que a única explicação necessária seria para a línea enque é criada a variável Coluna e o estranho ali é aquele número 9, mas ele é o tamanho da cadeia que pretendo escrever (Alô Mundo).

Desta forma este programa somente conseguiria centrar cadeias de 9 caracteres, mas veja isso:

$ var=Papo $ echo ${#var} 4 $ var="Papo de Botequim" $ echo ${#var} 16

Ahhh, melhorou! Então agora sabemos que a construção ${#variavel} devolve a quantidade de caracteres de variavel. Assim sendo, vamos otimizar o nosso programa para que ele escreva envídeo reverso, no centro da tela a cadeia passada como parâmetro e depois o cursor volte à posição que estava antes da execução do script.

$ cat alo.sh #!/bin/bash # Script bobo para testar # o comando tput (versao 2)

Colunas=`tput cols` # Salvando quantidade colunas Líneas=`tput lines` # Salvando quantidade líneas Línea=$((Líneas / 2)) # Qual eh a línea do meio da tela? Coluna=$(((Colunas - ${#1}) / 2)) #Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Línea $Coluna # Posicionando para escrever tput rev # Video reverso echo $1 tput sgr0 # Restaura video ao normal tput rc # Restaura cursor aa posição original

Este script é igual ao anterior, só que trocamos o valor fixo da versão anterior (9), por ${#1}, onde este 1 é o $1 ou seja, esta construção devolve o tamanho do primeiro parâmetro passado para o programa. Se o parâmetro que eu quiser passar tiver espaços enbranco, teria que colocá-lo todo entre aspas, senão o $1 seria somente o primeiro pedaço. Para evitar este aborrecimento, é só substituir o $1 por $*, que como sabemos é o conjunto de todos os parâmetros. Então aquela línea ficaria assim:

    Coluna=`$(((Colunas - ${#*}) / 2))` #Centrando a mensagem na tela

e a línea echo $1 passaria a ser echo $*. Mas não esqueça de qdo executar, passar a frase que vc desja centrar como parâmetro.

E agora podemos ler os dados da tela

Bem a partir de agora vamos aprender tudo sobre leitura, só não posso ensinar a ler cartas e búzios porque se eu soubesse, estaria rico, num pub londrino tomando scotch e não enum boteco desses tomando chope. Mas vamos enfrente.

Da última vez que nos encontramos aqui eu já dei uma palínea sobre o comando read. Para começarmos a sua analise mais detalhada. veja só isso:

$ read var1 var2 var3 Papo de Botequim $ echo $var1 Papo $ echo $var2 de $ echo $var3 Botequim $ read var1 var2 Papo de Botequim $ echo $var1 Papo $ echo $var2 de Botequim

Como você viu, o read recebe uma lista separada por espaços enbranco e coloca cada item desta lista enuma variável. Se a quantidade de variáveis for menor que a quantidade de itens, a última variável recebe o restante.

Eu disse lista separada por espaços enbranco? Agora que você já conhece tudo sobre o $IFS (Inter Field Separator) que eu te apresentei quando falávamos do comando for, será que ainda acredita nisso? Vamos testar direto no prompt:

$ oIFS="$IFS" $ IFS=: $ read var1 var2 var3 Papo de Botequim $ echo $var1 Papo de Botequim $ echo $var2

$ echo $var3

$ read var1 var2 var3 Papo:de:Botequim $ echo $var1 Papo $ echo $var2 de $ echo $var3 Botequim $ IFS="$oIFS"

Viu, estava furado! O read lê uma lista, assim como o for, separada pelos caracteres da variável $IFS. Então veja como isso pode facilitar a sua vida:

$ grep julio /etc/passwd julio:x:500:544:Julio C. Neves � 7070:/home/julio:/bin/bash $ oIFS="$IFS" # Salvando IFS $ IFS=: $ grep julio /etc/passwd | read lname lixo uid gid coment home shell $ echo -e "$lname\n$uid\n$gid\n$coment\n$home\n$shell" julio 500 544 Julio C. Neves � 7070 /home/julio /bin/bash $ IFS="$oIFS" # Restaurando IFS

Como você viu, a saída do grep foi redirecionada para o comando read que leu todos os campos de uma só tacada. A opção -e do echo foi usada para que o \n fosse entendido como um salto de línea (new line), e não como um literal.

Sob o Bash existem diversas opções do read que servem para facilitar a sua vida. Veja a tabela a seguir:

Opções do comando read no Bash
  -s     O que está sendo teclado não aparece na tela  
  Opção     Ação
  -p prompt     Escreve o prompt antes de fazer a leitura  
  -n num     Lê até num caracteres  
  -t seg     Espera seg segundos para que a leitura seja concluída  

E agora direto aos exemplos curtos para demonstrar estas opções.

Para ler um campo "Matrícula":

$ echo -n "Matricula: "; read Mat # -n nao salta línea Matricula: 12345 $ echo $Mat 12345

Ou simplificando com a opção -p:

$ read -p "Matricula: " Mat Matricula: 12345 $ echo $Mat 12345

Para ler uma determinada quantidade de caracteres:

$ read -n5 -p"CEP: " Num ; read -n3 -p- Compl CEP: 12345-678$ $ echo $Num 12345 $ echo $Compl 678

Neste exemplo fizemos dois read: um para a primeira parte do CEP e outra para o seu complemento, deste modo formatando a entrada de dados. O cifrão ($) após o último algarismo teclado, é porque o read não tem o new-line implícito por default como o tem o echo.

Para ler que até um determinado tempo se esgote (conhecido como time out):

$ read -t2 -p "Digite seu nome completo: " Nom || echo 'Eta moleza!' Digite seu nome completo: JEta moleza! $ echo $Nom

$

Obviamente isto foi uma brincadeira, pois só tinha 3 segundos para digitar o meu nome completo e só me deu tempo de teclar um J (aquele colado no Eta), mas serviu para mostrar duas coisas:

  1. O comando após o par de barras verticais (||) (o ou lógico, lembra-se?) será executado caso a digitação não tenha sido concluída no tempo estipulado;
  2. A variável Nom permaneceu vazia. Ela será valorada somente quando o <ENTER> for teclado.

Para ler um dado sem ser exibido na tela:

$ read -sp "Senha: " Senha: $ echo $REPLY segredo :)

Aproveitei um erro para mostrar um macete. Quando escrevi a primeira línea, esqueci de colocar o nome da variável que iria receber a senha, e só notei quando ia listar o seu valor. Felizmente a variável $REPLY do Bash, possui a última cadeia lida e me aproveitei disso para não perder a viagem. Teste você mesmo o que acabei de fazer.

Mas o exemplo que dei, era para mostrar que a opção -s impede o que está sendo teclado de ir para a tela. Como no exemplo anterior, a falta do new-line fez com que o prompt de comando ($) permanecesse na mesma línea.

Bem, agora que sabemos ler da tela vejamos como se lê os dados dos archivos.

Vamos ler archivos?

Como eu já havia lhe dito, e você deve se lembrar, o while testa um comando e executa um bloco de instruções enquanto este comando for bem sucedido. Ora quando você está lendo um archivo que lhe dá permissão de leitura, o read só será mal sucedido quando alcançar o EOF (end of file), desta forma podemos ler um archivo de duas maneiras:

1 - Redirecionando a entrada do archivo para o bloco do while assim:

    while read Línea
    do
        echo $Línea
    done < archivo

2 - Redirecionando a saída de um cat para o while, da seguinte maneira:

    cat archivo |
    while read Línea 
    do
        echo $Línea
    done

Cada um dos processos tem suas vantagens e desvantagens:

Vantagens do primeiro processo:

  • É mais rápido;
  • Não necessita de um subshell para assisti-lo;

Desvantagem do primeiro processo:

  • enum bloco de instruções grande, o redirecionamento fica pouco visível o que por vezes prejudica a vizualização do código;

Vantagem do segundo processo:

  • Como o nome do archivo está antes do while, é mais fácil a vizualização do código.

Desvantagens do segundo processo:

  • O Pipe (|) chama um subshell para interpretá-lo, tornando o processo mais lento, pesado e por vezes problemático (veja o exemplo a seguir).

Para ilustrar o que foi dito, veja estes exemplos a seguir:

$ cat readpipe.sh #!/bin/bash # readpipe.sh # Exemplo de read passando archivo por pipe.

Ultimo="(vazio)" cat $0 | # Passando o arq. do script ($0) p/ while while read Línea do Ultimo="$Línea" echo "-$Ultimo-" done echo "Acabou, Último=:$Ultimo:"

Vamos ver sua execução:

$ readpipe.sh -#!/bin/bash- -# readpipe.sh- -# Exemplo de read passando archivo por pipe.- -- -Ultimo="(vazio)"- -cat $0 | # Passando o arq. do script ($0) p/ while- -while read Línea- -do- -Ultimo="$Línea"- -echo "-$Ultimo-"- -done- -echo "Acabou, Último=:$Ultimo:"- Acabou, Último=:(vazio):

Como você viu, o script lista todas as suas próprias líneas com um sinal de menos (-) antes e outro depois de cada, e no final exibe o conteúdo da variável $Ultimo. Repare no entanto que o conteúdo desta variável permanece como (vazio).

     - Ué será que a variável não foi atualizada?

     - Foi, e isso pode ser comprovado porque a línea echo "-$Ultimo-" lista corretamente as líneas.

     - Então porque isso aconteceu?

     - Por que como eu disse, o bloco de instruções redirecionado pelo pipe (|) é executado enum subshell e lá as variáveis são atualizadas. Quando este subshell termina, as atualizações das variáveis vão para os píncaros do inferno junto com ele. Repare que vou fazer uma pequena mudança nele, passando o archivo por redirecionamento de entrada (<) e as coisas passarão a funcionar na mais perfeita ordem:

$ cat redirread.sh #!/bin/bash # redirread.sh # Exemplo de read passando archivo por pipe.

Ultimo="(vazio)" while read Línea do Ultimo="$Línea" echo "-$Ultimo-" done < $0 # Passando o arq. do script ($0) p/ while echo "Acabou, Último=:$Ultimo:"

E veja a sua perfeita execução:

$ redirread.sh -#!/bin/bash- -# redirread.sh- -# Exemplo de read passando archivo por pipe.- -- -Ultimo="(vazio)"- -while read Línea- -do- -Ultimo="$Línea"- -echo "-$Ultimo-"- -done < $0 # Passando o arq. do script ($0) p/ while- -echo "Acabou, Último=:$Ultimo:"- Acabou, Último=:echo "Acabou, Último=:$Ultimo:":

Bem amigos da Rede Shell, para finalizar o comando read só falta mais um pequeno e importante macete que vou mostrar utilizando um exemplo prático. Suponha que você queira listar na tela um archivo e a cada dez registros esta listagem pararia para que o operador pudesse ler o conteúdo da tela e ela só voltasse a rolar (scroll) após o operador digitar qualquer tecla. Para não gastar papel (da Linux Magazine) pra chuchu, vou fazer esta listagem na horizontal e o meu archivo (numeros), tem 30 registros somente com números seqüênciais. Veja:

$ seq 30 > numeros $ cat 10porpag.sh #!/bin/bash # Prg de teste para escrever # 10 líneas e parar para ler # Versão 1

while read Num do let ContLin++ # Contando... echo -n "$Num " # -n para nao saltar línea ((ContLin % 10)) > /dev/null || read done < numeros

Na tentativa de fazer um programa genérico criamos a variável $ContLin (por que na vida real, os registros não são somente números seqüenciais) e parávamos para ler quando o resto da divisão por 10 fosse zero (mandando a saída para /dev/null de forma a não aparecer na tela, sujando-a). Porém, quando fui executar deu a seguinte zebra:

$ 10porpag.sh 1 2 3 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30

Repare que faltou o número 11 e a listagem não parou no read. O que houve foi que toda a entrada do loop estava redirecionada do archivo numeros e desta forma, a leitura foi feita encima deste archivo, desta forma perdendo o 11 (e também o 22).

Vamos mostrar então como deveria ficar para funcionar a contento:

$ cat 10porpag.sh #!/bin/bash # Prg de teste para escrever # 10 líneas e parar para ler # Versão 2

while read Num do let ContLin++ # Contando... echo -n "$Num " # -n para nao saltar línea ((ContLin % 10)) > /dev/null || read < /dev/tty done < numeros

Observe que agora a entrada do read foi redirecionada por /dev/tty, que nada mais é senão o terminal corrente, explicitando desta forma que aquela leitura seria feita do teclado e não de numeros. É bom realçar que isto não acontece somente quando usamos o redirecionamento de entrada, se houvéssemos usado o redirecionamento via pipe (|), o mesmo teria ocorrido.

Veja agora a sua execução:

$ 10porpag.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Isto está quase bom mas falta um pouco para ficar excelente. Vamos melhorar um pouco o exemplo para que você o reproduza e teste (mas antes de testar aumente o número de registros de numeros ou reduza o tamanho da tela, para que haja quebra).

$ cat 10porpag.sh #!/bin/bash # Prg de teste para escrever # 10 líneas e parar para ler # Versão 3

clear while read Num do ((ContLin++)) # Contando... echo "$Num" ((ContLin % (`tput lines` - 3))) || { read -n1 -p"Tecle Algo " < /dev/tty # para ler qq caractere clear # limpa a tela apos leitura } done < numeros

A mudança substancial feita neste exemplo é com relação à quebra de página, já que ela é feita a cada quantidade-de-líneas-da-tela (tput lines) menos (-) 3, isto é, se a tela tem 25 línea, listará 22 registros e parará para leitura. No comando read também foi feita uma alteração, inserido um -n1 para ler somente um caractere sem ser necessariamente um <ENTER> e a opção -p para dar a mensagem.

     - Bem meu amigo, por hoje é só porque acho que você já está de saco cheio...

     - Num tô não, pode continuar...

     - Se você não estiver eu estou... Mas já que você está tão empolgado com o Shell, vou te deixar um exercício de apredizagem para você melhorar a sua CDteca que é bastante simples. Reescreva o seu programa que cadastra CDs para montar toda a tela com um único echo e depois vá posicionando à frente de cada campo para receber os valores que serão teclados pelo operador.

Não se esqueça, qualquer dúvida ou falta de companhia para um chope é só mandar um e-mail para julio.neves@gmail.com. Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação enShell (de 40 horas) que mande um e-mail para julio.neves@uniriotec.br para informar-se. Valeu!

-- HumbertoPina - 12 Jan 2007

 
This site is powered by FoswikiCopyright © 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