You are here:
Wiki-SL
>
TWikiBar Web
>
BatePapos
>
TWikiBarPapo004
(01 Aug 2009,
BrSalgado
)
(raw view)
E
dit
A
ttach
---+!!Papo de Botequim Parte IV %TOC% - E aí cara, tentou fazer o exercício que te pedi para revigorar as idéias? - Claro, que sim! Em programação, se você não treinar, não aprende. Você me pediu para fazer um _scriptizinho_ para informar se um determinado usuário, que será passado como parâmetro esta logado (arghh!) ou não. Eu fiz o seguinte: %TERMINAL_INI% $ cat logado%OUT_INI% #!/bin/bash # Pesquisa se uma pessoa está logada ou não if who | grep $1 then echo $1 está logado else echo $1 não se encontra no pedaço fi%OUT_FIM% %TERMINAL_FIM% - Calma rapaz! Já vi que você chegou cheio de tesão, primeiro vamos pedir os nossos chopes de praxe e depois vamos ao _Shell_. Chico traz dois chopes, um sem colarinho! - Agora que já molhamos os nossos bicos, vamos dar uma olhadinha na execução do seu bacalho: %TERMINAL_INI% $ logado jneves%OUT_INI% jneves pts/0 Oct 18 12:02 (10.2.4.144) jneves está logado%OUT_FIM% %TERMINAL_FIM% Realmente funcionou. Passei o meu _login_ como parâmetro e ele disse que eu estava logado, porém ele mandou uma linha que eu não pedi. Esta linha é a saída do comando =who=, e para evitar que isso aconteça é só mandá-la para o buraco negro que a esta altura você já sabe que é o =/dev/null=. Vejamos então como ficaria: %TERMINAL_INI% $ cat logado%OUT_INI% #!/bin/bash # Pesquisa se uma pessoa está logada ou não (versão 2) if who | grep $1 > /dev/null then echo $1 está logado else echo $1 não se encontra no pedaço fi%OUT_FIM% %TERMINAL_FIM% Agora vamos aos testes: %TERMINAL_INI% $ logado jneves%OUT_INI% jneves está logado $ logado chico chico não se encontra no pedaço%OUT_FIM% %TERMINAL_FIM% %ATENCAO_INI% Ah, agora sim! Lembre-se desta pegadinha, a maior parte dos comandos tem uma saída padrão e uma saída de erros (o =grep= é uma das poucos exceções, já que não dá mensagem de erro quando não acha uma cadeia) e é necessário estarmos atentos para redirecioná-las para o buraco negro quando necessário. %ATENCAO_FIM% Bem, agora vamos mudar de assunto: na última vez que nos encontramos aqui no Botequim, eu estava te mostrando os comandos condicionais e, quando já estávamos de goela seca falando sobre o if, você me perguntou como se testa condições. Vejamos então o ---++ O Comando test Bem, todos estamos acostumados a usar o =if= testando condições, e estas são sempre, maior, menor, maior ou igual, menor ou igual, igual e diferente. Bem, em _Shell_ para testar condições, usamos o comando =test=, só que ele é muito mais poderoso que o que estamos habituados. Primeiramente vou te mostrar as principais opções (existem muitas outras) para testarmos arquivos em disco: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Opções do Comando test para arquivos* || | *Opção* | *Verdadeiro se:* | | =-e arq= | =arq= existe | | =-s arq= | =arq= existe e tem tamanho maior que zero | | =-f arq= | =arq= existe e é um arquivo regular | | =-d arq= | =arq= existe e é um diretório; | | =-r arq= | =arq= existe e com direito de leitura | | =-w arq= | =arq= existe e com direito de escrita | | =-x arq= | =arq= existe e com direito de execução | </center> Veja agora as principais opções para teste de cadeias de caracteres: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Opções do comando test para cadeias de caracteres* || | *Opção* | *Verdadeiro se:* | | =-z cadeia= | Tamanho de =cadeia= é zero | | =-n cadeia= | Tamanho de =cadeia= é maior que zero | | =cadeia= | A cadeia =cadeia= tem tamanho maior que zero | | =c1 = c2= | Cadeia =c1= e =c2= são idênticas | </center> E pensa que acabou? Engano seu! Agora é que vem o que você está mais acostumado, ou seja as famosas comparações com numéricos. Veja a tabela: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Opções do comando test para números* ||| | *Opção* | *Verdadeiro se:* | *Significado* | | =n1 -eq n2= | =n1= e =n2= são iguais | equal | | =n1 -ne n2= | =n1= e =n2= não são iguais | not equal | | =n1 -gt n2= | =n1= é maior que =n2= | greater than | | =n1 -ge n2= | =n1= é maior ou igual a =n2= | greater or equal | | =n1 -lt n2= | =n1= é menor que =n2= | less than | | =n1 -le n2= | =n1= é menor ou igual a =n2= | less or equal | </center> Além de tudo, some-se a estas opções as seguintes facilidades: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Operadores* || | *Operador* | *Finalidade* | | Parênteses =( )= | Agrupar | | Exclamação =!= | Negar | | =-a= | =E= lógico | | =-o= | =OU= lógico | </center> Ufa! Como você viu tem coisa prá chuchu, e como eu te disse no início, o nosso =if= é muito mais poderoso que o dos outros. Vamos ver em uns exemplos como isso tudo funciona, primeiramente testaremos a existência de um diretório: Exemplos: <verbatim> if test -d lmb then cd lmb else mkdir lmb cd lmb fi </verbatim> No exemplo, testei se existia um diretório =lmb= definido, caso negativo (=else=), ele seria criado. Já sei, você vai criticar a minha lógica dizendo que o _script_ não está otimizado. Eu sei, mas queria que você o entendesse assim, para então poder usar o ponto-de-espantação (=!=) como um negador do =test=. Veja só: <verbatim> if test ! -d lmb then mkdir lmb fi cd lmb </verbatim> Desta forma o diretório =lmb= seria criado somente se ele ainda não existisse, e esta negativa deve-se ao ponto-de-exclamação (=!=) precedendo a opção =-d=. Ao fim da execução deste fragmento de _script_, o programa estaria com certeza dentro do diretório =lmb=. Vamos ver dois exemplos para entender a diferença comparação entre números e entre cadeias. <verbatim> cad1=1 cad2=01 if test $cad1 = $cad2 then echo As variáveis são iguais. else echo As variáveis são diferentes. fi </verbatim> Executando o fragmento de programa acima vem: =As variáveis são diferentes.= Vamos agora alterá-lo um pouco para que a comparação seja numérica: <verbatim> cad1=1 cad2=01 if test $cad1 -eq $cad2 then echo As variáveis são iguais. else echo As variáveis são diferentes. fi </verbatim> E vamos executá-lo novamente: =As variáveis são iguais.= Como você viu nas duas execuções obtive resultados diferentes porque a cadeia =01= é realmente diferente da cadeia =1=, porém, a coisa muda quando as variáveis são testadas numericamente, já que o número =1= é igual ao número =01=. Exemplos: Para mostrar o uso dos conectores =-o= (=OU=) e =-a= (=E=), veja um exemplo animal feito direto no _prompt_ (me desculpem os zoólogos, mas eu não entendendo nada de reino, filo, classe, ordem, família, gênero e espécie, desta forma o que estou chamando de família ou de gênero tem grande chance de estar incorreto): %TERMINAL_INI% $ Familia=felinae $ Genero=gato $ if test $Familia = canidea -a $Genero = lobo -o $Familia = felina -a $Genero = leão > then > echo Cuidado > else > echo Pode passar a mão > fi%OUT_INI% Pode passar a mão%OUT_FIM% %TERMINAL_FIM% Neste exemplo caso o animal fosse da família canídea =E= (=-a=) do gênero lobo, =OU= (=-o=) da familia felina =E= (=-a=) do gênero leão, seria dado um alerta, caso contrário a mensagem seria de incentivo. %DICA_INI% Os sinais de maior (=>=) no início das linhas internas ao =if= são os _prompts_ de continuação (que estão definidos na variável =$PS2=) e quando o _Shell_ identifica que um comando continuará na linha seguinte, automaticamente ele o coloca até que o comando seja encerrado. %DICA_FIM% Vamos mudar o exemplo para ver se continua funcionando: %TERMINAL_INI% $ Familia=felino $ Genero=gato $ if test $Familia = felino -o $Familia = canideo -a $Genero = onça -o $Genero = lobo > then > echo Cuidado > else > echo Pode passar a mão > fi%OUT_INI% Cuidado%OUT_FIM% %TERMINAL_FIM% Obviamente a operação redundou em erro, isto foi porque a opção =-a= tem precedência sobre a =-o=, e desta forma o que primeiro foi avaliado foi a expressão: =$Familia = canideo -a $Genero = onça= Que foi avaliada como falsa, retornando o seguinte: =$Familia = felino -o FALSO -o $Genero = lobo= Que resolvida vem: =VERDADEIRO -o FALSO -o FALSO= Como agora todos conectores são =-o=, e para que uma série de expressões conectadas entre si por diversos =OU= lógicos seja verdadeira, basta que uma delas seja, a expressão final resultou como =VERDADEIRO= e o =then= foi executado de forma errada. Para que isso volte a funcionar façamos o seguinte: %TERMINAL_INI% $ if test \($Familia = felino -o $Familia = canideo\) -a \($Genero = onça -o $Genero = lobo\) > then > echo Cuidado > else > echo Pode passar a mão > fi%OUT_INI% Pode passar a mão%OUT_FIM% %TERMINAL_FIM% Desta forma, com o uso dos parênteses agrupamos as expressões com o conector =-o=, priorizando as suas execuções e resultando: =VERDADEIRO -a FALSO= Para que seja =VERDADEIRO= o resultado duas expressões ligadas pelo conector =-a= é necessário que ambas sejam verdadeiras, o que não é o caso do exemplo acima. Assim o resultado final foi =FALSO= sendo então o =else= corretamente executado. Se quisermos escolher um CD que tenha faixas de 2 artistas diferentes, nos sentimos tentados a usar um =if= com o conector =-a=, mas é sempre bom lembrarmos que o _bash_ nos dá muito recursos, e isso poderia ser feito de forma muito mais simples com um único comando =grep=, da seguinte maneira: %TERMINAL_INI% $ grep Artista1 musicas | grep Artista2 %TERMINAL_FIM% Da mesma forma para escolhermos CDs que tenham a participação do =Artista1= e do =Artista2=, não é necessário montarmos um if com o conector =-o=. O =egrep= (ou =grep -E=, sendo este mais aconselhável) também resolve isso para nós. Veja como: %TERMINAL_INI% $ egrep (Artista1|Artista2) musicas %TERMINAL_FIM% Ou (nesse caso específico) o próprio =grep= puro e simples poderia nos quebrar o galho: %TERMINAL_INI% $ grep Artista[12] musicas %TERMINAL_FIM% No =egrep= acima, foi usada uma expressão regular, onde a barra vertical (=|=) trabalha como um =OU= lógico e os parênteses são usados para limitar a amplitude deste =OU=. Já no =grep= da linha seguinte, a palavra =Artista= deve ser seguida por um dos valores da lista formada pelos colchetes (=[ ]=), isto é, =1= ou =2=. - Tá legal, eu aceito o argumento, o =if= do _Shell_ é muito mais poderoso que os outros caretas, mas cá pra nós, essa construção de =if test ...= é muito esquisita, é pouco legível. - É você tem razão, eu também não gosto disso e acho que ninguém gosta. Acho que foi por isso, que o _Shell_ incorporou outra sintaxe que substitui o comando =test=. Exemplos: Para isso vamos pegar aquele exemplo para fazer uma troca de diretórios, que era assim: <verbatim> if test ! -d lmb then mkdir lmb fi cd lmb </verbatim> e utilizando a nova sintaxe, vamos fazê-lo assim: <verbatim> if [ ! -d lmb ] then mkdir lmb fi cd lmb </verbatim> Ou seja, o comando =test= pode ser substituído por um par de colchetes (=[ ]=), separados por espaços em branco dos argumentos, o que aumentará enormemente a legibilidade, pois o comando =if= irá ficar com a sintaxe semelhante à das outras linguagens e por isso este será o modo que o comando =test= será usado daqui para a frente. ---++Querida, Encolheram o Comando Condicional Se você pensa que acabou, está muito enganado. Repare a tabela (tabela verdade) a seguir: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Valores Booleanos* | *E* | *OU* | | VERDADEIRO-VERDADEIRO | VERDADEIRO | VERDADEIRO | | VERDADEIRO-FALSO | FALSO | VERDADEIRO | | FALSO-VERDADEIRO | FALSO | VERDADEIRO | | FALSO-FALSO | FALSO | FALSO | </center> Ou seja, quando o conector é =E= e a primeira condição é verdadeira, o resultado final pode ser =VERDADEIRO= ou =FALSO=, dependendo da segunda condição, já no conector =OU=, caso a primeira condição seja verdadeira, o resultado sempre será =VERDADEIRO= e se a primeira for falsa, o resultado dependerá da segunda condição. Ora, os caras que desenvolveram o interpretador não são bobos e estão sempre tentando otimizar ao máximo os algoritmos. Portanto, no caso do conector =E=, a segunda condição não será avaliada, caso a primeira seja falsa, já que o resultado será sempre =FALSO=. Já com o =OU=, a segunda será executada somente caso a primeira seja falsa. Aproveitando disso, criaram uma forma abreviada de fazer testes. Batizaram o conector =E= de =&&= e o =OU= de =||= e para ver como isso funciona, vamos usá-los como teste no nosso velho exemplo de trocarmos de diretório, que em sua última versão estava assim: <verbatim> if [ ! -d lmb ] then mkdir lmb fi cd lmb </verbatim> Isso também poderia ser escrito da seguinte maneira: <verbatim> [ ! -d lmb ] && mkdir lmb cd lmb </verbatim> Ou ainda retirando a negação (=!=): <verbatim> [ -d lmb ] || mkdir lmb cd lmb </verbatim> No primeiro caso, se o primeiro comando (o =test= que está representado pelos colchetes) for bem sucedido, isto é, não existir o diretório =lmb=, o =mkdir= será efetuado porque a primeira condição era verdadeira e o conector era =E=. No exemplo seguinte, testamos se o diretório =lmb= existia (no anterior testamos se ele não existia) e caso isso fosse verdade, o =mkdir= não seria executado porque o conector era =OU=. Outra forma: =cd lmb || mkdir lmb= Neste caso, se o =cd= fosse mal sucedido, seria criado o diretório =lmb= mas não seria feito o =cd= para dentro dele. Para executarmos mais de um comando desta forma, é necessário fazermos um grupamento de comandos, e isso se consegue com o uso de chaves (={ }=). Veja como seria o correto: <verbatim> cd lmb || { mkdir lmb cd lmb } </verbatim> Ainda não está legal, porque caso o diretório não exista, o =cd= dará a mensagem de erro correspondente. Então devemos fazer: <verbatim> cd lmb 2> /dev/null || { mkdir lmb cd lmb } </verbatim> Como você viu o comando =if= nos permitiu fazer um =cd= seguro de diversas maneiras. É sempre bom lembrarmos que o seguro a que me referi é no tocante ao fato de que ao final da execução você sempre estará dentro de =lmb=, desde que você tenha permissão entrar em =lmb=, permissão para criar um diretório em =../lmb=, haja espaço em disco, ... ---++ E tome de test Ufa! Você pensa que acabou? Ledo engano! Ainda tem uma forma de =test= a mais. Essa é legal porque ela te permite usar padrões para comparação. Estes padrões atendem às normas de Geração de Nome de Arquivos (_File Name Generation_, que são ligeiramente parecidas com as Expressões Regulares, mas não podem ser confundidas com estas). A diferença de sintaxe deste para o =test= que acabamos de ver é que esse trabalha com dois pares de colchete da seguinte forma: =[[ expressão ]]= Onde =expressão= é uma das que constam na tabela a seguir: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Expressões Condicionais Para Padrões* || | *Expressão* | *Retorna* | | =cadeia == padrão= %BR% =cadeia1 = padrao= | Verdadeiro se =cadeia1= casa com =padrão= | | =cadeia1 != padrao= | Verdadeiro se =cadeia1= não casa com =padrao=. | | =cadeia1 < cadeia1= | Verdadeiro se =cadeia1= vem antes de =cadeia1= alfabeticamente. | | =cadeia1 > cadeia1= | Verdadeiro se =cadeia1= vem depois de =cadeia1= alfabeticamente | | =expr1 && expr2= | "E" lógico, verdadeiro se ambos =expr1= e =expr2= são verdadeiros | | =expr1 ¦¦ expr2= | "OU" lógico, verdadeiro se =expr1= ou =expr2= for verdadeiro | </center> %TERMINAL_INI% $ echo $H%OUT_INI% 13%OUT_FIM% $ [[ $H !== [0-9] || $H !== 1[0-2] ]] || echo Hora inválida%OUT_INI% Hora inválida%OUT_FIM% $H=12 $ [[ $H !== [0-9] || $H !== 1[0-2] ]] || echo Hora inválida $ %TERMINAL_FIM% Neste exemplo, testamos se o conteúdo da variável =$H= estava compreendido entre zero e nove =([0-9])= ou =(||)= se estava entre dez e doze =(1[0-2])=, dando uma mensagem de erro caso não fosse. Exemplos: Para saber se uma variável tem o tamanho de um e somente um caractere, faça: %TERMINAL_INI% $ var=a $ [<nop>[ $var !== ? ]] && echo var tem um caractere%OUT_INI% var tem um caractere%OUT_FIM% $ var=aa $ [[ $var !== ? ]<nop>] && echo var tem um caractere $ %TERMINAL_FIM% Como você pode imaginar, este uso de padrões para comparação, aumenta muito o poderio do comando =test=. No início deste papo, antes do último chope, afirmamos que o comando =if= do interpretador _Shell_ é mais poderoso que o seu similar em outras linguagens. Agora que conhecemos todo o seu espectro de funções, diga-me: você concorda ou não com esta assertiva? ---++Acaso Casa com case Vejamos um exemplo didático: dependendo do valor da variável =$opc= o _script_ deverá executar uma uma das opções: inclusão, exclusão, alteração ou fim. Veja como ficaria este fragmento de _script_: <verbatim> if [ $opc -eq 1 ] then inclusao elif [ $opc -eq 2 ] then exclusao elif [ $opc -eq 3 ] then alteracao elif [ $opc -eq 4 ] then exit else echo Digite uma opção entre 1 e 4 fi </verbatim> Neste exemplo você viu o uso do =elif= com um =else if=, esta á a sintaxe válida e aceita, mas poderíamos fazer melhor, e isto seria com o comando =case=, que tem a sintaxe a seguir: <verbatim> case $var in padrao1) cmd1 cmd2 cmdn ;; padrao2) cmd1 cmd2 cmdn ;; padraon) cmd1 cmd2 cmdn ;; esac </verbatim> Onde a variável =$var= é comparada aos padrões =padrao1, ..., padraon= e caso um deles atenda, o bloco de comandos =cmd1, ..., cmdn= correspondente é executado até encontrar um duplo ponto-e-vírgula (=;;=), quando o fluxo do programa se desviará para instrução imediatamente após o =esac=. Na formação dos padrões, são aceitos os seguintes caracteres: <center> %TABLE{ sort="off" tableborder="0" cellpadding="4" cellspacing="1" headerbg="#0000FF" headercolor="#FFFF00" databg="#BBBBBB,#DDDDDD" headerrows="2" footerrows="1" }% | *Caracteres Para Formação de Padrões* || | *Caractere* | *Significado* | | =*= | Qualquer caractere ocorrendo zero ou mais vezes | | =?= | Qualquer caractere ocorrendo uma vez | | =[...]= | Lista de caracteres | | =¦= | =OU= lógico | </center> Para mostrar como fica melhor, vamos repetir o exemplo anterior, só que desta vez usaremos o =case= e não o =if ... elif ... else ... fi=. <verbatim> case $opc in 1) inclusao ;; 2) exclusao ;; 3) alteracao ;; 4) exit ;; *) echo Digite uma opção entre 1 e 4 esac </verbatim> Como você deve ter percebido, eu usei o asterisco como a última opção, isto é, se o asterisco atende a qualquer coisa, então ele servirá para qualquer coisa que não esteja no intervalo de 1 a 4. Outra coisa a ser notada é que o duplo ponto-e-vírgula não é necessário antes do =esac=. Exemplos: Vamos agora fazer um _script_ mais radical. Ele te dará bom dia, boa tarde ou boa noite dependendo da hora que for executado, mas primeiramente veja estes comandos: %TERMINAL_INI% $ date%OUT_INI% Tue Nov 9 19:37:30 BRST 2004%OUT_FIM% $ date +%H<nop>%OUT_INI% 19%OUT_FIM% %TERMINAL_FIM% O comando =date= informa a data completa do sistema, mas ele tem diversas opções para seu mascaramento. Neste comando, a formatação começa com um sinal de mais (=+=) e os caracteres de formatação vêm após um sinal de percentagem (=%=), assim o =%H= significa a hora do sistema. Dito isso vamos ao exemplo: %TERMINAL_INI% $ cat boasvindas.sh%OUT_INI% #!/bin/bash # Programa bem educado que # dá bom-dia, boa-tarde ou # boa-noite conforme a hora Hora=$(date +%H) case $Hora in 0? | 1[01]) echo Bom Dia ;; 1[2-7] ) echo Boa Tarde ;; * ) echo Boa Noite ;; esac exit%OUT_FIM% %TERMINAL_FIM% Peguei pesado, né? Que nada vamos esmiuçar a resolução caso-a-caso (ou seria case-a-case? :) ) =0? | 1[01]= - Significa zero seguido de qualquer coisa (=?=), ou (=|=) um seguido de zero ou um (=[01]=) ou seja, esta linha pegou 01, 02, ... 09, 10 e 11; =1[2-7] = - Significa um seguido da lista de dois a sete, ou seja, esta linha pegou 12, 13, ... 17; =* = - Significa tudo que não casou com nenhum dos padrões anteriores. - Cara, até agora eu falei muito e bebi pouco. Agora eu vou te passar um exercício para você fazer em casa e me dar a resposta da próxima vez que nos encontrarmos aqui no botequim, tá legal? - Tá, mas antes informe ao pessoal que está acompanhando este curso conosco como eles podem te encontrar para fazer críticas, contar piada, convidar para o chope, curso ou palestra ou até mesmo para falar mal dos políticos. - É fácil, meu e-mail é <a href="mailto:julio.neves@gmail.com?Subject=Duvidas Papo de botequim">julio.neves@gmail.com</a>, mas pare de me embromar que eu não vou esquecer de te passar o _script_ para fazer. É o seguinte: quero que você faça um programa que receberá como parâmetro o nome de um arquivo e que quando executado salvará este arquivo com o nome original seguido de um til (=~=) e colocará este arquivo dentro do vi (o melhor editor que se tem notícia) para ser editado. Isso é para ter sempre a última cópia boa deste arquivo caso o cara faça alterações indevidas. Obviamente, você fará as críticas necessárias, como verificar se foi passado um parâmetro, se o arquivo passado existe, ... Enfim, o que te der na telha e você achar que deve constar do _script_. Deu prá entender? - Hum, hum... - Chico! Traz mais um sem colarinho que o cara aqui já está dando para entender! :) 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 <a href="mailto:contato@clavis.com.br?Subject=Curso de Shell com Julio Neves">gerencia de treinamento</a> 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 <a href="mailto:julioneves@openoffice.org?Subject=Dúvidas Papo de Botequim">mim</a>. Valeu! -- Main.EvandroPastor - 19 Sep 2005
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r22
<
r21
<
r20
<
r19
<
r18
|
B
acklinks
|
V
iew topic
|
M
ore topic actions
Topic revision: r22 - 01 Aug 2009 - 22:32:36 -
BrSalgado
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