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 II'Waiter, get me a pint and don't worry about my lad over here, he's finally getting to meet a real operating system and he's got a lot to learn!' 'So my friend, could you get anything of what I've said so far?' 'Well, I can get what you mean, but I actually don't see what's the point of it.'
'Take it easy pal! We're just begining... What I've said so far is a taste of what lies ahead. As soon as we start developing structured programs, you'll see how useful those tools can be. After learning that, you'll see how easy it is to reach the top shellves. Now, tell me: how do you like the
'Pardon me! I don't know any
'Sure, sure...
'Well, this The great grep'Waiter, this time I'll try a caipirinha - the Brazilian National Drink - (See how to prepare it)!'
'So, I told you that Searching a file: $ grep mary /etc/passwd
Searching more than one file: $ grep grep *.sh
Searching the output of a command $ who | grep pelegrino
Considering the 1st example - which is the simplest one - I searched the occurrences of the word $ grep '^rafael' /etc/passwd
'Hold on, hold on... what's that caret (circumflex
'The caret (
The 2nd example will list all the lines of all the files with the extension
And look!!
So, looking at the 3rd example, the command The grep family
You know, the command
Their main features are:
The considerations above on speed are valid to the Unix
grep family. grep is faster running on Linux, because the other two (fgrep and egrep ) are shell scripts that execute grep .
And I must say: I don't like that solution. 'Now that you know the differences among the tree, tell me: What do you think about the examples I gave before the explanation?'
'I thought 'Perfect!! I see you got what I said! Let's see some other examples to make their differences even clearer.'
I know that there is a text talking about Linux, but I'm not quite sure on whether the word Linux is written with a capital L or with a small one, what should I do? There are two options in that case: $ egrep (Linux | linux) arquivo.txt
or $ grep [Ll]inux arquivo.txt
In the first case, the complex regular expression
In the second case, on the other hand, the regular expression Another example. If you want to list the subdirectories of a directory, you should run: $ ls -l | grep '^d'
drwxr-xr-x 3 root root 4096 Dec 18 2000 doc
drwxr-xr-x 11 root root 4096 Jul 13 18:58 freeciv
drwxr-xr-x 3 root root 4096 Oct 17 2000 gimp
drwxr-xr-x 3 root root 4096 Aug 8 2000 gnome
drwxr-xr-x 2 root root 4096 Aug 8 2000 idl
drwxrwxr-x 14 root root 4096 Jul 13 18:58 locale
drwxrwxr-x 12 root root 4096 Jan 14 2000 lyx
drwxrwxr-x 3 root root 4096 Jan 17 2000 pixmaps
drwxr-xr-x 3 root root 4096 Jul 2 20:30 scribus
drwxrwxr-x 3 root root 4096 Jan 17 2000 sounds
drwxr-xr-x 3 root root 4096 Dec 18 2000 xine
As you can see above, the circumflex (
Let's take another example. You know what are the first four positions of the output of a
Thus, in order to find out what are the executable files in a directory, you should: $ ls -la | egrep '^-..(x|s)'
-rwxr-xr-x 1 root root 2875 Jun 18 19:38 rc
-rwxr-xr-x 1 root root 857 Aug 9 22:03 rc.local
-rwxr-xr-x 1 root root 18453 Jul 6 17:28 rc.sysinit
Once again the caret ( The same result would be found with the command: $ ls -la | grep '^-..[xs]'
and the search would be faster. Building a CD Library'Let me use a nice and didactic example: the process of building a CD Library. Keep in mind that it is as possible to develop software to organize audio CDs, as it is to data CDs (including those you get when you buy magazines, those you burn for yourself, etc.).' 'Hold on a sec. Where am I taking the CD data from?' 'Firstly I'll show you how your software can obtain data from those who are using it, afterwards I'll show you how to get data from the screen or from a file.' Informing the Parameters'In our case, the layout of a music file will be:' name of the album^artist~name of the song:..:singer of the song
As you can see above, a circumflex (
The software I'm intended to develop is called $ musinc "album^musician~music:musician~music:..."
That way, the software $ cat teste
#!/bin/bash
# Program to test how to inform the parameters
echo "1o. parm -> $1"
echo "2o. parm -> $2"
echo "3o. parm -> $3"
Let's run it now: $ teste informing parameters to test
bash: teste: cannot execute
OOPS, there is a detail I've forgotten: we have to make the file executable before running it: $ chmod 755 teste
$ teste informing parameters to test
1o. parm -> informing
2o. parm -> parameters
3o. parm -> to
Interestingly, the last word $ teste "informing parameters" to test
1o. parm -> informing parameters
2o. parm -> to
3o. parm -> test
With inverted commas Shell did not consider the blank space between the two first words, making it consider them as a single parameter. Parametric HintsSince we are talking about parameters, let me give you some hints:
teste , in order to use the variables we have just seen. Let's do it this way:
$ cat teste
#!/bin/bash
# Program to test how to inform the parameters (2nd Version)
echo The program $0 received $# parameters
echo "1o. parm -> $1"
echo "2o. parm -> $2"
echo "3o. parm -> $3"
echo Todos de uma só \"tacada\": $*
Note that preceding the inverted commas I inserted a inverted slash, in order to tell Shell not to interpret them. Let's run the program. $ teste informing parameters to test
The program teste received 4 parameters
1o. parm -> informing
2o. parm -> parameters
3o. parm -> to
Todos de uma "tacada": informing parameters to test
As I've said before, the parameters are numbered from 1 to 9, but that does not mean that it is not possible to use more than 9 parameters. Let's test it:
$ cat teste
#!/bin/bash
# Program to test how to inform the parameters (3rd Version)
echo The program $0 received $# parameters
echo "11th parm -> $11"
shift
echo "2nd parm -> $1"
shift 2
echo "4th Parm -> $4"
Let's run it now: $ teste informing parameters to test
The program teste received 4 parameters
11th parm -> informing1
2nd parm -> parameters
4th parm -> test
There are two remarkable points about this script:
Well, now that you know a little bit more about informing parameters, let's return to our CD Library and create our script for including CDs on bank called
$ cat musinc
#!/bin/bash
# Cadastra CDs (Version 1)
#
echo $1 >> musics
Since it is a is very functional script, I'll simply attach the received parameter at the end of the file songs. Let's include 3 albums and see if it works (in order to simplify, I'll suppose each album contains just 2 songs): $ musinc "album 3^Musician5~Music5:Musician6~Music5"
$ musinc "album 1^Musician1~Music1:Musician2~Music2"
$ musinc "album 2^Musician3~Music3:Musician4~Music4"
Listing the content of songs. $ cat musics
album 3^Musician5~Music5:Musician6~Music6
album 1^Musician1~Music1:Musician2~Music2
album 2^Musician3~Music3:Musician4~Music4
It is not as functional as it was supposed to be... it could be a lot better. The albums are out of order, complicating the research. Let's change the script and test it again:
$ cat musinc
#!/bin/bash
# Cadastra CDs (versao 2)
#
echo $1 >> musics
sort musics -o musics
Including another one $ musinc "album 4^Musician7~Music7:Musician8~Music8"
Now let's see what happens to the song file: $ cat musics
album 1^Musician1~Music1:Musician2~Music2
album 2^Musician3~Music3:Musician4~Music4
album 3^Musician5~Music5:Musician6~Music5
album 4^Musician7~Music7:Musician8~Music8
I simply inserted a line that classifies the file WOW! Now it is nice and almost functional. But attention and don't panic! That is not the final version. The next version of the program will be a lot better and more friendly! We'll develop it as soon as we learn how to get data from the screen and how to format the input.
Listing with the $ cat muslist
#!/bin/bash
# Search for CDs (version 1)
#
grep $1 musicas
Let's run it looking for $ muslist "album 2"
grep: can't open 2
musicas: album 1^Musician1~Music1:Musician2~Music2
musicas: album 2^Musician3~Music3:Musician4~Music4
musicas: album 3^Musician5~Music5:Musician6~Music6
musicas: album 4^Musician7~Music7:Musician8~Music8
'What a mess!! Where is the mistake? I put the parameter between inverted commas so that shell would not split it into two...'
'Yeap, but pay attention to how grep $1 musics
Even putting grep album 2 musics
As the grep [arq1, arq2, ..., arqn]
Use inverted commas whenever there is a blank space or a
<TAB> in the chain of characters that grep will run. That helps the words after the blank space or <TAB> from being interpreted as file names.
On the other side, it is better not to consider the case of the letters in the research. The following program would solve two problems at the same time: $ cat muslist
#!/bin/bash
# Search for CDs (version 2)
#
grep -i "$1" musics
In that case, the option $ muslist "album 2"
album2^Musician3~Music3:Musician4~Music4
Pay attention too to the fact that 'Hold on pal! That putting between inverted commas thing is not really a friendly way of doing that...' 'You are right! Let me show you another way, then: $ cat muslist
#!/bin/bash
# Consulta CDs (versao 3)
#
grep -i "$*" musics
$ muslist album 2
album 2^Musician3~Music3:Musician4~Music4
The option You should have realized by now that the problem about Shell is not if if does or not something, but what is the best way of doing it (as you've seen, the range of options is huge!).' 'But what if I have to exclude a CD? Once I forgot a CD of mine under the sun and when I looked at it again... it was lost. What if that happened again?'
'Well, let's make another script called
Before developing it, I'd like to introduce you to a very useful option of the $ grep -v "album 2" musics
album 1^Musician1~Music1:Musician2~Music2
album 3^Musician5~Music5:Musician6~Music6
album 4^Musician7~Music7:Musician8~Music8
As I've mentioned, that $ cat musexc
#!/bin/bash
# Delete CDs from Library (version 1)
#
grep -v "$1" musics > /tmp/mus$$
mv -f /tmp/mus$$ musics
The first line sends the file
I used the file 'And that's it?' 'Yeah, man! Well, those programs we've made are quite basic, because we still lack knowledge about some tools. But, while I have another pint, you can practice using the examples, and I promise you will develop a nice control system for your CDs. Next time we meet, I'll show you how conditional commands work and we'll improve those scripts.' 'That's it for now... but before: Waiter, another round for me and my pal, please!' |
||||||||||||||||||||||||||||
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. |