Difference: TWikiBarTalk006 (1 vs. 20)

Revision 2025 Dec 2017 - Main.PauloSantana

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

Pub Talk Part VI

Line: 448 to 448
 Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to me.

Thanks! \ No newline at end of file

Added:
>
>
next

-- PauloSantana - 25 Dec 2017

 \ No newline at end of file

Revision 1908 Apr 2015 - JulioNeves

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

Pub Talk Part VI

Line: 242 to 242
  [ "$Art" ] && oArt="$Art" # If empty Art previous Reg="$Reg$oArt~$Mus:" # Mounting registry Cont=$((Cont + 1))
Changed:
<
<
# The above line could also be ((Cont++))
>
>
# The above line could also be ((Cont++)) or (better) let Cont++
 done echo "$Reg" >> musics sort musics -o musics

Revision 1818 Mar 2014 - JulioNeves

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

Pub Talk Part VI

Added:
>
>

 
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.

 

Loop commands (Continuing)

Revision 1705 Mar 2014 - JulioNeves

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

Pub Talk Part VI

Line: 45 to 45
 This file was created by DOS/Windows and
Changed:
<
<
download by a badly
>
>
downloaded by a badly
 implemented ftp.
Line: 97 to 97
 
||   bitwise OR
Changed:
<
<
     - Wait. You think that our talk about loop is over with the for command? Silly mistake, buddy. We still have two others to check out.
>
>
     - Wait. You think that our talk about loop is over with the for command? Silly mistake, buddy. We still have two others to check out.
 

The while command

Every programmer knows this command, since it's found on every language and usually a bunch of commands are executed while a certain condition is true. Therefore the name.

Changed:
<
<
Meeh... That only happens on those boring languages. On Shell programming a bunch of commands are executed while a command is true. And, of course, if you want to check if a condition is true you can do it by using while with test, exactly how you learnt back during our if talk. Remember?
>
>
Meeh... That only happens on those boring languages. On Shell programming a bunch of commands are executed while a command is true. And, of course, if you want to check if a condition is true you can do it by using while with test, exactly how you learnt back during our if talk. Remember?
  So, the syntax will look like this:
Line: 120 to 120
  Think about the following scenario: I have this hot babe waiting for me, but I can't leave work since my prick boss (kinda redundant, I know) is still working and his office is on my way out.
Changed:
<
<
I think he got suspicious after the fifth time I walked to the restroom to check if he was still there... So I had to go back to my desk, connect to the server and create the following script:
>
>
I think he got suspicious after the fifth time I walked to the restroom to check if he was still there... So I had to go back to my desk, connect to the server and create the following script:
 
$ cat logout.sh
Line: 133 to 133
 echo The prick is gonne. Don't hesitate, exit.
Changed:
<
<
This tiny script uses the while command tests the pipeline returned by the who and grep commands, which will be true while grep is able to locate the word boss on who 's return. So the script will sleep for 30 seconds while the boss is still there (Argh!). As soon as he disconnects from the server, the script flow will leave the loop and yield the so much wanted freedom message.
>
>
This tiny script uses the while command to test the pipeline returned by the who and grep commands, which will be true while grep is able to locate the word boss on who 's return. So the script will sleep for 30 seconds while the boss is still there (Argh!). As soon as he disconnects from the server, the script flow will leave the loop and yield the so much wanted freedom message.
  So, when I ran it, guess what happened?
Line: 145 to 145
 boss pts/0 Jan 4 08:52 (10.2.4.144)
Changed:
<
<
That means every 30 seconds it would send on my screen the grep command result, which was not nice, since it would pollute my screen and the expected freedom message could go unnoticed. Fortunately we know how to avoid it by redirecting the pipeline message to /dev/null (another way to do the same, is using the -q (quiet) grep option. But this works only in GNU grep, not in UNIX).
>
>
That means every 30 seconds it would send on my screen the grep command result, which was not nice, since it would pollute my screen and the expected freedom message could go unnoticed. Fortunately we know how to avoid it by redirecting the pipeline message to /dev/null (another way to do the same, is using the -q (quiet) grep option. But this works only in GNU grep, not in UNIX).
 
$ cat logout.sh
Line: 158 to 158
 echo The prick is gonne. Don't hesitate, exit.
Changed:
<
<
Now I want to put together a script that can take the name (and any other needed parameter) of a program which will run in background and let me know when it's finished. But before that, so you undestand the examples, I have to show you a new system variable. Take a look at this commands from the prompt:
>
>
Now I want to put together a script that can take the name (and any other needed parameter) of a program which will run in background and let me know when it's finished. But before that, so you undestand the examples, I have to show you a new system variable. Take a look at this commands from the prompt:
 
$ sleep 10&
Line: 170 to 170
 16317
Changed:
<
<
It means I created a background process which would sleep 10 seconds so I could show you that the variable $! saves the PID (process IDentification) of the last background running process. But notice that after the line done that the variable kept it's value even after the process is finished.
>
>
It means I created a background process which would sleep 10 seconds so I could show you that the variable $! saves the PID (Process IDentification) of the last background running process. But notice that after the line done that the variable kept it's value even after the process is finished.
 
Changed:
<
<
Well, with that in mind it's easier to monitor any background process. Take a look how:
>
>
Well, with that in mind it's easier to monitor any background process. Take a look how:
 
$ cat monbg.sh
Line: 186 to 186
 do sleep 5 done
Changed:
<
<
echo Process is finished $1
>
>
echo Process $1 is finished
 
Changed:
<
<
This script is very similar to the previous ones, with a couple extra tricks: It must be run in background so it won't hold the prompt, but the $! will contain the PID of the program parsed as a parameter, since it was put in background after the monbg.sh itselfs. You may also notice that we are running grep with the option -q (quiet). You could obtain the same result running while ps|grep $! >/dev/null, as we've been using until now.
>
>
This script is very similar to the previous ones, with a couple extra tricks: It must be run in background so it won't hold the prompt, but the $! will contain the PID of the program parsed as a parameter, since it was put in background after the monbg.sh itselfs. You may also notice that we are running grep with the option -q (quiet). You could obtain the same result running while ps|grep $! >/dev/null, as we've been using until now.
 
Pinguim com placa de dica (em inglês)
Added:
>
>
 
 
Changed:
<
<

Don't forget: Bash provides you the system variable $! which contains the PID (Process IDentification) of the last background running process.

>
>
Don't forget: Bash provides you the system variable $! which contains the PID (Process IDentification) of the last background running process.
 
Changed:
<
<

Let's improve the musinc, which is our program to include records in the file music, but first I need to teach you to catch a data of the screen, and I'm warning: I'll just give a little hint of the read command (which is who gets the data of the screen) it's enough to solve this our problem. In another round of beer I'll teach you all about it, including how to format screen, but today we are talking about loops.

>
>
Let's improve the musinc, which is our program to include records in the file music, but first I need to teach you to catch a data of the screen, and I'm warning: I'll just give a little hint of the read command (which is who gets the data of the screen) it's enough to solve this our problem. In another round of beer I'll teach you all about it, including how to format screen, but today we are talking about loops.
  The command syntax to read what interests us today is:
Line: 211 to 208
 Where prompt of read is the text you want to appear written on the screen, and when the operator keying the data, it will go to the variable var. For example:

Changed:
<
<
$ read -p "Álbum Title: " Tit
>
>
$ read -p "Album Title: " Tit
 
Changed:
<
<
Well, once you understand this, let the specification of our problem: we do a program that initially read the album name and then will make a loop reading, catching the music and the artist. This loop terminates when an empty music is informed, this is, when asked to typing of music, the operator gives a simple <ENTER>. To make life easier for the operator, we offer as default the same artist name of previous music (since it is normal that the album is all the same artist) until he wishes to change it. Let's see how it fits:
>
>
Well, once you understand this, let the specification of our problem: we do a program that initially read the album name and then will make a loop reading, catching the music and the artist. This loop terminates when an empty music is informed, this is, when asked to typing of music, the operator gives a simple <ENTER>. To make life easier for the operator, we offer as default the same artist name of previous music (since it is normal that the album is all the same artist) until he wishes to change it. Let's see how it fits:
 
$ cat musinc
Line: 247 to 244
 sort musics -o musics
