You are here:
Wiki-SL
>
TWikiBar Web
>
TWikiBarTalk003
(30 Sep 2006,
JulioNeves
)
(raw view)
E
dit
A
ttach
---+!! Pub Talk Part III<!--pula duas linhas--> %TOC% 'Get me two pints waiter, I've got a lot to talk!' ---++ Working on chains 'No, I'm not going to get you on a hard work! I'm just going to talk about chains of characters.' ---+++ The cut command<!--pula duas linhas--> 'Let me show you first, a very practical instruction: the =cut= command. This instruction may be used to cut a certain piece of a file and it may be used in two different ways' ---++++ The cut command and the option -c 'With the option =-c=, the syntax of the command is the following:' <verbatim> cut -c PosIni-PosFim [file] </verbatim> 'In which:' <verbatim> PosIni = Initial Position PosFim = Final position </verbatim> %TERMINAL_INI% $ cat numbers %OUT_INI%1234567890 0987654321 1234554321 9876556789%OUT_FIM% $ cut -c1-5 numbers %OUT_INI%12345 09876 12345 98765%OUT_FIM% $ cut -c-6 numbers%OUT_INI% 123456 098765 123455 987655%OUT_FIM% $ cut -c4- numbers%OUT_INI% 4567890 7654321 4554321 6556789%OUT_FIM% $ cut -c1,3,5,7,9 numbers%OUT_INI% 13579 08642 13542 97568%OUT_FIM% $ cut -c -3,5,8- numbers%OUT_INI% 1235890 0986321 1235321 9875789%OUT_FIM% %TERMINAL_FIM% 'As you can see, there are four different syntaxes: at the first one (=-c 1-5=), I have especified a range, in the second one (=-c -6=), I have especified everything up to one position, in the third (=-c 4-=), from a certain point onward and in the fourth (=-c 1,3,5,7,9=), certain positions. The last one (=-c -3,5,8-=) was just to show that they can all be combined.' ---++++ The cut commandand the option -f 'Don't you think that it's finished. As you may have realized, this syntax is handful for fixed sized files, but actually, there are more files with variable sized fields, in which each field ends with a delimiting character. Let's take a look at the file =musics= that we started in our last meeting.' %TERMINAL_INI% $ cat musics%OUT_INI% album 1^Musician1~Music1:Musician2~Music2 album 2^Musician3~Music3:Musician4~Music4 album 3^Musician5~Music5:Musician6~Music5 album 4^Musician7~Music7:Musician8~Music8%OUT_FIM% %TERMINAL_FIM% 'So, the layout is the following one:' <verbatim> album^Musician1~music1:...:Musician~musicn </verbatim> 'That means that the name of the album is separated by a circumflex (or caret =^=) from the rest of the register. This register is made of several groups (composed by: the singer of each song and the song). The artist and the name of the song are separated by a tilde (=~=), and a colon (=:=) separates the name of the song and the name of the singer.' 'So, in order to cut the piece of information that refers to the the second songs of the file =musics=, we must do the following:' %TERMINAL_INI% $ cut -f2 -d: musics%OUT_INI% Musician2~Music2 Musician4~Music4 Musician6~Music5 Musician8~Music8%OUT_FIM% %TERMINAL_FIM% 'That means that we have cut the second field (=-f=) delimited (=-d=) with a colon (=:=). But if we just wanted the names of the interpreters we should have used a different syntax:' %TERMINAL_INI% $ cut -f2 -d: musics | cut -f1 -d~%OUT_INI% Musician2 Musician4 Musician6 Musician8%OUT_FIM% %TERMINAL_FIM% 'In order to understand it, let's use the first line of musics:' %TERMINAL_INI% $ head -1 musics%OUT_INI% album 1^Musician1~Music1:Musician2~Music2%OUT_FIM% %TERMINAL_FIM% 'Watch me now:' Delimitating the first =cut= (=:=) =%T1%album 1^Musician1~Music1%T0%:%T2%Musician2~Music2%T0%= 'This way, at the first =cut=, the first delimiting field (=-d=) colon (=:=) is %T1%album 1^Musician1~Music1%T0% and the second one, that is of our interest, is %T2%Musician2~Music2%T0%. ' 'Let's see then, what's happened to the second =cut=:' New delimitating character (=~=) =%T1%Musician2%T0%~%T2%Music2%T0%= 'Now the first field of the delimitating character (=-d=) tilde (=~=) is of our interest and it is %T1%Musician2%T0% and the second field is %T2%Music2%T0%.' 'Considering that our first assumption was applied to the rest of the file, we'll get that same answer.' ---+++ If you cut, you paste 'As you may guess, the paste command pastes things. When we are dealing with shell, nevertheless, we talk about pasting files. In order to understand it, let's see:' <verbatim> paste file1 file2 </verbatim> 'This way, the command will send the registers from =file1= and from =file1= to the standard output (stdout). The registers of both files will be arranged side by side and if you do not define a delimitating character, the default one =<TAB>= will be used.' 'Paste is a rarely used command because of its syntax (not that it is hard, it is not well known). Let's play with two files:' %TERMINAL_INI% $ seq 10 > integer $ seq 2 2 10 > even %TERMINAL_FIM% 'In order to check the content of the files, let's use the paste command in its more conventional way:' %TERMINAL_INI% $ paste integer even%OUT_INI% 1 2 2 4 3 6 4 8 5 10 6 7 8 9 10%OUT_FIM% %TERMINAL_FIM% ---++++ Laying down 'Let's convert the column into a line:' %TERMINAL_INI% $ paste -s even%OUT_INI% 2 4 6 8 10%OUT_FIM% %TERMINAL_FIM% ---++++ Using separators 'As we have said, =<TAB>= is the default separator, but it can be changed with the option =-d=. So, in order to calculate the sum, we would perform the following operation:' %TERMINAL_INI% $ paste -s -d'+' even # could be: -sd'+'%OUT_INI% 2+4+6+8+10%OUT_FIM% %TERMINAL_FIM% 'Afterwards, we would paste that line to the calculator (=bc=), then it would be like this:' %TERMINAL_INI% $ paste -sd'+' even | bc%OUT_INI% 30%OUT_FIM% %TERMINAL_FIM% 'So, the factorial of the number defined by =$Num= would be:' %TERMINAL_INI% $ seq $Num | paste -sd'*' | bc %TERMINAL_FIM% 'With the =paste= command, it is also possible to employ some 'exotic' formats, like the following:' %TERMINAL_INI% $ ls | paste -s -d'\t\t\n'%OUT_INI% file1 file2 file3 file4 file5 file6%OUT_FIM% %TERMINAL_FIM% 'What has just happened was: with the option =-s=, the =past= command converts lines into columns. The separators (oh, yeah! There might be more than one separator after each column that has been created) would be a =<TAB>=, another =<TAB>= and a =<ENTER>=. So that the output would be presented in three columns.' 'Now that you got it, check how the same thing can be done, but in an easier (and less strange) way, using the same command, but with a different syntax:' %TERMINAL_INI% $ ls | paste - - -%OUT_INI% file1 file2 file3 file4 file5 file6%OUT_FIM% %TERMINAL_FIM% 'That happens because when we use a minus (=-=), the =paste= command substitutes the files for the standard input (or output). In our last example, the data of the files was sent to the standard output (_stdout_), because the character _pipe_ (=|=), changed the route of the =ls= command to the standard input (_stdin_) of the =paste= command, but take a look at the following example:' %TERMINAL_INI% $ cat file1%OUT_INI% precedence privilegious proportional%OUT_FIM% $ cat file2%OUT_INI% position mary motion%OUT_FIM% $ cut -c-3 file1 | paste -d "" - file2%OUT_INI% preposition primary promotion%OUT_FIM% %TERMINAL_FIM% 'In that case, the =cut= command has returned the three first letters of each register of =file1=. The =paste= command was designed not to employ a separator (=-d""=) and to receive an input from the standard input (whose route has been changed by the pipe (=|=) at the dash (=-=), generating an output with =file2=.' ---+++ The tr command 'Another very interesting command is =tr=. It substitutes, compresses or removes characters. Its syntax follows the pattern:' <verbatim> tr [options] string1 [string2] </verbatim> 'The =tr= command copies the text from the standard input, changes the occurrences of the characters of =string1= by their correspondents in =string2= or changes multiple occurrences of the characters from =string1= for just one character, or it removes characters from =string1=.' The main =options= are: <center> %TABLE{ databg="#ffffff" headerrows="1" }% | *Main options of the tr command* || | *option* | *meaning* | | =-s n= | compresses =n= occurrences of the string into one | | =-d char= | removes the characters =char= from the string | </center> ---++++ Changing characters with tr 'Let'me show you a silly example first' %TERMINAL_INI% $ echo silly | tr i a%OUT_INI% sally%OUT_FIM% %TERMINAL_FIM% 'That means, I have changed the occurrences of =i= for =a=.' 'Suppose that at a certain point of my script, the operator is asked to press =y= or =n= (Yes or No), and its answer is stored at the variable =$Resp=. The content of that file could be capitalized or not, so, in order to avoid many tests to find out whether it is =N=, =n=, =Y=, =y=, I simply do the following:' %TERMINAL_INI% $ Resp=$(echo $Resp | tr YN yn) %TERMINAL_FIM% 'and afterwards, you can be sure that the content of the file will be whether a =n= or a =y=.' 'If my file =FileIn= is all written in small letters and I wish to convert them into capital letters, what can I do?' %TERMINAL_INI% $ tr A-Z a-z < FileIn > /tmp/$$ $ mv -f /tmp/$$ ArqEnt %TERMINAL_FIM% 'Take a look: I have used the notation =A-Z= so that I would not need to write =ABCDEF....YZ=. Other notations that could be used were those we call _escape sequences_ (which are common to other languages, like C) whose meaning you'll see below:' <center> %TABLE{ databg="#ffffff" headerrows="1" }% | *Escape Sequences* ||| | *Sequence* | *Meaning* | *Octal* | | \t | Tab | \011 | | \n | New line <ENTER> | \012 | | \v | Vertical Tab | \013 | | \f | Form Feed | \014 | | \r | Carriage Return <^M> | \015 | | \\ | Inverted Dash | \0134 | </center> ---++++ Removing characters with tr 'Let-me tell you a tale: a student was quite mad at me, so he decided to make things worse for me and in a practical exercise, he handed me in a script in which the commands were separated by a semicolon (do you remember I said that semicolon is used to write many commands at the same line?).' 'I'll show you an example of such an aberration:' %TERMINAL_INI% $ cat confusion%OUT_INI% echo Read an online shell book at <noautolink>http://www.julioneves.com</noautolink> > book;cat book;pwd;ls;rm -f trash 2>/dev/null;cd ~%OUT_FIM% %TERMINAL_FIM% 'When the script was run, the answer was:' %TERMINAL_INI% $ confusion%OUT_INI% Read an online shell book at <noautolink>http://www.julioneves.com</noautolink> /home/jneves/LM confusion book musexc musics musinc muslist number%OUT_FIM% %TERMINAL_FIM% 'But, since I was meant to grade the script, I had to evaluate it seriously, so, to understand what he has done, I called him and in front of him, I ran the following command:' %TERMINAL_INI% $ tr ";" "\n" < confusion%OUT_INI% echo Read an online shell book at <noautolink>http://www.julioneves.com</noautolink> pwd ls rm -f trash 2>/dev/null%OUT_FIM% cd ~ %TERMINAL_FIM% 'I don't have to tell you how disapointed he got when I, in a few seconds, undid the joke he had spent hours doing.'%BR% 'But, pay attention! If I were using a Unix system (with =ksh= ou =sh=), the command should be:' %TERMINAL_INI% $ tr ";" "\012" < confusion %TERMINAL_FIM% ---++++ Shrinking with tr 'See the difference between two executions of the date command (one I ran today and the other I ran two weeks ago):' %TERMINAL_INI% $ date # Today%OUT_INI% Sun Sep 19 14:59:54 2004%OUT_FIM% $ date # Two weeks ago%OUT_INI% Sun Sep 5 10:12:33 2004%OUT_FIM% %TERMINAL_FIM% 'If I wanted to isolate the hour, I should do the following:' %TERMINAL_INI% $ date | cut -f 4 -d ' '%OUT_INI% 14:59:54%OUT_FIM% %TERMINAL_FIM% 'On the other hand, two weeks ago, the answer would be:' %TERMINAL_INI% $ date | cut -f 4 -d ' '%OUT_INI% 5%OUT_FIM% %TERMINAL_FIM% 'But pay attention to the following detail:' %TERMINAL_INI% $ date # Two weeks ago%OUT_INI% Sun Sep 5 10:12:33 2004%OUT_FIM% %TERMINAL_FIM% 'As you can see, there are two blank spaces before the number =5= (day). That ruins it all, because the third part is empty and the fourth is the day (=5=). The ideal would be to compress the sucessive blank spaces into just one in order to work with the two strings. See how you can do it:' %TERMINAL_INI% $ date | tr -s " "%OUT_INI% Sun Sep 5 10:12:33 2004%OUT_FIM% %TERMINAL_FIM% 'You can see there is no more two spaces Now I can cut it:' %TERMINAL_INI% $ date | tr -s " " | cut -f 4 -d " "%OUT_INI% 10:12:33%OUT_FIM% %TERMINAL_FIM% 'See how shell can be handful? Now, take a look at the following file, that originally came from that operational system that is vulnerable to all sorts of virus.' <noautolink> %TERMINAL_INI% $ cat -ve FileFromDOS.txt%OUT_INI% This file^M$ was recorded by^M$ the Windows and^M$ downloaded by^M$ a badly done ftp.^M$%OUT_FIM% %TERMINAL_FIM% </noautolink> 'Let-me give you two tips:' %TIP_INI% *Tip #1* - The option =-v= of the cat command shows the invisible control characters, with the notation =^L=, in which =^= stands for the control key and =L= stands for the corresponding letter. The option =-e= shows the end of the line with a dolar sign (=$=). %TIP_FIM% %TIP_INI% *Tip #2* - That happens because in Windows (or DOS) formated files, there is a carriage-return (=\r=) and a line-feed (=\n=) at the end of the registers. In Linux formated files, on the other hand, there is only a line-feed at the end of the registers. %TIP_FIM% 'Let's clean the file now' <noautolink> %TERMINAL_INI% $ tr -d '\r' < FileFromDOS.txt > /tmp/$$ $ mv -f /tmp/$$ FileFromDOS.txt %TERMINAL_FIM% </noautolink> 'Check now what's happened:' <noautolink> %TERMINAL_INI% $ cat -ve FileFromDOS.txt%OUT_INI% This file$ was recorded by$ the Windows and$ downloaded by$ a badly done ftp.$%OUT_FIM% %TERMINAL_FIM% </noautolink> 'The option =-d= of the =tr= command removes a character (the one that has been specified) from the whole file. Thus, I have removed the unwishful characters saving the text in a temporary file (that afterwards became the substitute of the original file).'%BR% If I were using a Unix machine (with =ksh= ou =sh=), the command should be: <noautolink> %TERMINAL_INI% $ tr -d '\015' < FileFromDOS.txt > /tmp/$$ $ mv -f /tmp/$$ FileFromDOS.txt %TERMINAL_FIM% </noautolink> %ATTENTION_INI% That has happened because ftp was run on binary mode (or image), and it means: no text interpretation. If, before the file transmission, the option ascii had been defined, that wouldn't have happened. %ATTENTION_FIM% 'Well, those hints are making me enjoy this shell stuff, but there are many things I still can't do.' 'Nevermind! There are still many things for you to learn about shell programming. But you are ready to solve a lot of problems using what you've learn as long as you adopt a "shell way of thinking". Are you able to make a script that tells me who's been logged in for more than one day at your server?' 'Surely not!! I would have to use conditional commands that I still don't know.' 'Why don't you change a little bit your way of thinking and come to the shell side of the force? Waiter, my pal, bring us some pints before we proceed... 'Now, that we have our pints, let's solve that problem. Pay attention to the who command:' %TERMINAL_INI% $ who%OUT_INI% jneves pts/1 Sep 18 13:40 rtorres pts/0 Sep 20 07:01 rlegaria pts/1 Sep 20 08:19 lcarlos pts/3 Sep 20 10:01%OUT_FIM% %TERMINAL_FIM% 'And also to the =date= command ' %TERMINAL_INI% $ date%OUT_INI% Mon Sep 20 10:47:19 BRT 2004%OUT_FIM% %TERMINAL_FIM% 'Now look: month and day are presented in the same format by both commands.' %TIP_INI% Sometimes different commands present outputs in different languages. When that happens, you can do the following: %TERMINAL_INI% $ date%OUT_INI% Mon Sep 20 10:47:19 BRT 2004%OUT_FIM% $ LANG=pt_BR date%OUT_INI% Seg Set 20 10:47:19 BRT 2004%OUT_FIM% %TERMINAL_FIM% This way, you can print a bit of uniformity to the languages employed (The original language of this URL is portuguese from Brazil). %TIP_FIM% 'Well, if there is a register of =who= in which we don't find today's date, that means the user has been logged in for more than one day (considering that the user can't be logged in since tomorrow)... So, let's save the piece of data that is of our interest.' %TERMINAL_INI% $ Data=$(date | cut -c 5-10) %TERMINAL_FIM% 'I have used the construction =$(...)=, in order to priorize the execution of the commands before attributing its output to the variable =$Data=. Let's see how it works:' %TERMINAL_INI% $ echo $Data%OUT_INI% Sep 20%OUT_FIM% %TERMINAL_FIM% 'Sweet! Now, what we should do, is to look for the registers that do not present that day in the output of the =who= command.' 'I see! Well, and since you've mentioned the action of searching, I'm thinking of =grep=. Am I right?' 'That is RIGHT! Very good! But I need to use =grep= with that option that makes it list just the registers in which there is *not* the string. Any idea?' 'Well, yeah... hummm... is it =-v=?' 'In fact, it IS! You're getting good at it! So let's see:' %TERMINAL_INI% $ who | grep -v "$Data"%OUT_INI% jneves pts/1 Sep 18 13:40%OUT_FIM% %TERMINAL_FIM% 'And if I wanted something a little prettier, I would do the following:' %TERMINAL_INI% $ who | grep -v "$Data" | cut -f1 -d ' '%OUT_INI% jneves%OUT_FIM% %TERMINAL_FIM% 'See? No conditional was necessary. Specially when we consider that our conditional (=if=) does not test conditions, but instructions, as we shall see.' ---++ Conditional Commands 'Check the lines below:' <noautolink> %TERMINAL_INI% $ ls musics%OUT_INI% musics%OUT_FIM% $ echo $?%OUT_INI% 0%OUT_FIM% $ ls FileThatDontExists%OUT_INI% ls: FileThatDontExists: No such file or directory%OUT_FIM% $ echo $?%OUT_INI% 1%OUT_FIM% $ who | grep jneves%OUT_INI% jneves pts/1 Sep 18 13:40 (10.2.4.144)%OUT_FIM% $ echo $?%OUT_INI% 0%OUT_FIM% $ who | grep juliana%OUT_INI% $ echo $?%OUT_FIM% 1 %TERMINAL_FIM% </noautolink> 'What that =$?= does? It looks like a variable, is it?' 'Yes, it is a variable that contains the returning code of the last instruction run. I can assure you that if this instruction succeeded, =$?= equals zero, otherwise, it will be different.' ---+++ The if command 'The if command tests the variable =$?=. Its syntax is:' <verbatim> if cmd then cmd1 cmd2 ... cmdn else cmd3 cmd4 ... cmdm fi </verbatim> 'That means: considering that the =cmd= command has been successfully executed, the commands that compose the set called =then= (=cmd1=, =cmd2=, =...= & =cmdn=) will be executed. Otherwise, the optional set of commands =else= (composed by the =cmd3=, =cmd4=, =...= & =cmdm= commands), will be executed. The execution will be finished with a =fi=.' 'Let's see how it works, using a small script that includes users at =/etc/passwd=:' %TERMINAL_INI% $ cat incusu%OUT_INI% #!/bin/bash # Version 1 if grep ^$1 /etc/passwd then echo User \'$1\' already exists else if useradd $1 then echo User \'$1\' included at /etc/passwd else echo "We have problems. Are you root?" fi fi%OUT_FIM% %TERMINAL_FIM% 'Notice that the =if= command tests the =grep= command (that's its purpose). If the =if= command succeeds (in the case above, that means: if the user - whose name is in =$1= - is found at =/etc/passwd=) the =then= set of commands is executed (in this example, only the =echo= command). Otherwise, the instructions of the =else= set are executed, where new =if= tests whether the =useradd= command works including the user =$1= in =/etc/passwd= or not, in this case an error message is exhibited asking if the guy is root.' 'Let's check the command, firstly trying to execute it with a pre existent user:' %TERMINAL_INI% $ incusu jneves%OUT_INI% jneves:x:54002:1001:Julio Neves:/home/jneves:/bin/bash User 'jneves' already exists%OUT_FIM% %TERMINAL_FIM% 'As we've seen a few times, an undesirable line was added by the output of the grep command. In order to avoid that problem, we should desviate the output of that command to /dev/null, like this:' %TERMINAL_INI% $ cat incusu%OUT_INI% #!/bin/bash # Version 2 if grep ^$1 /etc/passwd > /dev/null # or: if grep -q ^$1 /etc/passwd then echo User \'$1\' already exists else if useradd $1 then echo User \'$1\' included at /etc/passwd else echo "We have problems. Are you root?" fi fi%OUT_FIM% %TERMINAL_FIM% 'Now, let a normal user (not the root) test it:' <noautolink> %TERMINAL_INI% $ incusu JohnNobody%OUT_INI% ./incusu[6]: useradd: not found We have problems. Are you root?%OUT_FIM% %TERMINAL_FIM% </noautolink> 'Wow... that error was not supposed to occur! In order to avoid it, let's desviate the =useradd= error output to =/dev/null=, like this:' %TERMINAL_INI% $ cat incusu%OUT_INI% #!/bin/bash # Version 3 if grep ^$1 /etc/passwd > /dev/null # or: if grep -q ^$1 /etc/passwd then echo User \'$1\' already exists else if useradd $1 2> /dev/null then echo User \'$1\' included at /etc/passwd else echo "We have problems. Are you root?" fi fi%OUT_FIM% %TERMINAL_FIM% 'After doing those changes, and executing a =su -= (becoming root), let's see how it works:' %TERMINAL_INI% $ incusu xalaskero%OUT_INI% User 'xalaskero' included at /etc/passwd%OUT_FIM% %TERMINAL_FIM% 'Once again:' %TERMINAL_INI% $ incusu xalaskero%OUT_INI% User 'xalaskero' already exists%OUT_FIM% %TERMINAL_FIM% 'See? As I told you, as long as we talk and drink, our programming skills are improving. Let's see how we can enhance our music software:' %TERMINAL_INI% $ cat musinc%OUT_INI% #!/bin/bash # Include Musics (version 3) # if grep "^$1$" musicas > /dev/null then echo This album is already registered else echo $1 >> musics sort musics -o musics fi%OUT_FIM% %TERMINAL_FIM% 'It's an evolution of the previous version, see? Instead of including a register (that could be duplicated in the previous version), we now test if the begining (=^=) and the end (=$=) of a register match to the informed parameter (=$1=). A =^= is used at the begining of the string and a =$= is used at the end of it in order to test whether the parameter informed equals to some previously registered data.' 'Let's run it now, informing a previously registered album' %TERMINAL_INI% $ musinc "album 4^Musician7~Music7:Musician8~Music8"%OUT_INI% This album is already registered%OUT_FIM% %TERMINAL_FIM% 'And now a non registered one: ' %TERMINAL_INI% $ musinc "album 5^Musician9~Music9:Musician10~Music10" $ cat musicas%OUT_INI% album 1^Musician1~Music1:Musician2~Music2 album 2^Musician3~Music3:Musician4~Music4 album 3^Musician5~Music5:Musician6~Music5 album 4^Musician7~Music7:Musician8~Music8 album 5^Musician9~Music9:Musician10~Music10%OUT_FIM% %TERMINAL_FIM% 'As you've seen, our software is slowly improving, and it will get even better as long as we pass through these shell classes.' 'I've got all that you said, but I still don't get how I can do an if in order to test conditions, which I think that would be the main function of the command.' 'Dude, that's what the test command is for: to test conditions. The if command, on the other hand, tests the test command. Nevertheless, talking about it now would be way too complicated, moreover, I'm really thirsty. Let's have some beer and the next time I'll tell you about test and other if syntaxes.' 'Deal! Specially because I'm getting dizzy with that amount of information and it will give me some time to practice.' 'Why don't you write a little script that informs whether an user is logged on or not?? Meanwhile: WAITER?? two more pints, please...' -- Main.JulioNeves - 01 Aug 2006
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r6
<
r5
<
r4
<
r3
<
r2
|
B
acklinks
|
V
iew topic
|
M
ore topic actions
Topic revision: r6 - 30 Sep 2006 - 19:23:27 -
JulioNeves
TWikiBar.TWikiBarTalk003 moved from TWikiBar.TWikiBarPapo014 on 30 Sep 2006 - 19:23 by
JulioNeves
-
put it back
TWikiBar
Página Inicial
Últimas alterações
Índice
Procurar
Estatísticas de Uso
Aviso de Atualização
Configurações Gerais
Projeto Gráfico
Mapa do Site
Quem Somos
Registre-se
?
Regras de Formatação
Biblioteca Gráfica
?
Carinhas Gráficas
Webs Wiki-SL
Amadeu
Anapolivre
ArquivoLivre
Arte
BahiaSocial
BeaBa
BibliotecaLivre
Blogs
BrasilDigital
BrasilELivre
BSM
Ccsa
CESL
CoberturaWiki
Cooperativas
Curriculo
DarvinMarosin
DiaD
Dinamicoop
Economia
EconomiaSolidaria
EducacaoLivre
Ekaaty
Emacsbr
ENSL
Fatos
Festival3
Festival4
Flisol
Fmpb
Formatos
Foswikibr
FSM2005
GNOMEBR
GTTemario2004
GTWeb
Guialivre
HDC
Incubus
InkscapeBrasil
Jogos
KdeBR
KSP
LGM
LinuxStokDoc
Livros
Main
Mentores
MHHOB
MinuanoDigital
MoradiaECidadania
OlhosDagua
Olimpo
OLPC
OOPTQ
Papers
PCLivre
PentahoBrasil
Pessoas
Portal
Prefeituras
PSLAL
PSLBA
PSLBancarios
PSLBrasil
PSLGO
PSLMA
PSLMG
PSLMIP
PSLMT
PSLMulheres
PSLPI
PubFisl10
PubFisl7
PubFisl8
PubFisl9
QuilomboDoSopapo
RadioSL
RedeMesh
RedePopular
RobotWars
Sandbox
Saudelivre
Scribus
Sementes
Shakya
SLRJ
SoftwareLivreIrece
SoftwareLivreVS
SoLiSC
SuporteLivre
System
Telecentros
TeseSA
TextoLivre
TV
TWikiBar
TWikiPtbr
UNELivre
UNIMIX
VilaTorres
WebNordeste
WTRD2004
Este Menu
?skin=free
English
Español
Português brasileiro
Copyright © 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