Difference: TWikiBarTalk007 (1 vs. 11)

Revision 1125 Dec 2017 - Main.PauloSantana

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 576 to 576
  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 em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.
Changed:
<
<
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to of me .
>
>
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to of me .
  Thanks!
Added:
>
>
next

-- PauloSantana - 25 Dec 2017

Revision 1018 Mar 2014 - JulioNeves

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII



Added:
>
>
This is a very new translation from Portuguese to English. Please contribute to the development of this site indicating errors and and/or suggesting corrections and materials for this person.
      - What's up dude! It was very difficult to do the little script I asked you?

     - Yeah, I really had to think hard in front of the black screen but I think I succeeded! Well, at least in the tests I did the work thing, but you always have to look for problems!

Revision 913 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 483 to 483
 To not wasting paper (Linux Magazine), I'll make this list horizontally and my file (numbers) has 30 records only with sequential numbers. see:

Changed:
<
<
$ seq 30 | xargs -i echo lin {} > numbers # Criando arquivo numeros
>
>
$ seq 30 | xargs -i echo lin {} > numbers # Creating numbers file
 $ paste -sd':' numbers # This paste is to display content without being a #+ per row, using colons as separator lin 1:lin 2:lin 3:lin 4:lin 5:lin 6:lin 7:lin 8:lin 9:lin 10:lin 11:lin 12:lin 13:lin 14:lin 15:l

Revision 805 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 573 to 573
  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 em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.
Changed:
<
<
Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim.
>
>
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to of me .
 
Deleted:
<
<
Valeu!

-- JarbasJunior - 20 Oct 2005

 \ No newline at end of file
Added:
>
>
Thanks!

Revision 705 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 563 to 563
 done < numbers
Changed:
<
<
A mudança substancial feita neste exemplo é com relação à quebra de página, já que ela é feita a cada quantidade-de-linhas-da-tela (tput lines) menos (-) 3, isto é, se a tela tem 25 linha, 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.
>
>
A substantial change in this example is related to the page break, since it is made for each quantity-of-rows-of-screen (tput lines) less (-) 3, that is, if the screen has 25 rows, will list 22 records, and will stop for reading. In the read command a change was also made, inserted -n1 to read only one character without being necessarily a <ENTER> and the option -p to give the message.
 
Changed:
<
<
     - Bem meu amigo, por hoje é só porque acho que você já está de saco cheio...
>
>
     - Well my friend, we finished for today because I think you're tired...
 
Changed:
<
<
     - Num tô não, pode continuar...
>
>
     - I'm not, you can continue...
 
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.
>
>
     - If you are not I am... But since you're so excited about Shell, I'll leave you an exercise in learning programs for you to improve your CD Library that is quite simple. Rewrite your program that registers CDs to mount the whole screen with a single echo and then go positioning in front of each field to receive the values ​​that are typed by the operator.
  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 em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.

Revision 602 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 483 to 483
 To not wasting paper (Linux Magazine), I'll make this list horizontally and my file (numbers) has 30 records only with sequential numbers. see:

Changed:
<
<
$ seq 30 | xargs -i echo lin {} > numeros # Criando arquivo numeros $ paste -sd':' numeros # Este paste é para exibir o conteúdo sem ser um #+ por linha, usando dois-pontos como separador
>
>
$ seq 30 | xargs -i echo lin {} > numbers # Criando arquivo numeros $ paste -sd':' numbers # This paste is to display content without being a #+ per row, using colons as separator
 lin 1:lin 2:lin 3:lin 4:lin 5:lin 6:lin 7:lin 8:lin 9:lin 10:lin 11:lin 12:lin 13:lin 14:lin 15:l in 16:lin 17:lin 18:lin 19:lin 20:lin 21:lin 22:lin 23:lin 24:lin 25:lin 26:lin 27:lin 28:lin 29: lin 30 $ cat 10porpag.sh #!/bin/bash
Changed:
<
<
# Prg de teste para escrever # 10 linhas e parar para ler # Versão 1
>
>
# Test program to write # 10 lines and stop to read # Version 1
  while read Num do
Changed:
<
<
let ContLin++ # Contando... echo -n "$Num " # -n para nao saltar linha
>
>
let ContLin++ # Counting... echo -n "$Num " # -n not to jump row
  ((ContLin % 10)) > /dev/null || read
Changed:
<
<
done < numeros
>
>
done < numbers
 
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:
>
>
In an attempt to make a generic program we created the variable $ContLin (because in real life, the records aren't only sequential numbers) and we stopped to read when the rest of the division by 10 were zero (sending the output to /dev/null so as not to appear on the screen, dirtying it). However, when I run gave the following problem:
 
$ 10porpag.sh
Line: 511 to 511
 in 17 lin 18 lin 19 lin 20 lin 21 lin 23 lin 24 lin 25 lin 26 lin 27 lin 28 lin 29 lin 30 $
Changed:
<
<
Repare que faltou a linha lin 11 e a listagem não parou no read. O que houve foi que toda a entrada do loop estava redirecionada do arquivo numeros e desta forma, a leitura foi feita em cima deste arquivo, desta forma perdendo a lin 11 (e também a lin 22 ou qualquer linha múltipla de 11).
>
>
Note that missed the row lin 11 and the list did not stop at read. Happened that all input of loop was redirected from numbers file and thus the reading was taken upon this file, thereby losing lin 11 (and also lin 22 or any other row multiple 11).
 
Changed:
<
<
Vamos mostrar então como deveria ficar para funcionar a contento:
>
>
We will show how it should be for run correctly:
 
$ cat 10porpag.sh #!/bin/bash
Changed:
<
<
# Prg de teste para escrever # 10 linhas e parar para ler # Versão 2
>
>
# Test program to write # 10 lines and stop to read # Version 2
  while read Num do
Changed:
<
<
let ContLin++ # Contando... echo -n "$Num " # -n para nao saltar linha
>
>
let ContLin++ # Counting... echo -n "$Num " # -n not to jump row
  ((ContLin % 10)) > /dev/null || read < /dev/tty
Changed:
<
<
done < numeros
>
>
done < numbers
 
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.
>
>
Note that now the input of read was redirected by /dev/tty, which is nothing more than the current terminal, explaining this so that reading would be taken from the keyboard and not the numbers. It's good to note that this doesn't happen only when we use the input redirection, if we had used the redirect with pipe (|), the same would have occurred.
 
Changed:
<
<
Veja agora a sua execução:
>
>
See now it's execution:
 
$ 10porpag.sh
Line: 541 to 541
 lin 21 lin 22 lin 23 lin 24 lin 25 lin 26 lin 27 lin 28 lin 29 lin 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).
