Linux Shell ProgrammingHere we have a free and complete book about ShellThe thirst of the "free knowledge" is welcome. |
Comandos Shell Script |
||
Home | Articles | Buy the bookChangelogs |
Pub Talk 1Pub Talk 2Pub Talk 3Pub Talk 4Pub Talk 5 |
Pub Talk - Part V
- YO, man! How' doin' ? How's your brain ? Burned or can you handle more Shell ?
- I do ! I'm loving it ! I liked it so much that I put more love at exercise you gave me. Did you remember you asked me to do a program to receive as parameter a file name and, when executed, it should save this file with its original name followed by a tilde (
- Sure I do. Show me the money and tell me how you did it. $ cat vira
#!/bin/bash
#
# vira - vi backing up the previous file
# == = =
# Cheking if we have one parameter
if [ "$#" -ne 1 ]
then
echo "Error -> Usage: $0 Arq=$1 # If the file doesn't exist, there is no copy to be saved if [ ! -f "$Arq" ] then vi $Arq exit 0 fi # If I can save the file, why call vi ? if [ ! -w "$Arq" ] then echo "You are not allowed to write $Arq" exit 2 fi # Everything is OK. I'll save the backup and call vi cp -f $Arq $Arq~ vi $Arq exit 0
- Yeah, right ! But tell me: why did you finish the program with an
- Ahhh! I found the number after
- Good boy, you learned cool, but is better to clarify
'Till now, we saw some program blocks. When we saw an example about a cd lmb 2> /dev/null || { mkdir lmb cd lmb }
the code inside two keys (
A command block can be inside a
- Hold on Julio, what are these
- Yeah, you're right. I didn't tell it because the right time wasn't arrived. All loop instructions execute the block command found between Loop Commands
The loop commands, or loop instructions, are The for command
If you are a programmer, or have some programming experience, I'm sure you know the Lets understand its syntax, first in plain english, and then the real deal. for var in val1 val2 ... valn do cmd1 cmd2 cmdn done
The variable Now we saw what that means, lets see the correct syntax: for command first syntaxfor var in val1 val2 ... valn do cmd1 cmd2 cmdn done
That is amazing ! There is no changes between the real life, our real language, and the $ echo *
ArqDoDOS.txt1 confuso incusu logado musexc musicas musinc muslist
That means, Shell saw the star (
$ cat testefor1
#!/bin/bash
# 1st. Program to understand for
for Arq in * do echo -n $Arq: # The -n option doesn't generate a new line done Then lets run it: $ testefor1
ArqDoDOS.txt1:confuso:incusu:logado:musexc:musicas:musinc:muslist:$
As you can see, Shell changes the star in a space-separeted list. When
The command block to be executed was only the Another simple example (by now): $ cat testefor2
#!/bin/bash
# 2nd. program to understand for
for WORD in We are in the Pub Talk do echo $WORD done Running, whe have: $ testefor2
We
are
in
the
Tub
Talk
This is a silly simple sample, like the other one, but serves to show
See the power of the
For real, the lists are not separated by spaces unconditionally but, before go ahead, let me show you how is the behavior of a system variable called $ echo "$IFS" | od -h
0000000 0920 0a0a
0000004
I sent the variable (protected from Shell execution by quotation marks) to a hexadecimal dump (
Where the last $ echo ":$IFS:" | cat -vet
: ^I$
:$
Payt attention to the following tip to understand that cat construction:
At the
cat command, option -e represents the <ENTER> whit a dolar ($ ) and the option -t represents the <TAB> as a ^I . I used colons (: ) to show echo='s start and ending. This way, once again we can see that the variable =$IFS has three characters.
Now see, $ cat musics
album 1^Artista1~Musica1:Artista2~Musica2
album 2^Artista3~Musica3:Artista4~Musica4
album 3^Artista5~Musica5:Artista6~Musica6
album 4^Artista7~Musica7:Artista1~Musica3
album 5^Artista9~Musica9:Artista10~Musica10
Using this layout, we wrote the following script: $ cat listartista
#!/bin/bash
if [ $# -ne 1 ] then echo You should pass a parameter exit 1 fi IFS=" :" for ArtMus in $(cut -f2 -d^ musicas) do echo "$ArtMus" | grep $1 && echo $ArtMus | cut -f2 -d~ done
The script, as always, starts testing if the parameters was correctly passed . After that, the $ listartista Artista1
Artista1~Musica1
Musica1
Artista1~Musica3
Musica3
Artista10~Musica10
Musica10
Ups! Two undesireable things happen: the blocks and the
To avoid this, I should pass the artist name between quotes ( echo "$ArtMus" | grep Paris & Britney what would generate an error. The right way is: echo "$ArtMus" | grep -i "Paris & Britney"
We put the
We still need to fix the list of $ cat listartista
#!/bin/bash
# Dado um artista, mostra as suas musicas
# versao 2
if [ $# -eq 0 ] then echo You should pass a parameter exit 1 fi IFS=" :" for ArtMus in $(cut -f2 -d^ musicas) do echo "$ArtMus" | grep -i "^$@~" > /dev/null && echo $ArtMus | cut -f2 -d~ done Running it, we have: $ listartista Artista1
Musica1
Musica3
for command second syntaxfor var do cmd1 cmd2 cmdn done
- What ? Whitout the
- Yeah, right ? This construction seems strange but it is quite simple. In this case, Lets make some samples to better understanding. We'll do a script to receive a bunch of musics as parameters and list its authors: $ cat listamusica
#!/bin/bash
# Receives parts of the music as parameter and
# lists its players. If the parameter is a composite name
# shall be passed between quotes.
# ex. "Ups I did it again" "Four died in Ohio"
#
if [ $# -eq 0 ]
then
echo Uso: $0 musica1 [musica2] ... [musican]
exit 1
fi
IFS="
:"
for Musica
do
echo $Musica
Str=$(grep -i "$Musica" musicas) ||
{
echo " not found"
continue
}
for ArtMus in $(echo "$Str" | cut -f2 -d^)
do
echo " $ArtMus" | grep -i "$Musica" | cut -f1 -d~
done
done
Again, we started the exercise with a parameter check. Then we did a Lets run to see if it works: $ listamusica musica3 Musica4 "Poison"
musica3
Artista3
Artista1
Musica4
Artista4
Poison
Não encontrada
That's an ugly output because we still don't know how to format outputs, but any given day, when you know how to work with cursos positioning, bold, color, etc, we'll do this list again using all these "little stuff".
At this time, we must asking: "What about that traditional, other languages,
I will answer you: "I told you, homeboy, our 1 - With our first syntax, as the following examples, run straigh at the prompt: $ for i in $(seq 9)
> do
> echo -n "$i "
> done
1 2 3 4 5 6 7 8 9
In this one, the variable
Still using $ for i in $(seq 3 9)
> do
> echo -n "$i "
> done
4 5 6 7 8 9
Or with the more complete $ for i in $(seq 0 3 9)
> do
> echo -n "$i "
> done
0 3 6 9
2 - The other way is to do the same with a C-like syntax, showed as follow. for command third syntaxfor ((var=ini; cond; incr)) do cmd1 cmd2 cmdn done Onde:
Examples, examples, examples, to clarify the things: $ for ((i=1; i<=9; i++))
> do
> echo -n "$i "
> done
1 2 3 4 5 6 7 8 9
In this case the variable
Notice that at the
And, as I told about the $ for ((; i<=9;))
> do
> let i++
> echo -n "$i "
> done
1 2 3 4 5 6 7 8 9
The increment was tooked off the $ echo $j
$ let j++ $ echo $j 1
That means, the variable See how simple the things can be: $ for arq in *
> do
> let i++
> echo "$i -> $Arq"
> done
1 -> ArqDoDOS.txt1
2 -> confuso
3 -> incusu
4 -> listamusica
5 -> listartista
6 -> logado
7 -> musexc
8 -> musicas
9 -> musinc
10 -> muslist
11 -> testefor1
12 -> testefor2
- That's it mate. I'm pretty sure you are full of
- Hey Chico! Bring me the last one. |
||||||||||
Creative Commons license - Attribution and Non-Commercial (CC) 2009 By Visitors of Júlio Neves´s Pub. All content of this page may be used under the terms of the Creative Commons License: Atribuição-UsoNãoComercial-PermanênciaDaLicença. |