Changed:
<
<
This example starts with reading the album title, that is not informed, terminate program execution. Then one grep demand in the beginning (^) of each record musics, the title entered followed by the separator (^) (which is preceded by a backslash (\) to protect it from interpretation of Shell).
>
>
This example starts with reading the album title, that is not informed, terminate program execution. Then one grep demand in the beginning (^) of each record musics, the title entered followed by the separator (^) (which is preceded by a backslash (\) to protect it from interpretation of Shell).
 
Changed:
<
<
To read the names of the artists and the musics of the album, it set up a loop of while simple, whose only highlight is the fact of storing the artist of the previous song in the variable
>
>
To read the names of the artists and the musics of the album, it set up a loop of while simple, whose only highlight is the fact of storing the artist of the previous song in the variable
 $oArt which will only its content changed, when some data is entered for the variable $Art, this is, when not typed up a simple <ENTER> to maintain the previous artist.

What has been seen so far on the while was very little. This command is very used mainly for reading files, but we lack luggage to proceed. After learning to read, we'll see this statement further.

Pinguim com placa de dica (em inglês)
Changed:
<
<
File reading means reading one-on-one all records, which is always a slow operation. Be careful not to use the while when its use is unnecessary. The Shell have tools like sed and family grep which scour files optimally that crawl files optimally without requiring the use of commands loop to do it record by record (or even word by word).
>
>
 

File reading means reading one-on-one all records, which is always a slow operation. Be careful not to use the while when its use is unnecessary. The Shell have tools like sed and family grep which scour files optimally that crawl files optimally without requiring the use of commands loop to do it record by record (or even word by word).

 

The until command

Changed:
<
<
The until command works exactly the same as while, however unlike. He said all but said nothing, right? It is this: both test commands, both have the same syntax and both act in loop, but while while executes the block of instructions loop while a command is successful, the until executes the block of loop until the command to be successful. Seems little but the difference is fundamental.
>
>
The until command works exactly the same as while, however unlike. He said all but said nothing, right? It is this: both test commands, both have the same syntax and both act in loop, but while while executes the block of instructions loop while a command is successful, the until executes the block of loop until the command to be successful. Seems little but the difference is fundamental.
  The command syntax is almost identical to the while. See:
Line: 276 to 275
  And so the command block formed by instructions cmd1, cmd2,... and cmdn runs until the instruction execution command be successful.
Changed:
<
<
As I told you, while and until function antagonistically and this is very easy to demonstrate: in a war where you invent a gun, the enemy seeks a solution to neutralize it. Based on this principle bellicose my boss developed on the same server I ran the logaute.sh an script to control my arrival time.
>
>
As I told you, while and until function antagonistically and this is very easy to demonstrate: in a war where you invent a gun, the enemy seeks a solution to neutralize it. Based on this principle bellicose my boss developed on the same server I ran the logaute.sh an script to control my arrival time.
  One day the network has a problem, he asked me to take a look at his micro and left me alone in his room. I immediately began snooping around your files - because war is war - and look what I found:
Line: 291 to 290
 echo $(date "+ Em %d/%m às %H:%Mh") >> relapse.log
Changed:
<
<
Look at that bastard! The guy was riding a log with the times I came, and on top called the file that monitored me relapse.log! What does he mean by that?
>
>
Look at that bastard! The guy was riding a log with the times I came, and on top called the file that monitored me relapse.log! What does he mean by that?
 
Changed:
<
<
In this script the pipeline who | grep julio, will be successful only when julio is found in the command who, this is when I "log" on the server. Until that happens, the command sleep that forms the block of instructions until put the program on hold for 30 seconds. When this loop close, will be given a message to relapse.log (ARGHH!). Assuming that on 20/01 I logged in at 11:23 hours, the message would be as follows:
>
>
In this script the pipeline who | grep julio, will be successful only when julio is found in the command who, this is when I "log" on the server. Until that happens, the command sleep that forms the block of instructions until put the program on hold for 30 seconds. When this loop close, will be given a message to relapse.log (ARGHH!). Assuming that on 20/01 I logged in at 11:23 hours, the message would be as follows:
       On Jan 20 at 11:23 h
Line: 338 to 337
 done
Changed:
<
<
In this version, a larger loop was added before reading the title, which will end only when the variable $For stop being empty. If the album title is not given, the variable $For will receive value (in case I put 1 but could have put anything. Importantly, it is not empty) to exit this loop ending this way the program. In the rest, the script is identical to its earlier version.
>
>
In this version, a larger loop was added before reading the title, which will end only when the variable $For stop being empty. If the album title is not given, the variable $For will receive value (in case I put 1 but could have put anything. Importantly, it is not empty) to exit this loop ending this way the program. In the rest, the script is identical to its earlier version.
 

Shortcuts in the loop