>
>
This is almost good but lacking a bit to become excellent. We will improve a little example for you to play and test (but before testing increases the number of records numbers or reduce the size of the screen, so there is breakage).
 
$ cat 10porpag.sh #!/bin/bash
Changed:
<
<
# Prg de teste para escrever # 10 linhas e parar para ler # Versão 3
>
>
# Test program to write # 10 lines and stop to read # Version 3
  clear while read Num do
Changed:
<
<
((ContLin++)) # Contando...
>
>
((ContLin++)) # Counting...
  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"Tecle Algo " < /dev/tty # to read any character clear # clears the screen after reading
  }
Changed:
<
<
done < numeros
>
>
done < numbers
 

A mudança substancial feita neste exemplo é com relação à quebra de página, já que ela é feita a cada quantidade-de-linhas-da-tela (tput lines) menos (-) 3, isto é, se a tela tem 25 linha, 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.

Line: 578 to 578
 Valeu!

-- JarbasJunior - 20 Oct 2005

Deleted:
<
<
 \ No newline at end of file

Revision 501 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 360 to 359
 

Let's read files?

Added:
>
>
As I have told you, and you must remember, the while tests a command and executes a block of statements while this command is successful. When you are reading a file that gives you permission to read the read will only be unsuccessful when it reaches the EOF (end of file), in this way we can read a file in two ways:
 
Changed:
<
<
As I have told you, and you must remember, the while tests a command and executes a block of statements while this command is successful. Well when you are reading a file that gives you permission to read the read will only be unsuccessful when it reaches the EOF (end of file), in this way we can read a file in two ways:

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

>
>
1 - Redirecting input from file for the block while so:
 
Changed:
<
<
while read Linha
>
>
while read Row
  do
Changed:
<
<
echo $Linha done < arquivo
>
>
echo $Row done < file
 
Changed:
<
<
2 - Redirecionando a saída de um cat para o while, da seguinte maneira:
>
>
2 - Redirecting output of a cat for while, as follows:
 
Changed:
<
<
cat arquivo | while read Linha
>
>
cat file while read Row
  do
Changed:
<
<
echo $Linha
>
>
echo $Row
  done
Changed:
<
<
Cada um dos processos tem suas vantagens e desvantagens:
>
>
Each process has its advantages and disadvantages:
 
Changed:
<
<
Vantagens do primeiro processo:
>
>
Advantages of the first case:
 
Changed:
<
<
  • É mais rápido;
  • Não necessita de um subshell para assisti-lo;
>
>
* It's faster; * You do not need a subshell to watch it;
 
Changed:
<
<
Desvantagem do primeiro processo:
>
>
Disadvantage of the process:
 
Changed:
<
<
  • Em um bloco de instruções grande, o redirecionamento fica pouco visível o que por vezes prejudica a vizualização do código;
>
>
* In a large block of instructions, the redirection is not very visible which sometimes impairs visualization of the code;
 
Changed:
<
<
Vantagem do segundo processo:
>
>
Advantage of the second method:
 
Changed:
<
<
  • Como o nome do arquivo está antes do while, é mais fácil a vizualização do código.
>
>
* As the name of the file is before of while is easier to visualize the code.
 
Changed:
<
<
Desvantagens do segundo processo:
>
>
Disadvantages of the second case:
 
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).
>
>
* The Pipe (|) calls a subshell to interpret it, making the process slower, heavier and sometimes problematic (see example below).
 
Changed:
<
<
Para ilustrar o que foi dito, veja estes exemplos a seguir:
>
>
To illustrate what has been said, check out these examples:
 
$ cat readpipe.sh #!/bin/bash # readpipe.sh
Changed:
<
<
# Exemplo de read passando arquivo por pipe.
>
>
# Example of read passing file for pipe.
 
Changed:
<
<
Ultimo="(vazio)" cat $0 | # Passando o arq. do script ($0) p/ while while read Linha
>
>
Last="(empty)" cat $0 | # Passing the script file ($0) for while while read Row
 do
Changed:
<
<
Ultimo="$Linha" echo "-$Ultimo-"
>
>
Last="$Row" echo "-$Last-"
 done
Changed:
<
<
echo "Acabou, Último=:$Ultimo:"
>
>
echo "Finished, Last=:$Last:"
 
Changed:
<
<
Vamos ver sua execução:
>
>
Let's see it's execution:
 
$ readpipe.sh -#!/bin/bash- -# readpipe.sh-
Changed:
<
<
-# Exemplo de read passando arquivo por pipe.-
>
>
-# Example of read passing file for pipe.-
 --
Changed:
<
<
-Ultimo="(vazio)"- -cat $0 | # Passando o arq. do script ($0) p/ while- -while read Linha-
>
>
-Last="(empty)"- -cat $0 | # Passing the script file ($0) for while- -while read Row-
 -do-
Changed:
<
<
-Ultimo="$Linha"- -echo "-$Ultimo-"-
>
>
-Last="$Row"- -echo "-$Last-"-
 -done-
Changed:
<
<
-echo "Acabou, Último=:$Ultimo:"- Acabou, Último=:(vazio):
>
>
-echo "Finished, Last=:$Last:"- Finished, Last=:(empty):
 
Changed:
<
<
Como você viu, o script lista todas as suas próprias linhas 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).
>
>
As you saw, the script list all their own rows with a minus sign (-) before and other after each, and at the end displays the contents of the variable $Last. Note however that the contents of this variable remains (empty).
 
Changed:
<
<
     - Ué será que a variável não foi atualizada?
>
>
     - Huh! Does the variable was not updated?
 
Changed:
<
<
     - Foi, e isso pode ser comprovado porque a linha echo "-$Ultimo-" lista corretamente as linhas.
>
>
     - It was, and this can be proven because the row echo "-$Last-" correctly list the rows.
 
Changed:
<
<
     - Então porque isso aconteceu?
>
>
     - So why did this happen?
 
Changed:
<
<
     - Por que como eu disse, o bloco de instruções redirecionado pelo pipe (|) é executado em um 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 arquivo por redirecionamento de entrada (<) e as coisas passarão a funcionar na mais perfeita ordem:
>
>
     - Because as I said, the block of instructions redirected by pipe (|) runs on a subshell and there the variables are updated. When this subshell ends, updates of variables go to hell along with him. Note that I'll make a small change in him, passing the file for input redirection (<) and things will operate in perfect order:
 
$ cat redirread.sh #!/bin/bash # redirread.sh
Changed:
<
<
# Exemplo de read passando arquivo por pipe.
>
>
# Example of read passing file for pipe.
 
Changed:
<
<
Ultimo="(vazio)" while read Linha
>
>
Last="(empty)" while read Row
 do
Changed:
<
<
Ultimo="$Linha" echo "-$Ultimo-" done < $0 # Passando o arq. do script ($0) p/ while echo "Acabou, Último=:$Ultimo:"
>
>
Last="$Row" echo "-$Last-" done < $0 # Passing the script file ($0) for while echo "Finished, Last=:$Last:"
 
Changed:
<
<
E veja a sua perfeita execução:
>
>
And see his perfect execution:
 
$ redirread.sh -#!/bin/bash- -# redirread.sh-
Changed:
<
<
-# Exemplo de read passando arquivo por pipe.-
>
>
-# Example of read passing file for pipe.-
 --
Changed:
<
<
-Ultimo="(vazio)"- -while read Linha-
>
>
-Last="(empty)"- -while read Row-
 -do-
Changed:
<
<
-Ultimo="$Linha"- -echo "-$Ultimo-"- -done < $0 # Passando o arq. do script ($0) p/ while- -echo "Acabou, Último=:$Ultimo:"- Acabou, Último=:echo "Acabou, Último=:$Ultimo:":
>
>
-Last="$Row"- -echo "-$Last-"- -done < $0 # Passing the script file ($0) for while- -echo "Finished, Last=:$Last:"- Finished, Last=:echo "Finished, Last=:$Last:":
 
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 arquivo 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 arquivo (numeros), tem 30 registros somente com números seqüênciais. Veja:
>
>
Well friends Shell Network, to finalize the read command I just need to talk about a small and important trick. I will show using a practical example. Suppose you want to display a file in the list and this list of ten records stop so that the operator could read the contents of the screen and it only came back to roll (scroll) after the operator enter any key. To not wasting paper (Linux Magazine), I'll make this list horizontally and my file (numbers) has 30 records only with sequential numbers. see:
 
$ seq 30 | xargs -i echo lin {} > numeros # Criando arquivo numeros

Revision 401 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 360 to 360
 

Let's read files?

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 arquivo 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 arquivo de duas maneiras:
>
>
As I have told you, and you must remember, the while tests a command and executes a block of statements while this command is successful. Well when you are reading a file that gives you permission to read the read will only be unsuccessful when it reaches the EOF (end of file), in this way we can read a file in two ways:
  1 - Redirecionando a entrada do arquivo para o bloco do while assim:

Revision 328 Feb 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part VII


Line: 214 to 214
 
9   Back to default color  
Changed:
<
<

E agora podemos ler os dados da tela

>
>

And now we can read the screen data

 
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 em um boteco desses tomando chope. Mas vamos em frente.
>
>
Well from now on we will learn all about reading, just can not teach reading letters and whelks because if I knew, I would be rich, a pub London drinking scotch and not those in a pub drinking beer. But let's move on.
 
Changed:
<
<
Da última vez que nos encontramos aqui eu já dei uma palinha sobre o comando read. Para começarmos a sua analise mais detalhada. veja só isso:
>
>
The last time we met here, I gave an introduction to the read command. To start a more detailed analysis check this:
 
$ read var1 var2 var3
Changed:
<
<
Papo de Botequim
>
>
Pub Talk
 $ echo $var1
Changed:
<
<
Papo
>
>
Talk
 $ echo $var2 de $ echo $var3
Changed:
<
<
Botequim
>
>
Pub
 $ read var1 var2
Changed:
<
<
Papo de Botequim
>
>
Pub Talk
 $ echo $var1
Changed:
<
<
Papo
>
>
Talk
 $ echo $var2
Changed:
<
<
de Botequim
>
>
Pub
 
Deleted:
<
<
Como você viu, o read recebe uma lista separada por espaços em branco e coloca cada item desta lista em uma variável. Se a quantidade de variáveis for menor que a quantidade de itens, a última variável recebe o restante.
 
Changed:
<
<
Eu disse lista separada por espaços em branco? 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:
>
>
As you saw, the read receives a separate list for blanks and places each item on this list in a variable. If the number of variables is less than the number of items, the last variable is assigned the remainder.

I said separated list by whitespace? Now that you know all about $IFS (Inter Field Separator) that I introduced you when we talked for command, will still believe that? Let's test the direct prompt:

 
$ oIFS="$IFS" $ IFS=: $ read var1 var2 var3
Changed:
<
<
Papo de Botequim
>
>
Pub Talk
 $ echo $var1
Changed:
<
<
Papo de Botequim
>
>
Pub Talk
 $ echo $var2

$ echo $var3

$ read var1 var2 var3

Changed:
<
<
Papo:de:Botequim
>
>
Pub:Talk
 $ echo $var1