Changed:
<
<
Not always a program cycle, between a do and done, comes out the front door. On some occasions, we have put a command to abort a controlled manner this loop. Inversely, sometimes we want the flow of program execution back before getting to done. For this, we respectively commands break (we've seen rapidly the examples of comado while) and continue, which work as follows:
>
>
Not always a program cycle, between a do and done, comes out the front door. On some occasions, we have put a command to abort a controlled manner this loop. Inversely, sometimes we want the flow of program execution back before getting to done. For this, we respectively commands break (we've seen rapidly the examples of comado while) and continue, which work as follows:
  What I had not previously mentioned is that in its generic syntax they appear as follows:
Line: 352 to 351
       continue [qtd loop]
Changed:
<
<
Where qtd loop represents the amount of the internal loops on which the commands will act. Your default value is 1.
>
>
Where qtd loop represents the amount of the internal loops on which the commands will act. Your default value is 1.
 
Fluxograma
Changed:
<
<
I doubt you've ever deleted a file and soon after took a slap on the forehead cursing because it should not have removed it. Well, the tenth time I did this bullshit, I created a script to simulate a recycling bin, this is when I send remove one (or more) files, the program "pretends" that removed it, but actually it did was send it to /tmp/LoginName directory. I called this program erreeme and in /etc/profile I put the following line:
>
>
I doubt you've ever deleted a file and soon after took a slap on the forehead cursing because it should not have removed it. Well, the tenth time I did this bullshit, I created a script to simulate a recycling bin, this is when I send remove one (or more) files, the program "pretends" that removed it, but actually it did was send it to /tmp/LoginName directory. I called this program erreeme and in /etc/profile I put the following line:
       alias rm=erreeme
Line: 424 to 423
 exit $Error # Step eventual error number for the return code
Changed:
<
<
As you can see, most of the script is formed by small criticisms to parameters informed, but as script may have received multiple files to remove, every file that does not fit within the specified, there is a continue to the sequence back to the loop of for in order to receive other files.
>
>
As you can see, most of the script is formed by small criticisms to parameters informed, but as script may have received multiple files to remove, every file that does not fit within the specified, there is a continue to the sequence back to the loop of for in order to receive other files.
 
Changed:
<
<
When you are in Windows (excuse the bad word) and try to remove that pile of garbage with weird names like HD04TG.TMP if error happen in one of them, others are not removed, does not it? So continue was used to prevent such an oath to occur, this is, even if it gives error in the removal of a file, the program will continue removing others that were passed.
>
>
When you are in Windows (excuse the bad word) and try to remove that pile of garbage with weird names like HD04TG.TMP if error happen in one of them, others are not removed, does not it? So continue was used to prevent such an oath to occur, this is, even if it gives error in the removal of a file, the program will continue removing others that were passed.
       - I think by now you must be curious to see the program that restores the file removed, isn't it? For then there will go a challenge: make it at home and bring me to discuss at our next meeting here at the pub .
Line: 442 to 441
       - Waiter, bring another beer while he thinks!
Changed:
<
<
I will take also to promote my work: tell friends that anyone in order to do a good programming course in Shell to send an email to our management training to inform yourself.

Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to me.

>
>
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to me.
  Thanks!

Revision 1605 Mar 2014 - JulioNeves

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

Pub Talk Part VI

Line: 20 to 20
 # Example script # It's going to count the number of words # inside a file. We assume the words
Changed:
<
<
# are separated by spaces, or #
>
>
# are separated by spaces, <TAB> ou <ENTER>. #
 if [ $# -ne 1 ] then echo usage: $0 /file/path
Line: 44 to 44
 $ cat ArqDoDOS.txt This file was created by
Changed:
<
<
Dos/Windows and
>
>
DOS/Windows and
 download by a badly implemented ftp.

Revision 1528 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 436 to 436
       - Yeah I'll try, but don't know ...
Changed:
<
<
     - Have faith brother, I'm telling you it's easy! Any questions just give me an e-mail julio.neves@gmail.com. Now comes the chat I'm already dry throats so much talk. Join me in the next chope or will now rush out to do the script that I spent?
>
>
     - Have faith brother, I'm telling you it's easy! Any questions just give me an e-mail julio.neves@gmail.com. Now comes the chat I'm already dry throats so much talk. Join me in the next beer or will now rush out to do the script that I spent?
       - Let me think a little ...
Line: 444 to 444
  I will take also to promote my work: tell friends that anyone in order to do a good programming course in Shell to send an email to our management training to inform yourself.
Changed:
<
<
Any doubt or lack of companionship for a chope or even to speak ill of politicians just send an email to me.
>
>
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to me.
  Thanks!

Revision 1420 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 436 to 436
       - Yeah I'll try, but don't know ...
Changed:
<
<
     - Tenha fé irmão, eu tô te falando que é mole! Qualquer dúvida é só me passar um e-mail para julio.neves@gmail.com. Agora chega de papo que eu já estou de goela seca de tanto falar. Me acompanha no próximo chope ou já vai sair correndo para fazer o script que passei?
>
>
     - Have faith brother, I'm telling you it's easy! Any questions just give me an e-mail julio.neves@gmail.com. Now comes the chat I'm already dry throats so much talk. Join me in the next chope or will now rush out to do the script that I spent?
       - Let me think a little ...

     - Waiter, bring another beer while he thinks!

Changed:
<
<
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.
>
>
I will take also to promote my work: tell friends that anyone in order to do a good programming course in Shell to send an email to our management training to inform yourself.
 
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 chope or even to speak ill of politicians just send an email to me.
 
Changed:
<
<
Valeu!
>
>
Thanks!

Revision 1319 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 424 to 424
 exit $Error # Step eventual error number for the return code
Changed:
<
<
Como você pode ver, a maior parte do script é formada por pequenas criticas aos parâmetros informados, mas como o script pode ter recebido diversos arquivos para remover, a cada arquivo que não se encaixa dentro do especificado, há um continue, para que a sequência volte para o loop do for de forma a receber outros arquivos.
>
>
As you can see, most of the script is formed by small criticisms to parameters informed, but as script may have received multiple files to remove, every file that does not fit within the specified, there is a continue to the sequence back to the loop of for in order to receive other files.
 
Changed:
<
<
Quando você está no Windows (com perdão da má palavra) e tenta remover aquele monte de lixo com nomes esquisitos como HD04TG.TMP, se der erro em um deles, os outros não são removidos, não é? Então, o continue foi usado para evitar que um impropério desses ocorra, isto é, mesmo que dê erro na remoção de um arquivo, o programa continuará removendo os outros que foram passados.
>
>
When you are in Windows (excuse the bad word) and try to remove that pile of garbage with weird names like HD04TG.TMP if error happen in one of them, others are not removed, does not it? So continue was used to prevent such an oath to occur, this is, even if it gives error in the removal of a file, the program will continue removing others that were passed.
 
Changed:
<
<
     - Eu acho que a esta altura você deve estar curioso para ver o programa que restaura o arquivo removido, não é? Pois então aí vai vai um desafio: faça-o em casa e me traga para discutirmos no nosso próximo encontro aqui no boteco.
>
>
     - I think by now you must be curious to see the program that restores the file removed, isn't it? For then there will go a challenge: make it at home and bring me to discuss at our next meeting here at the pub .
 
Changed:
<
<
     - Poxa, mas nesse eu acho que vou dançar, pois não sei nem como começar...
>
>
     - Damn, but this I think I'll dance, do not even know how to start ...
 
Changed:
<
<
     - Cara, este programa é como tudo que se faz em Shell, extremamente fácil, é para ser feito em, no máximo 10 linhas. Não se esqueça que o arquivo está salvo em /tmp/$LOGNAME e que a sua última linha é o diretório em que ele residia antes de ser "removido". Também não se esqueça de criticar se foi passado o nome do arquivo a ser removido.
>
>
     - Dude, this program is like everything we do at Shell, extremely easy, is to be done in at most 10 lines. Don't forget that the file is saved in /tmp/$LOGNAME and its last line is the directory in which it resided before being "removed". Also be sure to criticize it was the last name of the file to be removed.
 
Changed:
<
<
     - É eu vou tentar, mas sei não...
>
>
     - Yeah I'll try, but don't know ...
       - Tenha fé irmão, eu tô te falando que é mole! Qualquer dúvida é só me passar um e-mail para julio.neves@gmail.com. Agora chega de papo que eu já estou de goela seca de tanto falar. Me acompanha no próximo chope ou já vai sair correndo para fazer o script que passei?
Changed:
<
<
     - Deixa eu pensar um pouco...
>
>
     - Let me think a little ...
 
Changed:
<
<
     - Chico, traz mais um chope enquanto ele pensa!
>
>
     - Waiter, bring another beer while he thinks!
  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 1218 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 368 to 368
 $ cat erreeme #/bin/bash #
Changed:
<
<
# Salvando Copia de Arquivo Antes de Remove-lo
>
>
# Saving file copy before removing it
 #

Changed:
<
<
if [ $# -eq 0 ] # Tem de ter um ou mais arquivos para remover
>
>
if [ $# -eq 0 ] # You must have one or more files to remove
 then
Changed:
<
<
echo "Erro -> Uso: erreeme arq [arq] ... [arq]" echo " O uso de metacaracteres e’ permitido. Ex. erreeme arq*"
>
>
echo "Error -> Use: erreeme arq [arq] ... [arq]" echo " The use of metacharacters is allowed. Ex. erreeme arq*"
  exit 1 fi

Changed:
<
<
MeuDir="/tmp/$LOGNAME" # Variavel do sist. Contém o nome do usuário. if [ ! -d $MeuDir ] # Se não existir o meu diretório sob o /tmp...
>
>
MyDir="/tmp/$LOGNAME" # Variable system. Contains the user name. if [ ! -d $MyDir ] # If my directory does not exist under the /tmp...
 then
Changed:
<
<
mkdir $MeuDir # Vou cria-lo
>
>
mkdir $MyDir # I will create it
 fi

Changed:
<
<
if [ ! -w $MeuDir ] # Se não posso gravar no diretório...
>
>
if [ ! -w $MyDir ] # If I can not write to the directory...
 then
Changed:
<
<
echo Impossivel salvar arquivos em $MeuDir. Mude permissao...
>
>
echo Impossible to save files in $MyDir. Change permission...
  exit 2 fi

Changed:
<
<
Erro=0 # Variavel para indicar o cod. de retorno do prg for Arq # For sem o "in" recebe os parametros passados
>
>
Error=0 # Variable to indicate the return code of the program for Arq # For without the "in" receives past parameters
 do
Changed:
<
<
if [ ! -f $Arq ] # Se este arquivo não existir...
>
>
if [ ! -f $Arq ] # If this file does not exist...
  then
Changed:
<
<
echo $Arq nao existe. Erro=3 continue # Volta para o comando for
>
>
echo $Arq doesn't exist. Error=3 continue # Back to the for command
  fi

Changed:
<
<
DirOrig=`dirname $Arq` # Cmd. dirname informa nome do dir de $Arq if [ ! -w $DirOrig ] # Verifica permissão de gravacaoo no diretório
>
>
DirOrig=`dirname $Arq` # Cmd. dirname informs the directory name of $Arq if [ ! -w $DirOrig ] # Checks write permission in the directory
  then
Changed:
<
<
echo Sem permissao de remover no diretorio de $Arq Erro=4 continue # Volta para o comando for
>
>
echo No permission to remove the directory of $Arq Error=4 continue # Back to the for command
  fi

Changed:
<
<
if [ "$DirOrig" = "$MeuDir" ] # Se estou "esvaziando a lixeira"...
>
>
if [ "$DirOrig" = "$MyDir" ] # If I am "emptying the recycle bin"...
  then
Changed:
<
<
echo $Arq ficara sem copia de seguranca rm -i $Arq # Pergunta antes de remover [ -f $Arq ] || echo $Arq removido # Será que o usuario removeu?
>
>
echo $Arq will be without backup rm -i $Arq # Question before removing [ -f $Arq ] || echo $Arq removed # Does the user removed?
  continue fi

Changed:
<
<
cd $DirOrig # Guardo no fim do arquivo o seu diretorio pwd >> $Arq # original para usa-lo em um script de undelete mv $Arq $MeuDir # Salvo e removo echo $Arq removido
>
>
cd $DirOrig # I save at end of file your directory pwd >> $Arq # original to use it in a script undelete mv $Arq $MyDir # saved and remove echo $Arq removed
 done
Changed:
<
<
exit $Erro # Passo eventual numero do erro para o codigo de retorno
>
>
exit $Error # Step eventual error number for the return code
 

Como você pode ver, a maior parte do script é formada por pequenas criticas aos parâmetros informados, mas como o script pode ter recebido diversos arquivos para remover, a cada arquivo que não se encaixa dentro do especificado, há um continue, para que a sequência volte para o loop do for de forma a receber outros arquivos.

Revision 1118 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 236 to 236
 do echo Track data $Cont: read -p "Music: " Mus
Changed:
<
<
[ "$Mus" ] || break # Leave empty
>
>
[ "$Mus" ] || break # Exit if empty
  read -p "Artist: $oArt // " Art [ "$Art" ] && oArt="$Art" # If empty Art previous
Changed:
<
<
Reg="$Reg$oArt~$Mus:" # mounting registry
>
>
Reg="$Reg$oArt~$Mus:" # Mounting registry
  Cont=$((Cont + 1)) # The above line could also be ((Cont++)) done
Line: 278 to 278
  As I told you, while and until function antagonistically and this is very easy to demonstrate: in a war where you invent a gun, the enemy seeks a solution to neutralize it. Based on this principle bellicose my boss developed on the same server I ran the logaute.sh an script to control my arrival time.
Changed:
<
<
Um dia deu um problema da rede, ele me pediu para dar uma olhada no micro dele e me deixou sozinho em sua sala. Imediatamente comecei a bisbilhotar seus arquivos - porque guerra é guerra - e veja só o que descobri:
>
>
One day the network has a problem, he asked me to take a look at his micro and left me alone in his room. I immediately began snooping around your files - because war is war - and look what I found:
 
Changed:
<
<
$cat chegada.sh
>
>
$cat arrival.sh
 #!/bin/bash

until who | grep julio do sleep 30 done

Changed:
<
<
echo $(date "+ Em %d/%m às %H:%Mh") >> relapso.log
>
>
echo $(date "+ Em %d/%m às %H:%Mh") >> relapse.log
 
Changed:
<
<
Olha que safado! O cara estava montando um log com os horários que eu chegava, e ainda por cima chamou o arquivo que me monitorava de relapso.log! O que será que ele quis dizer com isso?
>
>
Look at that bastard! The guy was riding a log with the times I came, and on top called the file that monitored me relapse.log! What does he mean by that?
 
Changed:
<
<
Neste script, o pipeline who | grep julio, será bem sucedido somente quando julio for encontrado no comando who, isto é, quando eu me "logar" no servidor. Até que isso aconteça, o comando sleep, que forma o bloco de instruções do until, porá o programa em espera por 30 segundos. Quando este loop encerrar-se, será dada uma mensagem para o relapso.log (ARGHH!). Supondo que no dia 20/01 eu me loguei às 11:23 horas, a mensagem seria a seguinte:
>
>
In this script the pipeline who | grep julio, will be successful only when julio is found in the command who, this is when I "log" on the server. Until that happens, the command sleep that forms the block of instructions until put the program on hold for 30 seconds. When this loop close, will be given a message to relapse.log (ARGHH!). Assuming that on 20/01 I logged in at 11:23 hours, the message would be as follows:
 
Changed:
<
<
     Em 20/01 às 11:23h
>
>
     On Jan 20 at 11:23 h
 
Changed:
<
<
Quando vamos cadastrar músicas, o ideal seria que pudéssemos cadastrar diversos CDs, e na última versão que fizemos do musinc, isso não ocorre, a cada CD que cadastramos o programa termina. Vejamos como melhorá-lo:
>
>
When we registering musics, the ideal would be that we could register several CDs. In the last version we did of "= musinc =" this does not happen, every CD that register the program ends. Let's see how to improve it:
 
$ cat musinc #!/bin/bash
Changed:
<
<
# Cadastra CDs (versao 5)
>
>
# Register CDs (version 5)
 #
Changed:
<
<
Para= until [ "$Para" ]
>
>
For= until [ "$For" ]
 do clear
Changed:
<
<
read -p "Título do Álbum: " Tit if [ ! "$Tit" ] # Se titulo vazio...
>
>
read -p "Album Title: " Tit if [ ! "$Tit" ] # If empty title...
  then
Changed:
<
<
Para=1 # Liguei flag de saída
>
>
For=1 # I turned on flag output
  else
Changed:
<
<
if grep "^$Tit\^" musicas > /dev/null
>
>
if grep "^$Tit\^" musics > /dev/null
  then
Changed:
<
<
echo Este álbum já está cadastrado
>
>
echo This album is already registered
  exit 1 fi Reg="$Tit^"
Line: 323 to 323
  oArt= while [ "$Tit" ] do
Changed:
<
<
echo Dados da trilha $Cont: read -p "Música: " Mus [ "$Mus" ] || break # Sai se vazio read -p "Artista: $oArt // " Art [ "$Art" ] && oArt="$Art" # Se vazio Art anterior Reg="$Reg$oArt~$Mus:" # Montando registro
>
>
echo Track data $Cont: read -p "Music: " Mus [ "$Mus" ] || break # Exit if empty read -p "Artist: $oArt // " Art [ "$Art" ] && oArt="$Art" # If empty Art previous Reg="$Reg$oArt~$Mus:" # Mounting registry
  Cont=$((Cont + 1))
Changed:
<
<
# A linha anterior tb poderia ser ((Cont++))
>
>
# The above line could also be ((Cont++))
  done
Changed:
<
<
echo "$Reg" >> musicas sort musicas -o musicas
>
>
echo "$Reg" >> musics sort musics -o musics
  fi done
Changed:
<
<
Nesta versão, um loop maior foi adicionado antes da leitura do título, que só terminará quando a variável $Para deixar de ser vazia. Caso o título do álbum não seja informado, a variável $Para receberá valor (no caso coloquei 1 mas poderia ter colocado qualquer coisa. O importante é que não seja vazia) para sair deste loop, terminando desta forma o programa. No resto, o script é idêntico à sua versão anterior.
>
>
In this version, a larger loop was added before reading the title, which will end only when the variable $For stop being empty. If the album title is not given, the variable $For will receive value (in case I put 1 but could have put anything. Importantly, it is not empty) to exit this loop ending this way the program. In the rest, the script is identical to its earlier version.
 
Changed:
<
<

Atalhos no loop

>
>

Shortcuts in the loop

 
Changed:
<
<
Nem sempre um ciclo de programa, compreendido entre um do e um done, sai pela porta da frente. Em algumas oportunidades, temos que colocar um comando que aborte de forma controlada este loop. De maneira inversa, algumas vezes desejamos que o fluxo de execução do programa volte antes de chegar ao done. Para isto, temos respectivamente, os comandos break (que já vimos rapidamente nos exemplos do comado while) e continue, que funcionam da seguinte forma:
>
>
Not always a program cycle, between a do and done, comes out the front door. On some occasions, we have put a command to abort a controlled manner this loop. Inversely, sometimes we want the flow of program execution back before getting to done. For this, we respectively commands break (we've seen rapidly the examples of comado while) and continue, which work as follows:
 
Changed:
<
<
O que eu não havia dito anteriormente é que nas suas sintaxes genéricas eles aparecem da seguinte forma:
>
>
What I had not previously mentioned is that in its generic syntax they appear as follows:
       break [qtd loop]
Changed:
<
<
e
>
>
and
       continue [qtd loop]
Changed:
<
<
Onde qtd loop representa a quantidade dos loops mais internos sobre os quais os comandos irão atuar. Seu valor default é 1.
>
>
Where qtd loop represents the amount of the internal loops on which the commands will act. Your default value is 1.
 
Fluxograma
Changed:
<
<
Duvido que você nunca tenha deletado um arquivo e logo após deu um tabefe na testa se xingando porque não devia tê-lo removido. Pois é, na décima vez que fiz esta besteira, criei um script para simular uma lixeira, isto é, quando mando remover um (ou vários) arquivo(s), o programa "finge" que removeu-o, mas no duro o que fez foi mandá-lo(s) para o diretório /tmp/LoginName_do_usuario. Chamei este programa de erreeme e no /etc/profile coloquei a seguinte linha:
>
>
I doubt you've ever deleted a file and soon after took a slap on the forehead cursing because it should not have removed it. Well, the tenth time I did this bullshit, I created a script to simulate a recycling bin, this is when I send remove one (or more) files, the program "pretends" that removed it, but actually it did was send it to /tmp/LoginName directory. I called this program erreeme and in /etc/profile I put the following line:
       alias rm=erreeme
Changed:
<
<
O programa era assim:
>
>
The program was well:
 
$ cat erreeme

Revision 1018 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 274 to 274
  done
Changed:
<
<
E desta forma o bloco de comandos formado pelas instruções cmd1, cmd2,... e cmdn é executado até que a execução da instrução comando seja bem sucedida.
>
>
And so the command block formed by instructions cmd1, cmd2,... and cmdn runs until the instruction execution command be successful.
 
Changed:
<
<
Como eu te disse, o while e until funcionam de forma antagônica e isso é muito fácil de demonstrar: em uma guerra sempre que se inventa uma arma, o inimigo busca uma solução para neutralizá-la. Baseado neste principio belicoso que o meu chefe, desenvolveu, no mesmo servidor que eu executava o logaute.sh um script para controlar o meu horário de chegada.
>
>
As I told you, while and until function antagonistically and this is very easy to demonstrate: in a war where you invent a gun, the enemy seeks a solution to neutralize it. Based on this principle bellicose my boss developed on the same server I ran the logaute.sh an script to control my arrival time.
  Um dia deu um problema da rede, ele me pediu para dar uma olhada no micro dele e me deixou sozinho em sua sala. Imediatamente comecei a bisbilhotar seus arquivos - porque guerra é guerra - e veja só o que descobri:

Revision 917 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 258 to 258
 File reading means reading one-on-one all records, which is always a slow operation. Be careful not to use the while when its use is unnecessary. The Shell have tools like sed and family grep which scour files optimally that crawl files optimally without requiring the use of commands loop to do it record by record (or even word by word).
Changed:
<
<

O comando until

>
>

The until command

 
Changed:
<
<
O comando until funciona exatamente igual ao while, porém ao contrário. Disse tudo mas não disse nada, né? É o seguinte: ambos testam comandos; ambos possuem a mesma sintaxe e ambos atuam em loop, porém enquanto o while executa o bloco de intruções do loop enquanto um comando for bem sucedido, o until executa o bloco do loop até que o comando seja bem sucedido. Parece pouca coisa mas a diferença é fundamental.
>
>
The until command works exactly the same as while, however unlike. He said all but said nothing, right? It is this: both test commands, both have the same syntax and both act in loop, but while while executes the block of instructions loop while a command is successful, the until executes the block of loop until the command to be successful. Seems little but the difference is fundamental.
 
Changed:
<
<
A sintaxe do comando é praticamente a mesma do while. Veja:
>
>
The command syntax is almost identical to the while. See:
 
Changed:
<
<
until comando
>
>
until command
  do cmd1 cmd2

Revision 817 Feb 2014 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 214 to 214
 $ read -p "Álbum Title: " Tit
Changed:
<
<
Bem, uma vez entendido isso, vamos à especificação do nosso problema: faremos um programa que inicialmente lerá o nome do álbum e em seguida fara um loop de leitura, pegando a música e o artista. Este loop termina quando for informada uma música vazia, isto é, ao ser solicitada a digitação da música, o operador dá um simples <ENTER>. Para facilitar a vida do operador, vamos oferecer como default o mesmo nome do artista da música anterior (já que é normal que o álbum seja todo do mesmo artista) até que ele deseje alterá-lo. Vamos ver como ficou:
>
>
Well, once you understand this, let the specification of our problem: we do a program that initially read the album name and then will make a loop reading, catching the music and the artist. This loop terminates when an empty music is informed, this is, when asked to typing of music, the operator gives a simple <ENTER>. To make life easier for the operator, we offer as default the same artist name of previous music (since it is normal that the album is all the same artist) until he wishes to change it. Let's see how it fits:
 
$ cat musinc #!/bin/bash
Changed:
<
<
# Cadastra CDs (versao 4)
>
>
# Registers CDs (version 4)
 # clear
Changed:
<
<
read -p "Título do Álbum: " Tit [ "$Tit" ] || exit 1 # Fim da execução se título vazio if grep "^$Tit\^" musicas > /dev/null
>
>
read -p "Album Title: " Tit [ "$Tit" ] || exit 1 # End of execution if empty title if grep "^$Tit\^" musics > /dev/null
 then
Changed:
<
<
echo Este álbum já está cadastrado
>
>
echo This album is already registered
  exit 1 fi Reg="$Tit^"
Line: 234 to 234
 oArt= while true do
Changed:
<
<
echo Dados da trilha $Cont: read -p "Música: " Mus [ "$Mus" ] || break # Sai se vazio read -p "Artista: $oArt // " Art [ "$Art" ] && oArt="$Art" # Se vazio Art anterior Reg="$Reg$oArt~$Mus:" # Montando registro
>
>
echo Track data $Cont: read -p "Music: " Mus [ "$Mus" ] || break # Leave empty read -p "Artist: $oArt // " Art [ "$Art" ] && oArt="$Art" # If empty Art previous Reg="$Reg$oArt~$Mus:" # mounting registry
  Cont=$((Cont + 1))
Changed:
<
<
# A linha anterior tb poderia ser ((Cont++))
>
>
# The above line could also be ((Cont++))
 done
Changed:
<
<
echo "$Reg" >> musicas sort musicas -o musicas
>
>
echo "$Reg" >> musics sort musics -o musics
 
Changed:
<
<
Este exemplo, começa com a leitura do título do álbum, que se não for informado, terminará a execução do programa. Em seguida um grep procura no início (^) de cada registro de musicas, o título informado seguido do separador (^) (que está precedido de uma contrabarra (\) para protegê-lo da interpretação do Shell).
>
>
This example starts with reading the album title, that is not informed, terminate program execution. Then one grep demand in the beginning (^) of each record musics, the title entered followed by the separator (^) (which is preceded by a backslash (\) to protect it from interpretation of Shell).
 
Changed:
<
<
Para ler os nomes dos artistas e as músicas do álbum, foi montado um loop de while simples, cujo único destaque é o fato de estar armazenando o artista da música anterior na variável $oArt que só terá o seu conteúdo alterado, quando algum dados for informado para a variável $Art, isto é, quando não teclou-se um simples <ENTER> para manter o artista anterior.
>
>
To read the names of the artists and the musics of the album, it set up a loop of while simple, whose only highlight is the fact of storing the artist of the previous song in the variable $oArt which will only its content changed, when some data is entered for the variable $Art, this is, when not typed up a simple <ENTER> to maintain the previous artist.
 
Changed:
<
<
O que foi visto até agora sobre o while foi muito pouco. Este comando é muito utilizado, principalmente para leitura de arquivos, porém nos falta bagagem para prosseguir. Depois que aprendermos a ler, veremos esta instrução mais a fundo.
>
>
What has been seen so far on the while was very little. This command is very used mainly for reading files, but we lack luggage to proceed. After learning to read, we'll see this statement further.
 
Pinguim com placa de dica (em inglês)
Changed:
<
<
Leitura de arquivo significa ler um-a-um todos os registros, o que é sempre uma operação lenta. Fique atento para não usar o while quando seu uso for desnecessário. O Shell tem ferramentas como o sed e a família grep que vasculham arquivos de forma otimizada sem ser necessário o uso de comandos de loop para fazê-lo registro a registro (ou até palavra a palavra).
>
>
File reading means reading one-on-one all records, which is always a slow operation. Be careful not to use the while when its use is unnecessary. The Shell have tools like sed and family grep which scour files optimally that crawl files optimally without requiring the use of commands loop to do it record by record (or even word by word).
 

O comando until

Revision 718 Nov 2013 - Main.AngelaFerreira

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

Pub Talk Part VI

Line: 200 to 200
 
Changed:
<
<
Vamos melhorar o musinc, que é o nosso programa para incluir registros no arquivo musicas, mas antes preciso te ensinar a pegar um dado da tela, e já vou avisando: só vou dar uma pequena dica do comando read (que é quem pega o dado da tela) que seja o suficiente para resolver este nosso problema. Em uma outra rodada de chope vou te ensinar tudo sobre o assunto, inclusive como formatar tela, mas hoje estamos falando sobre loops.
>
>
Let's improve the musinc, which is our program to include records in the file music, but first I need to teach you to catch a data of the screen, and I'm warning: I'll just give a little hint of the read command (which is who gets the data of the screen) it's enough to solve this our problem. In another round of beer I'll teach you all about it, including how to format screen, but today we are talking about loops.
 
Changed:
<
<
A sintaxe do comando read que nos interessa por hoje é a seguinte:
>
>
The command syntax to read what interests us today is:
 
Changed:
<
<
$ read -p "prompt de leitura" var
>
>
$ read -p "prompt of read" var
 
Changed:
<
<
Onde prompt de leitura é o texto que você quer que apareça escrito na tela, e quando o operador teclar o dado, ele irá para a variável var. Por exemplo:
>
>
Where prompt of read is the text you want to appear written on the screen, and when the operator keying the data, it will go to the variable var. For example:
 
Changed:
<
<
$ read -p "Título do Álbum: " Tit
>
>
$ read -p "Álbum Title: " Tit
 

Bem, uma vez entendido isso, vamos à especificação do nosso problema: faremos um programa que inicialmente lerá o nome do álbum e em seguida fara um loop de leitura, pegando a música e o artista. Este loop termina quando for informada uma música vazia, isto é, ao ser solicitada a digitação da música, o operador dá um simples <ENTER>. Para facilitar a vida do operador, vamos oferecer como default o mesmo nome do artista da música anterior (já que é normal que o álbum seja todo do mesmo artista) até que ele deseje alterá-lo. Vamos ver como ficou:

Revision 620 May 2011 - Main.AntonioTerceiro

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

Pub Talk Part VI

Line: 443 to 443
  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 xanax companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para moving company mim.
>
>
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! \ No newline at end of file

Revision 517 May 2011 - HenruKellion

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

Pub Talk Part VI

Line: 443 to 443
  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.
>
>
Qualquer dúvida ou falta de xanax companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para moving company mim.
  Valeu!

Revision 424 Mar 2010 - JulioNeves

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

Pub Talk Part VI

Line: 194 to 191
  This script is very similar to the previous ones, with a couple extra tricks: It must be run in background so it won't hold the prompt, but the $! will contain the PID of the program parsed as a parameter, since it was put in background after the monbg.sh itselfs. You may also notice that we are running grep with the option -q (quiet). You could obtain the same result running while ps|grep $! >/dev/null, as we've been using until now.
Added:
>
>
Pinguim com placa de dica (em inglês)
 
Deleted:
<
<
Pinguim com placa de dica
 Don't forget: Bash provides you the system variable $! which contains the PID (Process IDentification) of the last background running process.
Changed:
<
<
>
>
 
Line: 254 to 253
  O que foi visto até agora sobre o while foi muito pouco. Este comando é muito utilizado, principalmente para leitura de arquivos, porém nos falta bagagem para prosseguir. Depois que aprendermos a ler, veremos esta instrução mais a fundo.
Changed:
<
<
Pinguim com placa de dica
>
>
Pinguim com placa de dica (em inglês)
 Leitura de arquivo significa ler um-a-um todos os registros, o que é sempre uma operação lenta. Fique atento para não usar o while quando seu uso for desnecessário. O Shell tem ferramentas como o sed e a família grep que vasculham arquivos de forma otimizada sem ser necessário o uso de comandos de loop para fazê-lo registro a registro (ou até palavra a palavra).
Changed:
<
<
>
>
 

O comando until

Revision 310 Mar 2010 - JulioNeves

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

Pub Talk Part VI

Line: 145 to 145
 boss pts/0 Jan 4 08:52 (10.2.4.144)
Changed:
<
<
That means every 30 seconds it would send on my screen the grep command result, which was not nice, since it would pollute my screen and the expected freedom message could go unnoticed. Fortunately we know how to avoid it by redirecting the pipeline message to /dev/null.
>
>
That means every 30 seconds it would send on my screen the grep command result, which was not nice, since it would pollute my screen and the expected freedom message could go unnoticed. Fortunately we know how to avoid it by redirecting the pipeline message to /dev/null (another way to do the same, is using the -q (quiet) grep option. But this works only in GNU grep, not in UNIX).
 

Revision 208 Mar 2010 - EriBastos

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

Pub Talk Part VI

Line: 159 to 159
 echo The prick is gonne. Don't hesitate, exit.
Changed:
<
<

>
>
Now I want to put together a script that can take the name (and any other needed parameter) of a program which will run in background and let me know when it's finished. But before that, so you undestand the examples, I have to show you a new system variable. Take a look at this commands from the prompt:
 
Deleted:
<
<
Agora quero montar um script que receba o nome (e eventuais parâmetros) de um programa que será executado em background e que me informe do seu término. Mas, para você entender este exemplo, primeiro tenho de mostar uma nova variável do sistema. Veja estes comandos diretos no prompt:
 
$ sleep 10&
Line: 173 to 172
 16317
Changed:
<
<
Isto é, criei um processo em background para dormir por 10 segundos, somente para mostrar que a variável $! guarda o PID (Process IDentification) do último processo em background, mas repare após a linha do done, que a variável reteve o valor mesmo após o término deste processo.
>
>
It means I created a background process which would sleep 10 seconds so I could show you that the variable $! saves the PID (process IDentification) of the last background running process. But notice that after the line done that the variable kept it's value even after the process is finished.

Well, with that in mind it's easier to monitor any background process. Take a look how:

 
Deleted:
<
<
Bem sabendo isso já fica mais fácil de monitorar qualquer processo em background. Veja só como:
 
$ cat monbg.sh #!/bin/bash
Changed:
<
<
# Executa e monitora um # processo em background
>
>
# Run and monitors a # background process
 
Changed:
<
<
$1 & # Coloca em backgroud
>
>
$1 & # Puts in backgroud
 while ps | grep -q $! do sleep 5 done
Changed:
<
<
echo Fim do Processo $1
>
>
echo Process is finished $1
 
Changed:
<
<
Este script é bastante similar ao anterior, mas tem uns macetes a mais, veja só: ele tem que ser executado em background para não prender o prompt mas o $! será o do programa passado como parâmetro já que ele foi colocado em background após o monbg.sh propriamente dito. Repare também a opção -q (quiet) do grep, ela serve para tranformá-lo num comando mineiro, isto é, para o grep "trabalhar em silêncio". O mesmo resultado poderia ser obtido se a linha fosse while ps | grep $! > /dev/null, como nos exemplos que vimos até agora.
>
>
This script is very similar to the previous ones, with a couple extra tricks: It must be run in background so it won't hold the prompt, but the $! will contain the PID of the program parsed as a parameter, since it was put in background after the monbg.sh itselfs. You may also notice that we are running grep with the option -q (quiet). You could obtain the same result running while ps|grep $! >/dev/null, as we've been using until now.
 
Pinguim com placa de dica
Changed:
<
<
Não esqueça: o Bash disponibiliza a variável $! que possui o PID (Process IDentification) do último processo executado em background.
>
>
Don't forget: Bash provides you the system variable $! which contains the PID (Process IDentification) of the last background running process.
 
Added:
>
>

 Vamos melhorar o musinc, que é o nosso programa para incluir registros no arquivo musicas, mas antes preciso te ensinar a pegar um dado da tela, e já vou avisando: só vou dar uma pequena dica do comando read (que é quem pega o dado da tela) que seja o suficiente para resolver este nosso problema. Em uma outra rodada de chope vou te ensinar tudo sobre o assunto, inclusive como formatar tela, mas hoje estamos falando sobre loops.

A sintaxe do comando read que nos interessa por hoje é a seguinte:

Revision 106 Mar 2010 - EriBastos

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

Pub Talk Part VI

Loop commands (Continuing)

     - Hey dude! What's up? Are you all familiar with the for command yet? I gave you some homework for you to get acquainted with it. Did you do it?

     - Off course, man! I'm all excited about this new language and I did just what you asked me. I mean, without using the command wc, or it would be just too easy. Take lo...

     - Hold your horses, pal. You may be hooked to that language, but I'm really thirst! I need a beer. Hey, waiter... bring me two, please!

     - Anyway, like I was saying... take a look how I did it. Really easy...

$ cat contpal.sh #!/bin/bash # Example script # It's going to count the number of words # inside a file. We assume the words # are separated by spaces, or # if [ $# -ne 1 ] then echo usage: $0 /file/path exit 2 fi Cont=0 for Word in $(cat $1) do Cont=$((Cont+1)) done echo File $1 contains $Cont words.

That means the program will always start by checking if the parameters are correct, then will use the for command to count every word (remeber that the standard $IFS is space, <TAB> and <ENTER>, which is exactly how our words are separated by), adding to the $Cont variable.

Lets check again the file ArqDoDOS.txt.

$ cat ArqDoDOS.txt This file was created by Dos/Windows and download by a badly implemented ftp.

Let's try our program again, having this file as parameter:

$ contpal.sh ArqDoDOS.txt File ArqDoDOS.txt contains 13 words.

     - Nice! Works like a charm.

A little bit more of for and Math

Back to business. Last time we were here we finished our talk showing the following for loop:

    for ((; i<=9;))
    do
        let i++
        echo -n "$i "
    done

Once we get here, I think I should let you know that the Shell has the Arithmetic Expansion concept, which I'll give just a brief overview, since you can find an in depth coverage on the appetizer section.

The arithmetic expansion will be triggered by a construction like:

     $((expression))

or

     let expression

On the last for we talked about I used both forms of it, but we can't go ahead without knowing that the expression can be one of the following:

Arithmetic Expansion
||   bitwise OR
  Expression     Result  
id++ id--   variable post-increment and post-decrement
++id -–id   variable pre-increment and pre-decrement
**   Exponentiation
* / %  multiplication, division, remainder
+ -   unary minus and plus
<= >= < >   comparison operators
== !=   equality and inequality
&&   bitwise AND

     - Wait. You think that our talk about loop is over with the for command? Silly mistake, buddy. We still have two others to check out.

The while command

Every programmer knows this command, since it's found on every language and usually a bunch of commands are executed while a certain condition is true. Therefore the name. Meeh... That only happens on those boring languages. On Shell programming a bunch of commands are executed while a command is true. And, of course, if you want to check if a condition is true you can do it by using while with test, exactly how you learnt back during our if talk. Remember?

So, the syntax will look like this:

    while command
    do
        cmd1
        cmd2
        ...
        cmdn
    done

So the command block made witht he instructions cmd1, cmd2,... and cmdn will run while the execution of the command is successful.

Think about the following scenario: I have this hot babe waiting for me, but I can't leave work since my prick boss (kinda redundant, I know) is still working and his office is on my way out.

I think he got suspicious after the fifth time I walked to the restroom to check if he was still there... So I had to go back to my desk, connect to the server and create the following script:

$ cat logout.sh #!/bin/bash

while who | grep boss do sleep 30 done echo The prick is gonne. Don't hesitate, exit.

This tiny script uses the while command tests the pipeline returned by the who and grep commands, which will be true while grep is able to locate the word boss on =who='s return. So the script will sleep for 30 seconds while the boss is still there (Argh!). As soon as he disconnects from the server, the script flow will leave the loop and yield the so much wanted freedom message.

So, when I ran it, guess what happened?

$ logout.sh boss pts/0 Jan 4 08:46 (10.2.4.144) boss pts/0 Jan 4 08:47 (10.2.4.144) ... boss pts/0 Jan 4 08:52 (10.2.4.144)

That means every 30 seconds it would send on my screen the grep command result, which was not nice, since it would pollute my screen and the expected freedom message could go unnoticed. Fortunately we know how to avoid it by redirecting the pipeline message to /dev/null.

$ cat logout.sh #!/bin/bash

while who | grep boss > /dev/null do sleep 30 done echo The prick is gonne. Don't hesitate, exit.


Agora quero montar um script que receba o nome (e eventuais parâmetros) de um programa que será executado em background e que me informe do seu término. Mas, para você entender este exemplo, primeiro tenho de mostar uma nova variável do sistema. Veja estes comandos diretos no prompt:

$ sleep 10& [1] 16317 $ echo $! 16317 [1]+ Done sleep 10 $ echo $! 16317

Isto é, criei um processo em background para dormir por 10 segundos, somente para mostrar que a variável $! guarda o PID (Process IDentification) do último processo em background, mas repare após a linha do done, que a variável reteve o valor mesmo após o término deste processo.

Bem sabendo isso já fica mais fácil de monitorar qualquer processo em background. Veja só como:

$ cat monbg.sh #!/bin/bash

# Executa e monitora um # processo em background

$1 & # Coloca em backgroud while ps | grep -q $! do sleep 5 done echo Fim do Processo $1

Este script é bastante similar ao anterior, mas tem uns macetes a mais, veja só: ele tem que ser executado em background para não prender o prompt mas o $! será o do programa passado como parâmetro já que ele foi colocado em background após o monbg.sh propriamente dito. Repare também a opção -q (quiet) do grep, ela serve para tranformá-lo num comando mineiro, isto é, para o grep "trabalhar em silêncio". O mesmo resultado poderia ser obtido se a linha fosse while ps | grep $! > /dev/null, como nos exemplos que vimos até agora.

Pinguim com placa de dica Não esqueça: o Bash disponibiliza a variável $! que possui o PID (Process IDentification) do último processo executado em background.

Vamos melhorar o musinc, que é o nosso programa para incluir registros no arquivo musicas, mas antes preciso te ensinar a pegar um dado da tela, e já vou avisando: só vou dar uma pequena dica do comando read (que é quem pega o dado da tela) que seja o suficiente para resolver este nosso problema. Em uma outra rodada de chope vou te ensinar tudo sobre o assunto, inclusive como formatar tela, mas hoje estamos falando sobre loops.

A sintaxe do comando read que nos interessa por hoje é a seguinte:

$ read -p "prompt de leitura" var

Onde prompt de leitura é o texto que você quer que apareça escrito na tela, e quando o operador teclar o dado, ele irá para a variável var. Por exemplo:

$ read -p "Título do Álbum: " Tit

Bem, uma vez entendido isso, vamos à especificação do nosso problema: faremos um programa que inicialmente lerá o nome do álbum e em seguida fara um loop de leitura, pegando a música e o artista. Este loop termina quando for informada uma música vazia, isto é, ao ser solicitada a digitação da música, o operador dá um simples <ENTER>. Para facilitar a vida do operador, vamos oferecer como default o mesmo nome do artista da música anterior (já que é normal que o álbum seja todo do mesmo artista) até que ele deseje alterá-lo. Vamos ver como ficou:

$ cat musinc #!/bin/bash # Cadastra CDs (versao 4) # clear read -p "Título do Álbum: " Tit [ "$Tit" ] || exit 1 # Fim da execução se título vazio if grep "^$Tit\^" musicas > /dev/null then echo Este álbum já está cadastrado exit 1 fi Reg="$Tit^" Cont=1 oArt= while true do echo Dados da trilha $Cont: read -p "Música: " Mus [ "$Mus" ] || break # Sai se vazio read -p "Artista: $oArt // " Art [ "$Art" ] && oArt="$Art" # Se vazio Art anterior Reg="$Reg$oArt~$Mus:" # Montando registro Cont=$((Cont + 1)) # A linha anterior tb poderia ser ((Cont++)) done echo "$Reg" >> musicas sort musicas -o musicas

Este exemplo, começa com a leitura do título do álbum, que se não for informado, terminará a execução do programa. Em seguida um grep procura no início (^) de cada registro de musicas, o título informado seguido do separador (^) (que está precedido de uma contrabarra (\) para protegê-lo da interpretação do Shell).

Para ler os nomes dos artistas e as músicas do álbum, foi montado um loop de while simples, cujo único destaque é o fato de estar armazenando o artista da música anterior na variável $oArt que só terá o seu conteúdo alterado, quando algum dados for informado para a variável $Art, isto é, quando não teclou-se um simples <ENTER> para manter o artista anterior.

O que foi visto até agora sobre o while foi muito pouco. Este comando é muito utilizado, principalmente para leitura de arquivos, porém nos falta bagagem para prosseguir. Depois que aprendermos a ler, veremos esta instrução mais a fundo.

Pinguim com placa de dica Leitura de arquivo significa ler um-a-um todos os registros, o que é sempre uma operação lenta. Fique atento para não usar o while quando seu uso for desnecessário. O Shell tem ferramentas como o sed e a família grep que vasculham arquivos de forma otimizada sem ser necessário o uso de comandos de loop para fazê-lo registro a registro (ou até palavra a palavra).

O comando until

O comando until funciona exatamente igual ao while, porém ao contrário. Disse tudo mas não disse nada, né? É o seguinte: ambos testam comandos; ambos possuem a mesma sintaxe e ambos atuam em loop, porém enquanto o while executa o bloco de intruções do loop enquanto um comando for bem sucedido, o until executa o bloco do loop até que o comando seja bem sucedido. Parece pouca coisa mas a diferença é fundamental.

A sintaxe do comando é praticamente a mesma do while. Veja:

    until comando
    do
        cmd1
        cmd2
        ...
        cmdn
    done

E desta forma o bloco de comandos formado pelas instruções cmd1, cmd2,... e cmdn é executado até que a execução da instrução comando seja bem sucedida.

Como eu te disse, o while e until funcionam de forma antagônica e isso é muito fácil de demonstrar: em uma guerra sempre que se inventa uma arma, o inimigo busca uma solução para neutralizá-la. Baseado neste principio belicoso que o meu chefe, desenvolveu, no mesmo servidor que eu executava o logaute.sh um script para controlar o meu horário de chegada.

Um dia deu um problema da rede, ele me pediu para dar uma olhada no micro dele e me deixou sozinho em sua sala. Imediatamente comecei a bisbilhotar seus arquivos - porque guerra é guerra - e veja só o que descobri:

$cat chegada.sh #!/bin/bash

until who | grep julio do sleep 30 done echo $(date "+ Em %d/%m às %H:%Mh") >> relapso.log

Olha que safado! O cara estava montando um log com os horários que eu chegava, e ainda por cima chamou o arquivo que me monitorava de relapso.log! O que será que ele quis dizer com isso?

Neste script, o pipeline who | grep julio, será bem sucedido somente quando julio for encontrado no comando who, isto é, quando eu me "logar" no servidor. Até que isso aconteça, o comando sleep, que forma o bloco de instruções do until, porá o programa em espera por 30 segundos. Quando este loop encerrar-se, será dada uma mensagem para o relapso.log (ARGHH!). Supondo que no dia 20/01 eu me loguei às 11:23 horas, a mensagem seria a seguinte:

     Em 20/01 às 11:23h

Quando vamos cadastrar músicas, o ideal seria que pudéssemos cadastrar diversos CDs, e na última versão que fizemos do musinc, isso não ocorre, a cada CD que cadastramos o programa termina. Vejamos como melhorá-lo:

$ cat musinc #!/bin/bash # Cadastra CDs (versao 5) # Para= until [ "$Para" ] do clear read -p "Título do Álbum: " Tit if [ ! "$Tit" ] # Se titulo vazio... then Para=1 # Liguei flag de saída else if grep "^$Tit\^" musicas > /dev/null then echo Este álbum já está cadastrado exit 1 fi Reg="$Tit^" Cont=1 oArt= while [ "$Tit" ] do echo Dados da trilha $Cont: read -p "Música: " Mus [ "$Mus" ] || break # Sai se vazio read -p "Artista: $oArt // " Art [ "$Art" ] && oArt="$Art" # Se vazio Art anterior Reg="$Reg$oArt~$Mus:" # Montando registro Cont=$((Cont + 1)) # A linha anterior tb poderia ser ((Cont++)) done echo "$Reg" >> musicas sort musicas -o musicas fi done

Nesta versão, um loop maior foi adicionado antes da leitura do título, que só terminará quando a variável $Para deixar de ser vazia. Caso o título do álbum não seja informado, a variável $Para receberá valor (no caso coloquei 1 mas poderia ter colocado qualquer coisa. O importante é que não seja vazia) para sair deste loop, terminando desta forma o programa. No resto, o script é idêntico à sua versão anterior.

Atalhos no loop

Nem sempre um ciclo de programa, compreendido entre um do e um done, sai pela porta da frente. Em algumas oportunidades, temos que colocar um comando que aborte de forma controlada este loop. De maneira inversa, algumas vezes desejamos que o fluxo de execução do programa volte antes de chegar ao done. Para isto, temos respectivamente, os comandos break (que já vimos rapidamente nos exemplos do comado while) e continue, que funcionam da seguinte forma:

O que eu não havia dito anteriormente é que nas suas sintaxes genéricas eles aparecem da seguinte forma:

     break [qtd loop]

e

     continue [qtd loop]

Onde qtd loop representa a quantidade dos loops mais internos sobre os quais os comandos irão atuar. Seu valor default é 1.

Fluxograma

Duvido que você nunca tenha deletado um arquivo e logo após deu um tabefe na testa se xingando porque não devia tê-lo removido. Pois é, na décima vez que fiz esta besteira, criei um script para simular uma lixeira, isto é, quando mando remover um (ou vários) arquivo(s), o programa "finge" que removeu-o, mas no duro o que fez foi mandá-lo(s) para o diretório /tmp/LoginName_do_usuario. Chamei este programa de erreeme e no /etc/profile coloquei a seguinte linha:

     alias rm=erreeme

O programa era assim:

$ cat erreeme #/bin/bash # # Salvando Copia de Arquivo Antes de Remove-lo #

if [ $# -eq 0 ] # Tem de ter um ou mais arquivos para remover then echo "Erro -> Uso: erreeme arq [arq] ... [arq]" echo " O uso de metacaracteres e’ permitido. Ex. erreeme arq*" exit 1 fi

MeuDir="/tmp/$LOGNAME" # Variavel do sist. Contém o nome do usuário. if [ ! -d $MeuDir ] # Se não existir o meu diretório sob o /tmp... then mkdir $MeuDir # Vou cria-lo fi

if [ ! -w $MeuDir ] # Se não posso gravar no diretório... then echo Impossivel salvar arquivos em $MeuDir. Mude permissao... exit 2 fi

Erro=0 # Variavel para indicar o cod. de retorno do prg for Arq # For sem o "in" recebe os parametros passados do if [ ! -f $Arq ] # Se este arquivo não existir... then echo $Arq nao existe. Erro=3 continue # Volta para o comando for fi

DirOrig=`dirname $Arq` # Cmd. dirname informa nome do dir de $Arq if [ ! -w $DirOrig ] # Verifica permissão de gravacaoo no diretório then echo Sem permissao de remover no diretorio de $Arq Erro=4 continue # Volta para o comando for fi

if [ "$DirOrig" = "$MeuDir" ] # Se estou "esvaziando a lixeira"... then echo $Arq ficara sem copia de seguranca rm -i $Arq # Pergunta antes de remover [ -f $Arq ] || echo $Arq removido # Será que o usuario removeu? continue fi

cd $DirOrig # Guardo no fim do arquivo o seu diretorio pwd >> $Arq # original para usa-lo em um script de undelete mv $Arq $MeuDir # Salvo e removo echo $Arq removido done exit $Erro # Passo eventual numero do erro para o codigo de retorno

Como você pode ver, a maior parte do script é formada por pequenas criticas aos parâmetros informados, mas como o script pode ter recebido diversos arquivos para remover, a cada arquivo que não se encaixa dentro do especificado, há um continue, para que a sequência volte para o loop do for de forma a receber outros arquivos.

Quando você está no Windows (com perdão da má palavra) e tenta remover aquele monte de lixo com nomes esquisitos como HD04TG.TMP, se der erro em um deles, os outros não são removidos, não é? Então, o continue foi usado para evitar que um impropério desses ocorra, isto é, mesmo que dê erro na remoção de um arquivo, o programa continuará removendo os outros que foram passados.

     - Eu acho que a esta altura você deve estar curioso para ver o programa que restaura o arquivo removido, não é? Pois então aí vai vai um desafio: faça-o em casa e me traga para discutirmos no nosso próximo encontro aqui no boteco.

     - Poxa, mas nesse eu acho que vou dançar, pois não sei nem como começar...

     - Cara, este programa é como tudo que se faz em Shell, extremamente fácil, é para ser feito em, no máximo 10 linhas. Não se esqueça que o arquivo está salvo em /tmp/$LOGNAME e que a sua última linha é o diretório em que ele residia antes de ser "removido". Também não se esqueça de criticar se foi passado o nome do arquivo a ser removido.

     - É eu vou tentar, mas sei não...

     - Tenha fé irmão, eu tô te falando que é mole! Qualquer dúvida é só me passar um e-mail para julio.neves@gmail.com. Agora chega de papo que eu já estou de goela seca de tanto falar. Me acompanha no próximo chope ou já vai sair correndo para fazer o script que passei?

     - Deixa eu pensar um pouco...

     - Chico, traz mais um chope enquanto ele pensa!

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!

 
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