Changed:
<
<
Papo
>
>
Talk
 $ echo $var2
Changed:
<
<
de
>
>
of
 $ echo $var3
Changed:
<
<
Botequim
>
>
Pub
 $ 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:
>
>
As you saw, was wrong! The read read a list, like for, separated by the characters of the variable $IFS. Then see how it can make your life easier:
 
$ grep julio /etc/passwd julio:x:500:544:Julio C. Neves - 7070:/home/julio:/bin/bash
Changed:
<
<
$ oIFS="$IFS" # Salvando IFS
>
>
$ oIFS="$IFS" # Saving IFS
 $ IFS=:
Changed:
<
<
$ grep julio /etc/passwd | read lname lixo uid gid coment home shell
>
>
$ grep julio /etc/passwd | read lname trash uid gid coment home shell
 $ echo -e "$lname\n$uid\n$gid\n$coment\n$home\n$shell" julio 500
Line: 278 to 279
 Julio C. Neves - 7070 /home/julio /bin/bash
Changed:
<
<
$ IFS="$oIFS" # Restaurando IFS
>
>
$ IFS="$oIFS" # Restoring 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 linha (new line), e não como um literal.
>
>
As you saw, the output grep was redirected to the read command that read all fields at once. The and of the echo was used for the \n be understood as a line jump (new line), and not as a literal.
 
Changed:
<
<
Sob o Bash existem diversas opções do read que servem para facilitar a sua vida. Veja a tabela a seguir:
>
>
Under the Bash there are several options of read that serve to make your life easier. See the following table:
 
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  
>
>
Options of the read command in Bash
  -s     What is being typed does not appear on screen  
  Option     Action
  -p prompt     Writes prompt before doing the reading  
  -n num     Reads up num characters  
  -t seg     Wait sec seconds for the reading to be completed  
 
Changed:
<
<
E agora direto aos exemplos curtos para demonstrar estas opções.
>
>
And now straight to short examples to demonstrate these options.
 
Changed:
<
<
Para ler um campo "Matrícula":
>
>
To read a "Matriculation" field:
 
Changed:
<
<
$ echo -n "Matricula: "; read Mat # -n nao salta linha Matricula: 12345
>
>
$ echo -n "Matriculation: "; read Mat # -n not jumping line Matriculation: 12345
 $ echo $Mat 12345
Changed:
<
<
Ou simplificando com a opção -p:
>
>
Or simplifying with the option -p:
 
Changed:
<
<
$ read -p "Matricula: " Mat Matricula: 12345
>
>
$ read -p "Matriculation: " Mat Matriculation: 12345
 $ echo $Mat 12345
Changed:
<
<
Para ler uma determinada quantidade de caracteres:
>
>
To read a certain number of characters:
 
$ read -n5 -p"CEP: " Num ; read -n3 -p- Compl
Line: 326 to 327
 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.
>
>
In this example did two read: one for the first part of the CEP and another for its complement, thereby formatting data entry. The dollar sign ($) after the last digit entered, is because the read have not new-line implied by default as is echo.
 
Changed:
<
<
Para ler que até um determinado tempo se esgote (conhecido como time out):
>
>
To read that up to a certain time runs out (known as time out):
 
Changed:
<
<
$ read -t2 -p "Digite seu nome completo: " Nom || echo 'Eta moleza!' Digite seu nome completo: JEta moleza!
>
>
$ read -t2 -p "Enter your full name: " Nom || echo 'So eazy!' Enter your full name: JSo eazy!
 $ 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:
>
>
Obviously this was a joke, because it only had 3 seconds to enter my full name and only gave me time to type a J (one pasted on So), but it served to show two things:
 
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. The command after the pair of vertical bars (||) (or logical, remember?) will run if the typing was not completed in the stipulated time;
  2. The Nom variable remained empty. It will be valued only when <ENTER> is entered.
 
Changed:
<
<
Para ler um dado sem ser exibido na tela:
>
>
To read a data without being displayed on the screen:
 
Changed:
<
<
$ read -sp "Senha: " Senha: $ echo $REPLY segredo :)
>
>
$ read -sp "Password : " Password: $ echo $REPLY secret :)
 
Changed:
<
<
Aproveitei um erro para mostrar um macete. Quando escrevi a primeira linha, 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.
>
>
I took advantage of an error to show a trick. When I wrote the first line, I forgot to put the name of the variable that would receive the password, and only noticed when I was going to list their value. Fortunately the $REPLY Bash variable have the last string read and it took me not to miss the trip. Test yourself what I just did.
 
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 linha.
>
>
But the example I gave was to show that the option -s prevents what is typed to go to the screen. As in the previous example, the lack of the new-line has made the prompt of command ($) remained on the same line.
 
Changed:
<
<
Bem, agora que sabemos ler da tela vejamos como se lê os dados dos arquivos.
>
>
Well, now that we see how to read the screen reads file data.
 
Changed:
<
<

Vamos ler arquivos?

>
>

Let's read files?

  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 arquivo 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 arquivo de duas maneiras:

Revision 225 Feb 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"
Changed:
<
<

Papo de botequim parte VII

>
>

Pub Talk Part VII

 


Changed:
<
<
     - Cumequié rapaz! Derreteu os pensamentos para fazer o scriptizinho que eu te pedi?
>
>
     - What's up dude! It was very difficult to do the little script I asked you?
 
Changed:
<
<
     - É, eu realmente tive de colocar muita pensação na tela preta mas acho que consegui! Bem, pelo menos no testes que fiz a coisa funcionou, mas você tem sempre que botar chifres em cabeça de cachorro!
>
>
     - Yeah, I really had to think hard in front of the black screen but I think I succeeded! Well, at least in the tests I did the work thing, but you always have to look for problems!
 
Changed:
<
<
     - Não é bem assim, programar em shell é muito fácil, o que vale são as dicas e macetes que não são triviais. As correções que te faço, são justamente para mostrá-los. Mas vamos pedir dois chopes enquanto dou uma olhadela no teu script.
>
>
     - Not so, in shell programming is very easy, what counts are the tips and tricks that are not trivial. The fixes that I do, is just to show them. But we order two beers while I have a look in your script.
 
Changed:
<
<
     - Aê Chico, traz dois. Não esqueça que um é sem colarinho.
>
>
     - Hey waiter, brings two. Don't forget that one is no foam.
 
Changed:
<
<
$ cat restaura
>
>
$ cat restore
  #!/bin/bash #
Changed:
<
<
# Restaura arquivos deletados via erreeme
>
>
# Restore deleted files with erreeme
 #

if [ $# -eq 0 ] then

Changed:
<
<
echo "Uso: $0 <Nome do Arquivo a Ser Restaurado>"
>
>
echo "Uso: $0 <File Name to Be Restored>"
  exit 1 fi
Changed:
<
<
# Pega nome do diretório original na última linha
>
>
# Picks up the original directory name in the last line
 Dir=`tail -1 /tmp/$LOGNAME/$1`
Changed:
<
<
# O grep -v exclui última linha e cria o # arquivo com diretorio e nome originais
>
>
# O grep -v deletes last line and creates the # file with directory and original names
 grep -v $Dir /tmp/$LOGNAME/$1 > $Dir/$1
Changed:
<
<
# Remove arquivo que jah estava moribundo
>
>
# Remove file that already was to be eliminated
 rm /tmp/$LOGNAME/$1
Changed:
<
<
     - Peraí, deixa ver se entendi. Primeiramente você coloca na variável Dir a última linha do arquivo cujo nome é formado por /tmp/nome do operador ($LOGNAME)/parâmetro passado com nome do arquivo a ser restaurado ($1). Em seguida o grep -v que você montou exclui a linha em que estava o nome do diretório, isto é, sempre a última e manda o restante do arquivo, que seria assim o arquivo já limpo, para o diretório original e depois remove o arquivo 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!
>
>
     - Wait, let me get this straight. First you put the Dir variable the last line of the file whose name is formed by /tmp/name operator ($LOGNAME)/parameter passed to the file name to be restored ($1). Then the grep -v you rode deletes the row that was the name of the directory, that is, always the last and sends the rest of the file, so the file would already clean, to the original directory and then removes the file from the "trash"; S E N S A T IO N A L! Flawless! Zero error! See? You're already picking up the tricks of the shell!
 
Changed:
<
<
     - Então vamulá chega de lesco-lesco e blá-blá-blá, de que você vai falar hoje?
>
>
     - So here we go, what you'll talk about today?
 
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.
>
>
     - It'm seeing that the pet Shell caught you. That's nice, but let's see how you can (and should) read data and format screens and first let us understand a command that gives you all the tools for you to format your data entry screen.
 
Changed:
<
<

O comando tput

>
>

The tput command

 
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 linhas 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.
>
>
The largest use of this command is to position the cursor on the screen, but it is also very used to delete data from the screen, to know the number of rows and columns in order to correctly position a field, deleting a field whose criticism detected as wrong. Anyway, almost all the formatting of the screen is taken by this command.
 
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.
>
>
A few attributes of the command tput can not possibly work if the terminal model defined by the variable $TERM does not have this corporate facility.
 
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ó:
>
>
The table below presents the key attributes of the command executed and the effects on the terminal, but you see there are many more than that, get this:
 
$ 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.
>
>
In this example I received the initial size of the <TAB> ( Initial T ab), but tell me: what is this? If you want to know everything about the tput command (and looks is something that never ends), see: http://www.cs.utah.edu/dept/old/texinfo/tput/tput.html#SEC4.
 
Changed:
<
<
Principais Opções do Comando tput
setf   Altera a cor da fonte (set foreground)
Opções do tput   Efeito
cup lin col   CUrsor Position - Posiciona o cursor na linha lin e coluna col. A origem é zero
home   O mesmo que tput cup 0 0, isto é, coloca o cursor no vertice superior esquerdo da tela
bold   Coloca a tela em modo de ênfase
rev   Coloca a tela em modo de vídeo reverso
smso   Idêntico ao anterior
smul   A partir desta instrução, os caracteres teclados aparecerão sublinhados na tela
blink   Os caracteres teclados aparecerão piscando (nem todas as definições de terminais aceitam esse)
invis   A partir desse ponto, nada do que for digitado aparecerá no vídeo (Obs: Inseguro para ler senhas)
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 linhas 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 linha 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 linhas a partir da posição do cursor
dl n   Delete Lines - Remove n linhas 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
rc   Restore Cursor position - Coloca o cursor na posição marcada pelo último sc
flash   Faz um vídeo reverso muito rápido. Ideal para chamar a atenção sobre erros ou ocorrência interessantes
smcup   Bate uma foto atual da tela e a salva para posterior recuperação
rmcup   Repõe na tela a foto batida com o comando tput smcup
setb   Altera a cor de fundo (set background)
>
>
Top tput command options
setf   Changes the font color (set foreground)
tput Options   Effect
cup lin col   CUrsor Position - Positions the cursor on the line lin e col column. The origin is zero
home   Same as tput cup 0 0, that is, places the cursor in the upper left vertex of the screen
bold   Place the screen in mode of emphasis
rev   Place the screen in reverse video mode
smso   Same as above
smul   From this instruction, the typed characters appear underlined on the screen
blink   Typed characters appear flashing (not all terminal definitions accept this)
invis   From this point on, anything you type will appear in the video (Note: Unsure to read senhas)
sgr0   After using one of the above, use this to restore the screen to its normal mode
reset   Clears the terminal and restore your settings according to terminfo, in other words, the terminal returns to the standard set by the variable =$TERM  
lines   Returns the number of lines the screen at the time of instruction
cols   Returns the number of columns of the screen at the time of instruction
el   Erase Line - Deletes the line from the cursor position
ed   Erase Display - Clears the screen from cursor position
il n   Insert Lines - Inserts n rows from the cursor position
dl n   Delete Lines - Remove n rows from the cursor position
ech n   Erase CHaracters - Delete n characters from the cursor position
sc   Save Cursor position - Save cursor position
rc   Restore Cursor position - Place the cursor in the position marked by the last sc
flash   Makes a very fast reverse video. Ideal for calling attention to errors or interesting occurrence
smcup   Capture a current picture of the screen and saves it for later retrieval
rmcup   Reinstates on the screen the picture captured with the command tput smcup
setb   Changes the background color (set background)
 
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 em vídeo reverso e após isso, o cursor voltará para a posição em que estava antes de escrever esta tão criativa frase. Veja:
>
>
Let's do a silly program to show some attributes of this command. It is the famous and celebrated Hello World, only this phrase is written on the screen center and reverse video and after that, the cursor returns to the position it was in before writing this sentence so creative. see:
 
$ cat alo.sh #!/bin/bash
Changed:
<
<
# Script bobo para testar # o comando tput (versao 1)
>
>
# Silly script to test # the tput command (version 1)
 
Changed:
<
<
Colunas=`tput cols` # Salvando quantidade colunas Linhas=`tput lines` # Salvando quantidade linhas Linha=$((Linhas / 2)) # Qual eh a linha do meio da tela? Coluna=$(((Colunas - 9) / 2)) # Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Linha $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
>
>
Columns=`tput cols` # Saving amount columns Rows=`tput lines` # Saving amount rows Row=$((Rows / 2)) # What is the middle line of the screen? Column=$(((Columns - 9) / 2)) # Centring screen message tput sc # Saving position of the cursor tput cup $Row $Column # Positioning to write tput rev # Reverse Video echo Hello World tput sgr0 # Restore video to normal tput rc # Restore the original cursor position
 
Changed:
<
<
Como o programa já está todo comentado, acho que a única explicação necessária seria para a linha em que é criada a variável Coluna e o estranho ali é aquele número 9, mas ele é o tamanho da cadeia que pretendo escrever (Alô Mundo).
>
>
As the program is already commented all, I think the only explanation would be needed for the row that is created the variable Column and there is the strange number 9, but he is the size of the string that I want to write (Hello World).
 
Changed:
<
<
Desta forma este programa somente conseguiria centrar cadeias de 9 caracteres, mas veja isso:
>
>
Thus this program could only focus chains of 9 characters, but see it:
 
Changed:
<
<
$ var=Papo
>
>
$ var=Talk
 $ echo ${#var} 4
Changed:
<
<
$ var="Papo de Botequim"
>
>
$ var="Pub Talk"
 $ echo ${#var} 16
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 em ví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, improved! So now we know that building = $ {# variable} = returns the number of characters = variable =. Therefore, we will optimize our program for him to write in reverse video in the center of the screen the string passed as a parameter and then the cursor to the position it was before running the script.
 
$ cat alo.sh #!/bin/bash
Changed:
<
<
# Script bobo para testar # o comando tput (versao 2)
>
>
# Silly script to test # the tput command (version 2)
 
Changed:
<
<
Colunas=`tput cols` # Salvando quantidade colunas Linhas=`tput lines` # Salvando quantidade linhas Linha=$((Linhas / 2)) # Qual eh a linha do meio da tela? Coluna=$(((Colunas - ${#1}) / 2)) #Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Linha $Coluna # Posicionando para escrever tput rev # Video reverso
>
>
Columns=`tput cols` # Saving amount columns Rows=`tput lines` # Saving amount rows Row=$((Rows / 2)) # What is the middle line of the screen? Column=$(((Columns - ${#1}) / 2)) #Centring screen message tput sc # Saving position of the cursor tput cup $Row $Column # Positioning to write tput rev # Reverse Video
 echo $1
Changed:
<
<
tput sgr0 # Restaura video ao normal tput rc # Restaura cursor aa posição original
>
>
tput sgr0 # Restore video to normal tput rc # Restore the original cursor position
 
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 em branco, 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 linha ficaria assim:
>
>
This script is the same as before, except that we change the fixed value of the previous version (9), for ${#1}, where it's 1 is $1 that is, this construction returns the size of the first parameter passed to the program. If the parameter that I want to pass contains blanks, would have put it all in quotes, if not the $1 would be only the first piece. To avoid this trouble, just replace $1 for $*, which as we know is the set of all parameters. So that line would look like this:
 
Changed:
<
<
Coluna=$(((Colunas - ${#*}) / 2)) # Centrando a mensagem na tela
>
>
Column=$(((Columns - ${#*}) / 2)) # Centring screen message
 
Changed:
<
<
e a linha echo $1 passaria a ser echo $*. Mas não esqueça de quando executar, de passar como parâmetro, a frase que você deseja centrar.
>
>
and the row echo $1 would be echo $*. But don't forget when running, passing as a parameter, the phrase you want to center.
 
Changed:
<
<
Um outro exemplo, todo comentado, que usa um monte de artifício do comando tput é o que veremos a seguir. Ele serve principalmente para mostrar como se salva uma tela para posterior recuperação. Enfim, uma aula de fotografia de telas ;), veja:
>
>
Another example, all commented that uses a lot of artifice of the command tput is what we'll see. It serves mainly to show how to save a screen for later retrieval. Finally, a photography class screens :), check out:
 
Changed:
<
<
$ cat salva_tela seq 2000 | xargs # Sujando a tela Lin=$(($(tput lines) / 2)) # Calculando linha e coluna centrais da tela
>
>
$ cat screen_saver seq 2000 | xargs # Dirtying the screen Lin=$(($(tput lines) / 2)) # Calculating row and central column of the screen
 Col=$(($(tput cols) / 2))
Changed:
<
<
tput cup $Lin; tput el; tput setf 1 # Posicionando, apagando a linha central e colorindo echo "Em 10 segundos essa tela será fotografada e se apagará" tput civis # Cursor invisível para melhorar apresentação
>
>
tput cup $Lin; tput el; tput setf 1 # Positioning, erasing the centerline and coloring echo "In 10 seconds this screen will be captured and erase" tput civis # Invisible Cursor to improve presentation
 for ((i=10; i!=0; i--)) {
Changed:
<
<
tput cup $Lin $Col; tput el # Posiciona no centro da tela e limpa núm anterior
>
>
tput cup $Lin $Col; tput el # Positions the center of the screen and clears the previous number
  echo $i sleep 1 }
Changed:
<
<
tput smcup # Tirando uma foto da tela clear # Poderia ter usado tput reset
>
>
tput smcup # Taking a picture of the screen clear # I could have used tput reset
 tput cup $Lin
Changed:
<
<
echo "Dentro de 10 segundos a tela inicial será recuperada"
>
>
echo "In 10 seconds the initial screen will be recovered"
 for ((i=10; i>0; i--)) {
Changed:
<
<
tput cup $Lin $Col; tput el # Posicionou no centro da tela
>
>
tput cup $Lin $Col; tput el # Positioned in the center of the screen
  echo $i sleep 1 }
Changed:
<
<
tput rmcup # Restaurou a foto tput cvvis;tput setf 9 # Restaurou o cursor e cor
>
>
tput rmcup # Restored photo tput cvvis;tput setf 9 # Restored the cursor and color
 
Changed:
<
<
Para que você possa ver todas as combinações de cores de fonte e fundo (tput setf e tput setb), execute o script a seguir:
>
>
So you can see all the color combinations of font and background (tput setf and tput setb), run the following script:
 
$ cat colors1.sh
Line: 195 to 195
 tput setb 9; tput setf 9
Changed:
<
<
Antes eu disse que essas eram todas as combinações, mas se o tput bold estiver ativo, você terá mais 7 cores de fonte.
>
>
I said before that these were all combinations, but if tput bold is active, you will have 7 more font colors.
 
Changed:
<
<
Se estavas sem saco e não quisestes executar esse script para ver as cores, seus códigos são os seguintes:
>
>
If you were out of time and wished not run this script to see the colors, their codes are as follows:
 
Changed:
<
<
Cores do terminal
4   Vermelho  
  Símbolo     Cor
0   Preto  
1   Azul  
2   Verde  
3   Ciano  
>
>
Terminal colors
4   Red  
  Symbol     Color
0   Black  
1   Blue  
2   Green  
3   Cyan  
 
5   Magenta  
Changed:
<
<
9   Volta a cor default  
6   Amarelo  
7   Branco  
>
>
9   Back to default color  
6   Yellow  
7   White  
 

E agora podemos ler os dados da tela

Revision 120 Feb 2014 - Main.AngelaFerreira

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="WebHome"

Papo de botequim parte VII



     - Cumequié rapaz! Derreteu os pensamentos para fazer o scriptizinho que eu te pedi?

     - É, eu realmente tive de colocar muita pensação na tela preta mas acho que consegui! Bem, pelo menos no testes que fiz a coisa funcionou, mas você tem sempre que botar chifres em cabeça de cachorro!

     - Não é bem assim, programar em shell é muito fácil, o que vale são as dicas e macetes que não são triviais. As correções que te faço, são justamente para mostrá-los. Mas vamos pedir dois chopes enquanto dou uma olhadela no teu script.

     - Aê Chico, traz dois. Não esqueça que um é sem colarinho.


$ cat restaura #!/bin/bash # # Restaura arquivos deletados via erreeme #

if [ $# -eq 0 ] then echo "Uso: $0 <Nome do Arquivo a Ser Restaurado>" exit 1 fi # Pega nome do diretório original na última linha Dir=`tail -1 /tmp/$LOGNAME/$1` # O grep -v exclui última linha e cria o # arquivo com diretorio e nome originais grep -v $Dir /tmp/$LOGNAME/$1 > $Dir/$1 # Remove arquivo que jah estava moribundo rm /tmp/$LOGNAME/$1

     - Peraí, deixa ver se entendi. Primeiramente você coloca na variável Dir a última linha do arquivo cujo nome é formado por /tmp/nome do operador ($LOGNAME)/parâmetro passado com nome do arquivo a ser restaurado ($1). Em seguida o grep -v que você montou exclui a linha em que estava o nome do diretório, isto é, sempre a última e manda o restante do arquivo, que seria assim o arquivo já limpo, para o diretório original e depois remove o arquivo 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 linhas 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
setf   Altera a cor da fonte (set foreground)
Opções do tput   Efeito
cup lin col   CUrsor Position - Posiciona o cursor na linha lin e coluna col. A origem é zero
home   O mesmo que tput cup 0 0, isto é, coloca o cursor no vertice superior esquerdo da tela
bold   Coloca a tela em modo de ênfase
rev   Coloca a tela em modo de vídeo reverso
smso   Idêntico ao anterior
smul   A partir desta instrução, os caracteres teclados aparecerão sublinhados na tela
blink   Os caracteres teclados aparecerão piscando (nem todas as definições de terminais aceitam esse)
invis   A partir desse ponto, nada do que for digitado aparecerá no vídeo (Obs: Inseguro para ler senhas)
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 linhas 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 linha 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 linhas a partir da posição do cursor
dl n   Delete Lines - Remove n linhas 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
rc   Restore Cursor position - Coloca o cursor na posição marcada pelo último sc
flash   Faz um vídeo reverso muito rápido. Ideal para chamar a atenção sobre erros ou ocorrência interessantes
smcup   Bate uma foto atual da tela e a salva para posterior recuperação
rmcup   Repõe na tela a foto batida com o comando tput smcup
setb   Altera a cor de fundo (set background)

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 em vídeo reverso e após isso, o cursor voltará para a posição em que 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 Linhas=`tput lines` # Salvando quantidade linhas Linha=$((Linhas / 2)) # Qual eh a linha do meio da tela? Coluna=$(((Colunas - 9) / 2)) # Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Linha $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 linha em que é 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 em ví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 Linhas=`tput lines` # Salvando quantidade linhas Linha=$((Linhas / 2)) # Qual eh a linha do meio da tela? Coluna=$(((Colunas - ${#1}) / 2)) #Centrando a mensagem na tela tput sc # Salvando posicao do cursor tput cup $Linha $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 em branco, 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 linha ficaria assim:

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

e a linha echo $1 passaria a ser echo $*. Mas não esqueça de quando executar, de passar como parâmetro, a frase que você deseja centrar.

Um outro exemplo, todo comentado, que usa um monte de artifício do comando tput é o que veremos a seguir. Ele serve principalmente para mostrar como se salva uma tela para posterior recuperação. Enfim, uma aula de fotografia de telas ;), veja:

$ cat salva_tela seq 2000 | xargs # Sujando a tela Lin=$(($(tput lines) / 2)) # Calculando linha e coluna centrais da tela Col=$(($(tput cols) / 2)) tput cup $Lin; tput el; tput setf 1 # Posicionando, apagando a linha central e colorindo echo "Em 10 segundos essa tela será fotografada e se apagará" tput civis # Cursor invisível para melhorar apresentação for ((i=10; i!=0; i--)) { tput cup $Lin $Col; tput el # Posiciona no centro da tela e limpa núm anterior echo $i sleep 1 } tput smcup # Tirando uma foto da tela clear # Poderia ter usado tput reset tput cup $Lin echo "Dentro de 10 segundos a tela inicial será recuperada" for ((i=10; i>0; i--)) { tput cup $Lin $Col; tput el # Posicionou no centro da tela echo $i sleep 1 } tput rmcup # Restaurou a foto tput cvvis;tput setf 9 # Restaurou o cursor e cor

Para que você possa ver todas as combinações de cores de fonte e fundo (tput setf e tput setb), execute o script a seguir:

$ cat colors1.sh #!/bin/bash for ((b=0; b<=7; b++)) { tput setb 9; tput setf 9; echo -n "|" for ((f=0; f<=7; f++)) { tput setb $b; tput setf $f; echo -n " b=$b f=$f " tput setb 9; tput setf 9; echo -n "|" } echo } tput setb 9; tput setf 9

Antes eu disse que essas eram todas as combinações, mas se o tput bold estiver ativo, você terá mais 7 cores de fonte.

Se estavas sem saco e não quisestes executar esse script para ver as cores, seus códigos são os seguintes:

Cores do terminal
9   Volta a cor default  
  Símbolo     Cor
0   Preto  
1   Azul  
2   Verde  
3   Ciano  
4   Vermelho  
5   Magenta  
6   Amarelo  
7   Branco  

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 em um boteco desses tomando chope. Mas vamos em frente.

Da última vez que nos encontramos aqui eu já dei uma palinha 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 em branco e coloca cada item desta lista em uma 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 em branco? 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 linha (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 linha 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 linha, 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 linha.

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

Vamos ler arquivos?

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 arquivo 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 arquivo de duas maneiras:

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

    while read Linha
    do
        echo $Linha
    done < arquivo

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

    cat arquivo |
    while read Linha 
    do
        echo $Linha
    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:

  • Em um 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 arquivo 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 arquivo por pipe.

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

Vamos ver sua execução:

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

Como você viu, o script lista todas as suas próprias linhas 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 linha echo "-$Ultimo-" lista corretamente as linhas.

     - Então porque isso aconteceu?

     - Por que como eu disse, o bloco de instruções redirecionado pelo pipe (|) é executado em um 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 arquivo 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 arquivo por pipe.

Ultimo="(vazio)" while read Linha do Ultimo="$Linha" 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 arquivo por pipe.- -- -Ultimo="(vazio)"- -while read Linha- -do- -Ultimo="$Linha"- -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 arquivo 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 arquivo (numeros), tem 30 registros somente com números seqüênciais. Veja:

$ seq 30 | xargs -i echo lin {} > numeros # Criando arquivo numeros $ paste -sd':' numeros # Este paste é para exibir o conteúdo sem ser um #+ por linha, usando dois-pontos como separador lin 1:lin 2:lin 3:lin 4:lin 5:lin 6:lin 7:lin 8:lin 9:lin 10:lin 11:lin 12:lin 13:lin 14:lin 15:l in 16:lin 17:lin 18:lin 19:lin 20:lin 21:lin 22:lin 23:lin 24:lin 25:lin 26:lin 27:lin 28:lin 29: lin 30 $ cat 10porpag.sh #!/bin/bash # Prg de teste para escrever # 10 linhas e parar para ler # Versão 1

while read Num do let ContLin++ # Contando... echo -n "$Num " # -n para nao saltar linha ((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 lin 1 lin 2 lin 3 lin 4 lin 5 lin 6 lin 7 lin 8 lin 9 lin 10 lin 12 lin 13 lin 14 lin 15 lin 16 l in 17 lin 18 lin 19 lin 20 lin 21 lin 23 lin 24 lin 25 lin 26 lin 27 lin 28 lin 29 lin 30 $

Repare que faltou a linha lin 11 e a listagem não parou no read. O que houve foi que toda a entrada do loop estava redirecionada do arquivo numeros e desta forma, a leitura foi feita em cima deste arquivo, desta forma perdendo a lin 11 (e também a lin 22 ou qualquer linha múltipla de 11).

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

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

while read Num do let ContLin++ # Contando... echo -n "$Num " # -n para nao saltar linha ((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 lin 1 lin 2 lin 3 lin 4 lin 5 lin 6 lin 7 lin 8 lin 9 lin 10 lin 11 lin 12 lin 13 lin 14 lin 15 lin 16 lin 17 lin 18 lin 19 lin 20 lin 21 lin 22 lin 23 lin 24 lin 25 lin 26 lin 27 lin 28 lin 29 lin 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 linhas 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-linhas-da-tela (tput lines) menos (-) 3, isto é, se a tela tem 25 linha, 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.

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 em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.

Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim.

Valeu!

-- JarbasJunior - 20 Oct 2005

 
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