.----------------------------------. | Programação em Bourne-Again Shell `------------------------------------, | Por MELEU <meleu@meleu.cjb.net> http://meleu.da.

ru 05/2002 | `-----------------------------------------------------------------------' - = < 0. Intro 1. Começando 2. Variáveis e Parâmetros 2.1. Variáveis do Usuário 2.1.1. Variáveis Array 2.2. Variáveis do Shell 2.3. Variáveis Somente-Leitura 2.4. Parâmetros 2.4.1. shift 2.4.2. set (para editar parâmetros) 2.5. Substituição de Variáveis 3. Entrada e Saída (I/O) 3.1. echo 3.1.1 Sequências de Escape ANSI 3.2. read 3.3. Redirecionamento 3.3.1. Pipe 3.3.1.1. Comandos Úteis com o Pipe 4. Comandos de Tomadas de Decisão 4.1. if-then-else e afins 4.1.1. test 4.1.2. let 4.2. case 4.3. Tomadas de decisão com && e || 4.3.1. Listas 5. Comandos de Loop 5.1. for 5.1.1 "for" como na linguagem C 5.2. while 5.3. until 5.4. break e continue 5.5. Redirecionando loops 6. Funções 6.1 Funções como comandos 7. Tornando seu Script Amigável 7.1. getopts 7.2. select 7.3. dialog 8. Coisas úteis de se aprender 9. Exemplos Variados Í N D I C E > = -

9.1. 9.2. 9.3. 9.4. 9.5.

backup.sh howto.sh todo.sh inseretxt.sh Mextract.sh

10. Referências 11. Considerações Finais

------------------------------------------------------------------------0. Intro ***** ***** PRIMEIRO DE TUDO ************************************************** * * * Esta é a primeira versão do texto e ele está relativamente grande * * para que um único mortal revise-o por inteiro, com o agravante de que * * este mortal é um vestibulando. Por favor, se você achar algum erro, * * algo mal explicado, ou tem alguma sugestão para que o texto fique * * melhor mande-me um email: meleu@meleu.cjb.net * * Quando eu tiver tempo eu acrescentarei mais coisas... * * * ********************************************************************** *** Well... aqui estamos de volta... Dessa vez o assunto é shell script... Estou partindo do princípio de que ninguém aqui tem dúvidas quanto a utilidade de um shell script. Roubando uma citação de um amigo: "Em alguns casos, uma rede pode nao possuir um compilador (Vide Conectiva 5.0), logo, voce precisa se virar com o que tem, e os Shell Scripts podem suprir a sua necessidade em muitos casos." Eu já procurei um bocado de material sobre shell script em português na net e encontrei vários. Porém a maioria sobre Korn Shell, C Shell, poucos eram sobre bash. E os de bash eram muito superficiais. Explicavam só o começo de como criar seus shellscripts. Então o que eu pretendo aqui é entrar no assunto desde o início e com alguns detalhes (talvez não muitos). Note também que muitas coisas explicadas aqui podem ser usadas em

outros shells. Minhas fontes de pesquisa serão muito úteis para você, que é um newbie dedicado. Portanto consulte a seção de referências que você vai achar muita coisa boa. O único pré-requisito para o entendimento deste texto é que o leitor tenha alguma familiaridade com os comandos UNIX. Uma noçãozinha de programação (algoritmos) cairia bem. Se você não tem (ou acha que não tem) o pré-requisito acima citado, você pode adquirí-lo lendo o focalinux <http://www.focalinux.org>, ele é um bom material em português sobre os comandos, uso, configuração, etc. do GNU/Linux. Leitura recomendada! Se você sabe usar Expressões Regulares fica melhor ainda! Se não sabe aprenda a usar! Veja um guia sobre esse assunto na seção de referências. É de extrema importância que você vá praticando assim que aprender algo novo, isso ajuda a se familiarizar e memorizar as coisas. Por favor, não pense que sou um expert ou um guru em shell scripting! Eu só estava aprendendo e resolvi escrever isso pra ajudar quem também está afim de aprender. Não se esqueça: O aprendizado é eterno! ;-) A maioria dos scripts chamam programas existentes no sistema, não ficarei explicando o que faz cada comando. Se você quer saber o que ele faz, sua sintaxe e etc. procure na página man. Se você tiver alguma dúvida sobre o bash use: "help" ou "man bash". A manpage é bastante completa (e grande também)! Use-a como referência. Para sua comodidade eu coloquei os códigos entre as tags do Phrack Extraction Utility. Você pode encontrá-lo na última edição da phrack em <http://www.phrack.org>. Eu fiz um script em bash para extração dos códigos baseado no Phrack Extraction Utility, chama-se Meleu Extraction Utility (hehehe... qualquer semelhança NÃO é mera coincidência). Ele se encontra no tópico "9.5. Mextract.sh" e também em <http://meleu.da.ru/src/Mextract>. O esquema de organização é o seguinte: exemplos bestas ficam no diretório "BashScript/" os exemplos bacanas ficam no diretório "BashScript/bacanas/". * Atenção na versão em que eu fiz os meus testes, pois em versões antigas algumas coisas podem não funcionar (este e é o que vem na instalação do Slackware 8.0): /* -=-=-=-=-= version =-=-=-=-=- */ meleu@meleu:~$ bash --version GNU bash, version 2.05.0(1)-release (i386-slackware-linux-gnu) Copyright 2000 Free Software Foundation, Inc.

e outros pessoas que eu posso não me lembrar agora mas que também são meus camaradas. Especialmente para meus amiguinhos(as): lucipher. Blind_Bard.*/ Agradecimentos: A todos que fazem um esforcinho para publicar informações de qualidade em português.net> a sério. sem a qual tudo isso aqui não existiria! Amo vocês! =D LICENSA: Não quero nenhuma exclusividade! Quero é informação fluindo! Pegue este texto e espalhe em todo lugar em que ele for bem-vindo. veja: ' echo ls -l <--> /* --------------. aos camaradas da EoH Team <http://eoh-team. Emmanuele. Hekodangews. Se quiser extrair trechos dele e puder fazer o favor de citar de onde foi extraído. eu me sentiria agradecido.tk>. EvilLord. ou bash. ------------------------------------------------------------------------- 1.*/ Para que se possa executar um shell script é necessário permissão de . Mana_Laura.linuxsecurity.com. xf. Renato <www. aurélio (assim como eu também é um dinossauro-amante-do-modo-texto). um shell script é um arquivo em formato texto puro que contém comandos/instruções para serem executados em uma determinada shell. eSc2. O que vou tentar passar neste texto é como fazer shell script para o Bourne-Again Shell. às pessoas que levam a Unsekurity Scene <http://unsekurity.*/ <++> BashScript/primeiroexemplo. É lógico que também devo agradecimentos a toda a comunidade Open Source. clausen. Veja um exemplo de script: /* --------------./* -=-=-=-=-= version =-=-=-=-=.virtualave.sh #!/bin/bash echo 'Alo mamãe!' echo echo 'Agora executarei um simples "ls -l". klogd. hts. module. NashLeon. Esta é uma linguagem interpretada (você não precisa compilar para ter o executável) e o bash é o interpretador.br>. Começando ********* Como você já deve saber.

execução (mais sobre permissões em http://meleu.*/ <++> BashScript/procura_suid. mas tem que ser muito preguiçoso pra fazer um shell script de um comando só! :P De vez em quando é bom observar o que o script está fazendo.sh você faz: $ chmod u+x primeiroexemplo.sh #!/bin/bash # script para procurar arquivos suid # que pertençam a determinado usuário find / -user $1 -perm -4000 2> /dev/null <--> /* ----------------. veja: + echo + ls -l total 12 drwxr-xr-x drwxr-xr-x 5 meleu 2 meleu users users 4096 Aug 18 15:28 GNUstep 4096 Aug 19 23:11 progs . por exemplo: $ .Nas segunda e terceira linhas são usados comentários.A última linha que é realmente o comando. todo comentário começa com uma cerquilha (#) e vai até o final da linha. Referências)./procura_suid. Como você deve ter reparado.*/ Agora vamos a uma rápida explicação sobre o código.html#textos ). Veja: /* -=-=-=-=-=-= debugar =-=-=-=-=-=. ./primeiroexemplo.*/ $ bash -x BashScript/primeiroexemplo.ru/index. Para que somente você (dono do arquivo) tenha permissão de execução para o primeiroexemplo. o $1 significa o primeiro parâmetro dado na linha de comando (será falado mais sobre isso daqui a pouco).sh + echo 'Alo mamãe!' Alo mamãe! + echo + echo 'Agora executarei um simples "ls -l".Na primeira linha nós dizemos qual será o nosso intrepretador de comandos (o shell). .sh level5 irá procurar por todos os arquivos suid que pertençam ao usuário level5.. veja: ' Agora executarei um simples "ls -l".sh Agora você pode executar o script da seguinte forma: $ . . Para isso você pode usar alguns parâmetros junto com o shell para executar seu script. Você deve começar a linha com um "#!" (conhecido como sha-bang) e depois o caminho inteiro para o bash.da.sh Veja outro exemplo de apenas um comando: /* ----------------. esse shell script é útil nos wargames (veja 10..

A única coisa que não pode é usar um nome que já tenha sido definido para uma outra variável e que esta seja "readonly" (mais sobre isso adiante). todas as variáveis são strings. Variáveis e Parâmetros ********************** Ao contrário das outras linguagens. todas aquelas regrinhas para identificadores de linguagens de programação também se aplica aqui. mostra o script e depois executa-o (verbose). Outra coisa que devemos saber é que quando um shell script é executado ele usa OUTRA SHELL e NÃO USA A SHELL ATUAL. O bash usa strings para representar todos os dados que serão usados pelas variáveis. Também deve-se tomar cuidado para não fazer bobagens com . A seguir falaremos sobre os *tipos de variáveis* (e não "tipos de dados")... Outros parâmetros interessantes para a "debuagação" do script são: -n -v não executa os comandos. Só se pode começar com letra ou underline (número não pode).. o bash não possui "tipos de dados". Pois no bash as regras são parecidíssimas: * * * E Só se pode usar caracteres alfanuméricos e underline. :P mas é importante termos isso em mente quando formos usar variáveis.drwxr-xr-x 2 meleu users 4096 Aug 19 22:57 txts /* -=-=-=-=-=-= debugar =-=-=-=-=-=.. Se você conhece alguma outra linguagem de programação sabe que os identificadores possuem algumas regras quanto a sua nomeclatura. Desculpem eu estar berrando deste jeito.. Falando em variáveis. uma coisa que nós. falantes da língua portuguesa temos que saber é: * Os identificadores NÃO podem conter acentos! enfim. Você pode por exemplo fazer "if=lalala" que funcionará perfeitamente. apenas verifica erros de sintaxe (noexec).. Não pode conter espaços em branco.*/ O parâmetro "-x" faz com que seja exibido o comando e depois a saída do comando. ------------------------------------------------------------------------- 2. exceto aquela famosa sobre palavras reservadas.

*/ . Veja: $ nome='Meleu nao eh meleca!' Agora para usar a variável é só você colocar um cifrão '$' antes do nome dela.). `crases` e não usar nada.2. Veja isto: /* -=-=-=-=-= exemplos =-=-=-=-=. No exemplo abaixo nós criamos uma variável chamada "nome" e atribuímos a ela o valor "Meleu". ler.as variáveis do shell (explicados no tópico 2.1. "aspas duplas". Veja: $ nome=Meleu Não pode haver espaços nem antes nem depois do sinal de '='! Se você quiser atribuir um valor que contenha espaços é necessário usar as 'aspas simples'.*/ $ caminho='O meu path eh: $PATH' $ echo $caminho O meu path eh: $PATH $ caminho="O meu path eh: $PATH" $ echo $caminho O meu path eh: /usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/openwin/bin $ teste=`ls $HOME` $ echo $teste GNUstep/ progs/ textos/ $ conteudo_dir="Meu diretorio home contem: `ls $HOME`" $ echo $conteudo_dir Meu diretorio home contem: GNUstep/ progs/ textos/ $ teste=isso nao eh valido bash: nao: command not found $ teste=mas_isso_eh_valido $ echo $teste mas_isso_eh_valido /* -=-=-=-=-= exemplos =-=-=-=-=. Olhe um exemplo com e sem o '$': $ echo nome nome $ echo $nome Meleu não eh meleca! Existe diferença entre usar 'aspas simples'. Variáveis do Usuário ==================== As variáveis do usuário são as variáveis que você pode declarar. 2. inicializar e modificar.

.*/ $ dir_atual=$(pwd) $ echo $dir_atual /home/meleu $ echo $(ls $HOME) GNUstep/ progs/ textos/ $ tar czvf backup_$(date +%d-%m-%Y). porém ignora espaços excedentes. você pode fazer um shell script usar variáveis de usuário exportando-a com o comando "export" (ver man page do bash). Você pode usar as chaves para exibir uma variável (ex. portanto toda variável que for criada/inicializada num shell script perderá seu valor no final da execução do mesmo. quando executamos um shell script ele usa outro shell.tgz arquivo /* -=-=-= exemplo =-=-=. + 'aspas simples': atribuem à variável EXATAMENTE o que está entre elas. + `crases`: atribuem à variável a *saída do comando* que está entre elas. a variável de ambiente $PATH). tem a capacidade de ver o conteúdo de uma variável (no exemplo acima. você vai descobrir quando. e também a saída de comandos que estejam entre `crases`.*/ .Os mais espertos já perceberam as diferenças. No entanto. + nada: similar as aspas duplas. + "aspas duplas": atribuem à variável a string.*/ Como eu disse anteriormente.*/ $ name=coracao $ echo ${name}deleao coracaodeleao /* -=-=-=-=-= exemplo =-=-=-=-=.. mas para os mais lerdinhos (como eu) aí vai uma explicação.-) Veja estes exemplo: /* -=-=-= exemplo =-=-=. Um exemplo simples: /* -=-=-=-=-= exemplo =-=-=-=-=.*/ Outra coisa interessante é o uso das {chaves}. a variável de ambiente $HOME). Veja isto: /* -=-=-=-=-= exemplo =-=-=-=-=. Podemos usar $(cifrão-parênteses) no lugar das crases..: echo ${teste}). o valor das variáveis que porventura podem estar entre elas (no segundo exemplo. Em alguns casos é melhor usar $(cifrão-parênteses) mas eu não vou falar em quais. isso é útil quando você precisa separar a variável do que vem depois dela.

Para isso ele faria o seguinte: /* -=-=-= exemplo =-=-=./teste.sh #!/bin/bash echo "$VAR" $ export VAR='Um abraco para os gajos de Portugal! :)' $ . Variáveis Array --------------Também conhecidas como vetores.*/ 2. para sabermos qual é a sua fruta favorita basta digitarmos: $ echo ${FRUTA[0]} Bacana não acham? Agora vejamos uma coisa interessante. Imaginemos que EvilLord queira armazenar uma lista de suas frutas favoritas em uma variável array.$ cat teste.sh Um abraco para os gajos de Portugal! :) $ export VAR='--> mudei a variavel <--' $ .sh --> mudei a variavel <-/* -=-=-=-=-= exemplo =-=-=-=-=.. Este tipo de variável serve para se armazenar vários valores sob um nome e um índice. se eu declarar uma variável assim: $ FRUTA=goiaba e depois quiser fazer um array com o nome FRUTA eu posso fazer assim: $ FRUTA[1]=manga Desta maneira 'goiaba' passa a ser armazenada em FRUTA[0] Outra coisa interessante é que podemos declarar um array inteiro numa única linha de comando.*/ Supondo que ele colocou esta lista em ordem decrescente de gosto.1. Para isto usamos a sintaxe: ./teste. ops! digo.1.. A maneira de declarar variáveis array é a seguinte: NomeDaVariavel[Indice]=Valor sendo que Indice deve ser necessariamente um valor inteiro.*/ $ FRUTA[0]=goiaba $ FRUTA[1]=manga $ FRUTA[2]=pera $ FRUTA[3]=laranja /* -=-=-= exemplo =-=-=. Se eu declarar uma frut.

como nós já sabemos. Servem para determinar qual é o seu diretório home... O próprio shell inicializa algumas destas variáveis. --> HOME Esta variável tem um nome bem descritivo não acham? Bem. E se você precisar usar arrays de maneira mais complexa que isso: vá procurar a documentação oficial do bash! :P 2. enfim..bashrc ou ~/..2. seu prompt. Você pode atribuir novos valores para estas variáveis (uma boa é fazer isso no seu ~/. Pois o que o cd faz é o mesmo que "cd $HOME". valorn) Desta maneira o EvilLord economizaria teclado (?!) digitando isto: $ FRUTA=(goiaba manga pera laranja) E para vermos toda a lista de uma vez só.. um bocado de coisas. Se você alterar o valor de HOME.. Variáveis do Shell ================== Existem variáveis que o shell usa constantemente para um melhor funcionamento. Você já deve ter percebido que quando você dá um "cd" sem nenhum argumento você vai para o seu diretório home.NomeDoArray=(valor1 valor2 . podemos usar o seguinte comando: $ echo ${FRUTA[*]} Existem várias outras especificações para arrays mas quero passar aqui só o básico. em qual diretório o shell vai procurar por comandos que você digitar. estas são conhecidas como variáveis do shell. que podem ser lidas e alteradas pelo usuário. Vamos ver algumas destas variáveis mais importantes e suas respectivas funções. Quando você se loga no sistema o bash pega o nome do diretório que você está e o atribui à variável HOME. quando você digitar cd sem nenhum argumento o bash vai tentar te levar para o $HOME. o nosso diretório home é o diretório em que "caímos" assim que nos logamos (sabemos também que esta informação se encontra em /etc/passwd). Veja: /* -=-=-=-=-= exemplo =-=-=-=-=..*/ meleu:/usr/doc$ echo $HOME /home/meleu meleu:/usr/doc$ cd meleu:~$ pwd .bash_profile)..

Nada mais é . Exemplo: /* -=-=-= exemplo =-=-=. e então executar o programa suid feito pelo incompetente programador. Esta situação é bem difícil de se encontrar hoje em dia. e nesta função ele não usa o caminho completo do programa./home/meleu meleu:~$ HOME=/tmp meleu:/home/meleu$ cd meleu:~$ pwd /tmp meleu:~$ HOME=lalala meleu:/tmp$ cd bash: cd: lalala: No such file or directory /* -=-=-=-=-= exemplo =-=-=-=-=. Aí você faz um programa ou um shell script e nomeia ele como "date". no lugar de: system("/bin/date"). supondo que o programa está no seu PATH normal.*/ Portanto se eu digitar um "ls" o shell irá procurar pelo "ls" em /usr/local/bin depois em /usr/bin e daí em diante. Esta variável algumas vezes pode ser usada no hacking! Imagine que um programador inexperiente tenha feito um programa suid que usa a função system() (ou qualquer outra função que sirva para executar um comando externo). Vamos supor que o cara use: system ("date"). Agora é só alterar o PATH para que procure primeiro no diretório onde você salvou o SEU date. . resolvi colocar aqui por questões históricas.*/ Você também já deve ter reparado que quando estamos no nosso home aparece um til (~) logo antes do prompt.) --> PATH Esta variável armazena o caminho (path) que o shell irá percorrer para procurar um comando digitado pelo usuário. :P --> PS1 do Esta é a "Prompt String 1" ou "Primary Prompt String". Você pode alterar o PATH e executar um outro programa de sua preferência. e sim apenas o nome do programa. Observe este detalhe no exemplo acima.*/ meleu@meleu:/tmp$ echo $PATH / usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/usr/share/texmf /bin /* -=-=-= exemplo =-=-=. Faça uns testes aí que você vai me entender melhor.

--> MAIL . Na minha máquina o padrão é '\u@\h:\w\$ ' onde \u significa o nome do usuario.que o prompt que nos mostra que o shell está esperando um comando. o que dá a seguinte aparência: meleu@meleu:/usr/doc/Linux-HOWTOs$ Veja algumas possibilidades (na man page do bash tem mais): \d \h \s \t \T \u \w \W mostra a data atual mostra o hostname o nome do shell a hora atual (no estilo 24 horas) a hora atual (no estilo 12 horas) nome do usuário que está usando o shell nome do diretório atual (caminho todo) nome do diretório atual (somente o nome do diretório) Se você estiver afim de ter a impressão de que está no shell do root basta trocar o '$' por '#' (bah! que bobagem! :P ). Para aprender a fazer um monte de gracinhas com o PS1 dê uma lida no Bash-Prompt-HOWTO (ver 10.*/ $ echo m\ > e\ > l\ > e\ > u meleu $ echo 'm > e > l > e > u' m e l e u /* -=-=-= exemplo =-=-=. É usada quando um comando usa mais de uma linha. Você pode usar os mesmos caracteres especiais que o PS1 usa.*/ Este sinal '> ' (maior-espaço) é o PS2. \h significa o nome do host e \w é o diretório atual. Referências) --> PS2 Esta é a "Secondary Prompt String". Por exemplo: /* -=-=-= exemplo =-=-=. Quando você muda PS1 você muda a aparencia do prompt.

Veja: /* -=-=-= exemplo =-=-=. portanto se tiver um "exit" no script você vai executar um logoff. --> PROMPT_COMMAND Esta é bem interessante. executar o "exit" só se SHLVL for diferente de 1 (mais informações sobre o source em "6. É aí que está a utilidade da variável SHLVL.*/ meleu@meleu:~$ echo $MAIL /home/meleu/Mailbox /* -=-=-= MAIL =-=-=. Imagine que você está usando o bash e executou o bash de novo. Quando você está no shell primário o valor de SHLVL é 1.Nada mais é do que o arquivo onde são guardados seus emails.*/ meleu@meleu:~$ echo $MAIL /var/spool/mail/meleu /* -=-=-= MAIL =-=-=. Então você pode. Aqui na minha máquina eu uso o sendmail como servidor de email.*/ $ PROMPT_COMMAND="date +%T" 19:24:13 $ cd 19:24:17 .*/ --> SHLVL Esta variável armazena quantos shells você executou a partir da primeira shell. nesta situação o seu SHLVL vale 2.1 Funções como comandos").*/ Quando você inicializa scripts a partir do comando "source" o script é executado no shell pai.*/ porém se estivesse usando qmail seria: /* -=-=-= MAIL =-=-=. Ela armazena um comando que será executado toda hora que o prompt é exibido. Confuso? Vamos a um exemplo. através de um "if" por exemplo. Veja isto: /* -=-=-= exemplo =-=-=.*/ $ echo $SHLVL 1 $ bash # estou executando o bash a partir do bash $ echo $SHLVL 2 $ exit # saí do segundo bash exit $ echo $SHLVL 1 /* -=-=-= exemplo =-=-=. portanto: /* -=-=-= MAIL =-=-=.

toda essa linha será considerada uma única palavra --> RANDOM Quando você exibe esta variável ("echo $RANDOM") é exibido um número . 10. Referências). Isto é útil para casos como neste exemplo: /* ----------------. --> IFS O shell usa esta variável para dividir uma string em palavras separadas.*/ Se IFS for uma variável nula (vazia). tudo será considerado uma única palavra. Normalmente o IFS é um espaço. do echo $item done <--> /* ----------------. Desta maneira: isto eh uma string são quatro palavras.*/ Esta variável é útil quando queremos brincar com o prompt.*/ <++> BashScript/path. pois IFS é um espaço e as palavras estão separadas por espaço.txt eh uma linha sem nenhum comando exemplo =-=-=.sh #!/bin/bash IFS=':' for item in $PATH . para aprender mais sobre isso leia o Bash-Prompt-HOWTO (v. uma tabulação (Tab) e um caractere nova linha (\n).txt hacking/ pratica/ progs/ teste txts/ worldwritable.$ ls GNUstep/ Mail/ 19:24:19 $ 19:24:32 $ # isso 19:24:49 $ /* -=-=-= bons. Agora se eu mudar IFS para um ':' desta maneira: IFS=':' então a string: isto:eh:uma:string conterá quatro palavras. Por exemplo: se o IFS for nulo.

ambos possuem o mesmo resultado: /* -=-=-=-=-= exemplo-1 =-=-=-=-=.*/ $ readonly NOME="Meleu Zord" $ echo $NOME Meleu Zord /* -=-=-=-=-= exemplo-1 =-=-=-=-=. E para ver apenas as variáveis de ambiente use "env". porém existem muitas outras. e têm um total de 8 dígitos. Pra que serve isso? Sei lá! Várias coisas. Imagine que você queira um número de telefone celular qualquer (sei lá pra quê!). Veja os exemplos a seguir.3. O script a seguir gera números que comecem com 98 somente: /* ----------------. Quem é criativo sempre precisa de um número aleatório. PS3 .. TERM . LS_COLOR . LS_OPTIONS . Para tornar uma variável read-only podemos usar o comando "readonly" ou então "declare -r".*/ <++> BashScript/cellnumbergen. 2. MANPATH . HOSTNAME .aleatório entre 0 e 32767. do # se nao tiver 8 digitos acrescenta 0's NUM=${NUM}0 CONT=$(echo -n $NUM | wc -c) done echo $NUM <--> /* ----------------. Aqui na minha região estes números começam com 99 ou 98. Olhe a man page do bash na seção "Shell Variables" para mais detalhes. Variáveis Somente-Leitura ========================= Como sabemos as variáveis podem ter seu valor modificado pelo usuário. SHELL . você pode fazer um script que gera um número desse pra você.. HISTFILE .*/ . mas se nós quisermos variáveis que NÃO possam ter seus valores alterados basta declararmos tal variável como somente-leitura. Estas são as mais utilizadas.*/ --> Outras Outras variáveis que são muito usadas: MAILCHECK . USER .sh #!/bin/bash NUM="98$(echo $RANDOM)0" CONT=$(echo -n $NUM | wc -c) # quantos digitos tem? while [ $CONT -lt 8 ]. Para ver quais são as variáveis definidas no momento basta entrar com o comando "set".

especiais.4. Os parâmetros são variáveis. e também nós não podemos mudar o valor destas variáveis pelas vias "tradicionais". . digamos. UID. Para começar elas não obedecem as regras de nomeclatura de variáveis.*/ Existem várias variáveis somente-leitura que são inicializadas pelo shell. O único meio de apagar as variáveis readonly declaradas pelo usuário é saindo do shell (logout). evitando assim algum resultado crítico. 2. /* -=-=-=-=-= readonly =-=-=-=-=. pois elas usam números. O comando "readonly" quando usado sem parâmetros (ou o comando "declare" apenas com o parâmetro "-r") nos mostra todas as variáveis declaradas como somente-leitura.*/ Um bom uso deste tipo de variável é para garantir que variáveis importantes de um determinado script não possam ser sobregravadas.*/ Agora só pra ter certeza: /* -=-=-= teste =-=-=. como USER.*/ $ declare -r NOME="Meleu Zord" $ echo $NOME Meleu Zord /* -=-=-=-=-= exemplo-2 =-=-=-=-=. Parâmetros ========== Podemos passar parâmetros para o shell script assim como na maioria dos programas. No exemplo a seguir se for usado "declare -r" no lugar de "readonly" teríamos a mesma saída.*/ $ readonly declare -ar BASH_VERSINFO='([0]="2" [1]="05" [2]="0" [3]="1" [4]="release" [5]="i386-slackware-linux-gnu")' declare -ir EUID="1005" declare -ir PPID="1" declare -r SHELLOPTS="braceexpand:hashall:histexpand:monitor:ignoreeof:interactiv e-comments:emacs" declare -ir UID="1005" /* -=-=-=-=-= readonly =-=-=-=-=. para mudar o valor destas nós temos que contar com a ajuda do shift e/ou do set (como veremos adiante).*/ $ NOME=Fulano bash: NOME: readonly variable $ echo $NOME Meleu Zord /* -=-=-= teste =-=-=./* -=-=-=-=-= exemplo-2 =-=-=-=-=. TODAS as variáveis readonly uma vez declaradas não podem ser "unsetadas" ou ter seus valores modificado.

k. é o nome do shell script (a. parâmetro $1 é o primeiro parâmetro. Neste caso: parametros. Pra ficar mais claro.*/ <++> BashScript/parametros. todos os parâmetros./parametros. então dê uma olhada no seguinte script (se não entendê-lo tudo bem.. $9 o nono.sh echo "Nome do script: `basename $0`" echo "Número total de parâmetros: $#" echo "Primeiro parâmetro: $1" echo "Segundo parâmetro: $2" echo "Décimo quinto parâmetro: ${15}" echo "Todos os parâmetros: $*" <--> /* -----------------.. PID do script.*/ Se você não entendeu direito a diferença entre o $* e o $@.*/ $ . siga em frente e quando aprender sobre o "if" e o "for" leia-o novamente): . $1 a $9 ${10}. ${11}.a. quando o número do parâmetro possui mais de dígito é necessário o uso das chaves. cada um em strings separadas (exceto $0). todos os parâmetros em uma única string (exceto o $0). um $* $@ $# Outros: $? $$ valor de retorno do último comando (explicado mais adiante).Veja esta relação: $0 zero). e assim por diante.sh a b c d e f g h i j l m n o p q r s t u v x z Nome do script: parametros.sh Número total de parâmetros: 23 Primeiro parâmetro: a Segundo parâmetro: b Décimo quinto parâmetro: p Todos os parâmetros: a b c d e f g h i j l m n o p q r s t u v x z /* -=-=-=-=-= exemplo =-=-=-=-=.*/ /* -=-=-=-=-= exemplo =-=-=-=-=. número de parâmetros (sem contar com o $0). nada melhor do que um exemplo: /* -----------------.sh #!/bin/bash # # "basename" serve para eliminar o caminho do arquivo e mostrar # somente o último nome dele.

*/ 2. Ex.sh um dois tres quatro if [ -z "$1" ]. o shift./* -----------------. then echo "Uso: `basename $0` argumento1 argumento2 etc.1. shift ----O bash possui um comando embutido que lida com parâmetros.: # [prompt]$ .*/ <++> BashScript/testargs. Você pode ainda especificar quantas "casas" você quer que os parâmetros "andem" à esquerda através de "shift n" onde 'n' é o número de casas.sh #!/bin/bash echo "$#: $*" echo -e "executando \"shift\"" shift echo "$#: $*" echo -e "executando \"shift 5\"" shift 5 echo "$#: $*" echo -e "executando \"shift 7\"" shift 7 ." exit 1 fi echo echo "Listando argumentos com \"\$*\":" num=1 for arg in "$*".*/ <++> BashScript/shift-exemplo. Veja este exemplo: /* -----------------. do echo "Arg #$num = $arg" num=$[ $num + 1 ] done # Conclusão: $@ mostra cada argumento em strings separadas echo <--> /* -----------------. e assim por diante. Quando você usa o shift sai o primeiro parâmetro da lista e o segundo vai para $1 o terceiro vai para $2. do echo "Arg #$num = $arg" num=$[ $num + 1 ] done # Conclusão: $* mostra todos os argumentos como uma única string echo echo "Listando argumentos com \"\$@\":" num=1 for arg in "$@".4./testargs.sh #!/bin/bash # Ao executar este script entre alguns parametros. mas se o número de casas que ele deve andar for maior que o número de parâmetros o shift não é executado.

-) 2.sh (tópico 9. mesmo que eles tenham sido usados.*/ /* -=-=-=-=-= shift =-=-=-=-=.*/ Os valores que saem são perdidos. $2 seja 'dois'.4. respectivamente. Use com atenção! 2.5.*/ $ . Substituição de Variáveis ========================= .sh 1 2 3 4 5 6 7 8 9 0 10: 1 2 3 4 5 6 7 8 9 0 executando "shift" 9: 2 3 4 5 6 7 8 9 0 executando "shift 5" 4: 7 8 9 0 executando "shift 7" 4: 7 8 9 0 /* -=-=-=-=-= shift =-=-=-=-=.. Veja um exemplo de script: /* ----------------.2. e sim como usar set especificamente para editar parâmetros.echo "$#: $*" <--> /* ----------------. No meu Mextract. set (para editar parâmetros) ---------------------------O que vou passar neste tópico não é sobre como usar "todo o poder do comando set".*/ Não interessa quantos parâmetros você passar para este script. (huahuahau risada diabólica huahuahuha)" echo set um dois tres echo "Os $# novos parâmetros agora são: $@" echo <--> /* ----------------. 'dois' e 'tres'.5./shift-exemplo. no final você só terá $1. $3 seja 'tres' e só! Não existirá $4.*/ <++> BashScript/setparam. $5.) esta característica do set é muito bem aproveitada! .sh #!/bin/bash echo "Os $# parâmetros passados inicialmente foram: $@" echo echo "e agora eu vou alterá-los!" echo "como eu sou mau. $2 e $3 valendo 'um'. etc. Não tem nenhum segredo! Veja este exemplo: set um dois tres Isso fará com que $1 seja 'um'..

da.-) --> ${variavel:-string} Se "variavel" não tiver sido definida ou for vazia será substituída por "string".*/ $ echo ${EDITOR:?"Nenhum editor de texto"} bash: EDITOR: Nenhum editor de texto $ echo $EDITOR /* -=-=-= exemplo =-=-=.net $ echo $URL # observe que URL nao foi alterado /* -=-=-= exemplo =-=-=.net"} http://unsekurity. O valor da variável não é alterado.*/ $ echo ${URL:-"http://unsekurity.*/ --> ${variavel:=string} Se "variavel" não estiver sido definida ou for vazia.Isto é muito útil e pode ser muito mais elegante que ficar usando if's (explicados mais adiante) sem necessidade! Veja que bacana! .ru $ echo $WWW http://meleu.da. receberá "string". Exemplo: /* -=-=-= exemplo =-=-=.ru"} http://meleu.ru /* -=-=-= exemplo =-=-=.*/ --> ${variavel:?string} Se "variavel" não estiver sido definido ou for vazia.*/ $ echo ${WWW:="http://meleu. será substituída por "string" mas seu valor não será alterado. Veja este exemplo: /* -=-=-= exemplo =-=-=. O valor da variável não é alterado.da. Exemplo: /* -=-=-= exemplo =-=-=.*/ --> ${variavel:+string} Se "variavel" estiver definida.*/ . Veja um exemplo: /* -=-=-= exemplo =-=-=.*/ $ echo ${BROWSER:+"BROWSER definido como \"$BROWSER\""} BROWSER definido como "links" /* -=-=-= exemplo =-=-=.virtualave.virtualave. "string" será escrito em stderr (saída de erro padrão).

/* -=-=-= exemplo =-=-=.*/ $ echo uma boa rede de irc que conheco eh irc. chega! :) $ echo "$TESTE" primeira linha da variavel segunda linha terceira. echo ==== Nos já usamos o echo para escrever na tela.org $ echo "uma boa rede de irc que conheco eh irc.*/ Execute e veja o resultado.*/ <++> BashScript/filetype.linux. Para isso use o parâmetro "-n". > chega! :) > " $ echo $TESTE primeira linha da variavel segunda linha terceira. Veja este script: /* ----------------. 3. mas aqui vamos tratar de alguns "segredinhos" (que não são tão secretos assim).. Este parâmetro é útil quando você vai entrar com algo após o echo. Muita atenção deve ser tomada ao usar o echo.. Existem alguns momentos que você não quer que a saída do echo pule de linha automaticamente..org uma boa rede de irc que conheco eh irc. pois as aspas que você pode vir a deixar de usar podem fazer uma diferença danada (em alguns casos isso pode ser muito útil).------------------------------------------------------------------------- 3.sh #!/bin/bash echo -n "Entre com o nome do arquivo: " read FILE echo "Tipo do arquivo `file $FILE`" <--> /* ----------------.org" uma boa rede de irc que conheco eh irc..1. Entrada e Saída (I/O) ********************* Comunicando-se..org $ $ # agora um exemplo com variavel $ $ TESTE="primeira linha da variavel > segunda linha > terceira...linux..linux. .linux.

1m$*\e[0m" <--> /* ----------------. As sequências são iguais a da linguagem C. e antes de executar este script você precisa exportá-la: [prompt]$ export COLUMNS $COLUMNS ] || { echo Você precisa exportar a variável \"COLUMNS\": echo "Tente \"export COLUMNS\" e tente executar novamente" exit 1 } POSICAO=$[ ( $COLUMNS . Os mais malandrinhos devem ter tentado um contra-barra (backslash) '\'. echo -e "\e[${POSICAO}C\e[33.*/ <++> BashScript/amarelinho. etc. Que paia! /* -=-=-= exemplo =-=-=. 3. \b para backspace..`expr length "$*"` ) / 2 ] # `expr length "$*"` retorna o número de caracteres digitados # como parâmetros. e outras coisas interessantes.1.*/ . \a para beep.*/ O -e é também usado para escrever coloridinho (ai que fofo!).\nQue paia\a"! module caiu de cara tentando "top soul".chega! :) /* -=-=-= exemplo =-=-=. Veja este exemplo: /* -=-=-= exemplo =-=-=. É necessário usar o parâmetro "-e" com o echo.*/ $ echo -e "module caiu de cara tentando \"top soul\".. Veremos isso no tópico seguinte. Veja um exemplo (mais a frente você verá tabelas com os significados destas sequências): /* ----------------.1 Sequências de Escape ANSI ------------------------Para usar cores a sequência de escape é "\e[<NUM>m" (os sinais '<' e '>' não entram!).sh #!/bin/bash # imprime amarelinho no centro da linha # # # [ A variável $COLUMNS contém o número de colunas que o terminal está usando. Este parâmetro permite que usemos sequências de escape contra-barra. mas você não pode simplesmente fazer isso.*/ A esta altura você já deve ter se perguntado "Como faço para imprimir caracteres nova linha ou beep?!". exemplo: \n para nova linha.

Cada cor tem um código próprio. Veja uma tabela com os códigos de movimentação de cursor que eu conheço (os caracteres '<' e '>' devem ser ignorados): . Acima eu uso a variável POSICAO para mover o cursor para o centro da linha (veja o cálculo no código). | |-------------|------------------------------------------------| | | N=0 Apaga do cursor até fim da linha. | |-------------|------------------------------------------------| | \e[<N>E | Move o cursor N linhas para baixo na coluna 1. | |-------------|------------------------------------------------| | \e[<N>F | Move o cursor N linhas para cima na coluna 1. | | \e[<N>K | N=1 Apaga do cursor até o início da linha. o cursor vai andar "num" caraceteres para a direita. | |-------------|------------------------------------------------| | \e[<L>. | |-------------|------------------------------------------------| | | N=0 Apaga do cursor até o fim da tela. o 1 faz o marrom ficar em negrito. | |-------------|------------------------------------------------| | \e[<N>X | Limpa N caracteres à direita (com espaços).------------------------------------------------. | |-------------|------------------------------------------------| | \e[<N>S | Move a tela N linhas para cima. | | | N=2 Apaga a linha toda. | |-------------|------------------------------------------------| | \e[<N>T | Move a tela N linhas para baixo.<C>H | Coloca o cursor na linha L e na coluna C.-------------. No exemplo acima o 33 faz ficar marrom. | | | N=2 Apaga a tela toda. | | \e[<N>J | N=1 Apaga do cursor até o início da tela. por exemplo. | |-------------|------------------------------------------------| | \e[<N>P | Apaga N caracteres a direita.Agora uma explicação ligeira: o \e diz ao echo que o que vem depois é uma sequência de escape. O comando '[<num>m' muda para a cor "num". | |-------------|------------------------------------------------| | \e[<N>C | Move o cursor N colunas à direita. | |-------------|------------------------------------------------| | \e[<N>I | Move o cursor N tabulações à direita. | |-------------|------------------------------------------------| | \e[<N>G | Coloca o cursor na linha N. | |-------------|------------------------------------------------| | \e[<N>L | Adiciona N linhas em branco abaixo da atual. veja OBSERVAÇÕES mais adiante). porém combinando com o 1 fica amarelo (isso no modo texto. | |-------------|------------------------------------------------| | \e[<N>@ | Adiciona N espaços em branco. | Código | O que faz | |-------------|------------------------------------------------| | \e[<N>A | Move o cursor N linhas acima. | |-------------|------------------------------------------------| | \e[<N>D | Move o cursor N colunas à esquerda. pois no xterm. onde num é um número qualquer. | |-------------|------------------------------------------------| | \e[<N>M | Apaga N linhas abaixo da atual. | |-------------|------------------------------------------------| | \e[<N>B | Move o cursor N linhas abaixo. | . Se você der a sequência '[<num>C'.

Veja em http://verde666. Faça uns testes para praticar um pouquinho. Pra começar: você não precisa colocar um echo toda hora que for usar o read para escrever um prompt.-------------.1 Funções como comandos" você verá o Mfunctions.. e o código será assim: "\e[1. Por isso faça os testes que você descobrirá as cores -> Estas tabelas eu fiz graças a uma matéria que o aurélio escreveu sobre isso.-----------------------------. a lista é grande.org/coluna/ No tópico "6.*/ <++> BashScript/read1.2. Agora uma tabelinha dos atributos e seus números (N deve estar no formato "\e[<N>m"): .| Branco | 7 | '-----------------------------'----'-------------'---' OBSERVAÇÕES: -> Negrito. 3.----. | Atributo | N | Cor | X | |-----------------------------|----|-------------|---| | Desligar todos atributos | 0 | Preto | 0 | | Negrito | 1 | Vermelho | 1 | | Cor X para o primeiro plano | 3X | Verde | 2 | | Cor X para o segundo plano | 4X | Marrom | 3 | | Sublinhado | 4 | Azul | 4 | | Piscando (blink) | 5 | Roxo | 5 | | Vídeo reverso | 7 | Ciano | 6 | | -x| -. Principalmente quando temos negrito sendo usado com cores. ele contém uma função que mostra todas as combinações de cores possíveis. o código "\e[33m" irá ativar o marrom mas se for usado (no console!) com o atributo de negrito ficará amarelo.sh #!/bin/bash read -p "Entre com uma string: " string . read ==== Como você viu no script anterior para entrar com um dado usa-se "read".. | |-------------|------------------------------------------------| | \e[u | Restaura a posição do cursor que foi salva. Por exemplo. O read tem alguns "macetinhos". Sublinhado e Piscando possuem comportamentos diferentes no console e nos emuladores de terminal. | '-------------'------------------------------------------------' Sim. Basta fazer "read -p prompt variavel" Veja esta seção de exemplos: /* ----------------.33m".---.|-------------|------------------------------------------------| | \e[s | Salva a posição do cursor.

/* -=-=-=-=-= exemplo2 =-=-=-=-=.*/ /* ----------------. É útil para digitar uma senha por exemplo. Você também pode determinar o número de caracteres que serão lidos com o parâmetro "-n". Tente fazer "read -n 10 VAR". s1 = eSc2 s2 = adora s3 = ficar de copy'n'paste no IRC. Redirecionamento ================ Quem já sabe programar deve saber que existem três "file descriptors" abertos por padrão (pelo menos nos sistemas operacionais que conheço): .echo $string <--> /* ----------------./read-2. toda a string vai ser esta variável. Quando vai ler mais de uma variável ele a sua respectiva variável. e quando o número de strings variáveis a última fica com o excedente.*/ $ .*/ $ ./read-2. Mas cuidado: ao usar a opção -n você não poderá usar o backspace para fazer correções. E isso me foi bastante útil para fazer o Mextract. Tente "read -s PASS" e veja. O parâmetro "-s" serve para não ecoar o que for digitado. Mais sobre o read na manpage do bash.*/ /* -=-=-=-=-= exemplo =-=-=-=-=.*/ Quando o atribuída a atribui cada string excede o número de "read" vai ler apenas uma variável.3.*/ <++> BashScript/read2. 3.*/ /* -=-=-=-=-= exemplo2 =-=-=-=-=./read1.sh Entre com 3 strings: eSc2 adora ficar de copy'n'paste no IRC.sh #!/bin/bash read -p "Entre com 3 strings: " s1 s2 s3 echo "s1 = $s1 s2 = $s2 s3 = $s3" <--> /* ----------------.sh Entre com uma string: klogd eh um tremendo cachacero! klogd eh um tremendo cachacero! /* -=-=-=-=-= exemplo =-=-=-=-=. A opção "-r" serve para que a contra-barra (backslash) não aja como um caracter de escape.sh Entre com 3 strings: j00nix eh cabecudo s1 = j00nix s2 = eh s3 = cabecudo # o mesmo script com mais de 3 strings # $ . como você verá adiante.

Mas você pode apenas concatenar o conteúdo no final do arquivo usando ">>". Para fins práticos.txt 2> /dev/null Você ainda pode eliminar da saída os arquivos com stick bit e os arquivos de dispositivo usando parênt.) Veja este script a seguir a execute ele usando redirecionamento na linha de comando pra ver os resultados /* ----------------.txt" este será criado. EI!! Isto aqui é sobre redirecionamento.stdin (standard input).txt 2> /dev/null Ainda temos um probleminha: este comando irá mostrar também todos os links simbólicos e vários arquivos de dispositivo.. se preferirem :P ). Veja como direcionar de: + arquivo para stdin $ programa < arquivo + stdout para arquivo $ programa > arquivo + stderr para arquivo $ programa 2> arquivo + stdout para stderr $ programa 1>&2 + stderr para stdout $ programa 2>&1 + stdout e stderr para arquivo $ programa &> arquivo Se você usar por exemplo "find / -perm -2 > worldwritable.*/ <++> BashScript/redirecionamento. e não sobre o find! Vá ler a man page do find! =P Se o arquivo já existir seu conteúdo será sobregravado.sh #!/bin/bash echo "Isto vai para a saída padrão. Para não ver as mensagens de "Permission Denied" faça isso: $ find / -perm -2 > worldwritable.. a saída do comando será gravada nele e a saída de erro padrão será impressa na tela (ou écran. Exemplo: $ echo " F I M D O A R Q U I V O " >> worldwritable." . estes são considerados arquivos e você pode direcionar destes "arquivos" para outros e vice-versa.txt" e no diretório não tiver um arquivo chamado "worldwritable.txt Faça os testes e tire suas conclusões! . Para eliminar os links simbólicos faça o seguinte: $ find / -perm -2 ! -type l > worldwritable. stdout (standard output) e stderr (standard error).

*/ Tem um outro tipo de redirecionamento que é bastante útil. Pipe ==== Agora vejamos o pipe." 1>&2 echo "Isto vai criar um arquivo e colocar esta linha nele. usar este tipo de redirecionamento para fazer um shell script escrever um outro arquivo usando o comando "cat".echo "Isto vai para a saída de erro padrão." >> ARQUIVO <--> /* ----------------. return 0.c acabou na linha ACIMA do _EOF_ # Observe no arquivo.c o $NAME será "traduzido" para o username adequado echo -e "\n\tCOMPILANDO O PROGRAMA\n" gcc arquivo. Isso é muito útil para usar programas externos através de shell scripts. Vamos a um exemplo em que eu crio um código de programa escrito em C através do script (note que as variáveis do script SÃO interpretadas): /* ----------------.*/ 3.c\n" # O arquivo. printf ("\tFeito por $NAME\n\n").*/ <++> BashScript/catredir.c #include <stdio.sh #!/bin/bash NAME=`whoami` echo -e "\n\tCRIANDO O ARQUIVO arquivo.1. Você pode.h> int main (void) { printf ("\n\tPrograma que não faz nada além disso. Sua sintaxe é: $ programa1 | programa2 O pipe é usado para você fazer da saída de um programa a entrada de .3.\n").c -o arquivo echo -e "\n\tFEITO!\n" <--> /* ----------------. } _EOF_ # O arquivo. É assim: $ programa << delimitador Isto quer dizer que o programa vai ler o arquivo stdin até encontrar o delimitador. por exemplo.c terminará quando encontrar a string _EOF_ cat << _EOF_ > arquivo." > ARQUIVO echo "Esta linha vai para o final do arquivo.

txt Se não entendeu algo do comando acima e quer entender.*/ Mais exemplos serão dados ao longo do texto. $ # A linha abaixo nao tem utilidade. Comandos Úteis com o Pipe ========================= --> xargs O xargs transforma stdin em argumentos da linha de comando.sh já mostrado anteriormente). Apesar de simples o pipe é muito útil e poderoso.3. ele usa argumentos. 3.outro (como usado no exemplo amarelinho.*/ $ who | cut -c-9 # lembrando: pipe transforma stdout em stdin meleu hack root $ # "echo" nao le arquivo. É como se você fizesse "programa > arquivo" só que o saída do programa . Ele faz com que a saída do programa vá para a saída padrão. Veja este exemplo muito simples: /* -=-=-=-=-= exemplo $ who meleu tty1 Nov hack tty2 Nov root tty3 Nov $ who | cut -c-9 meleu hack root /* -=-=-=-=-= exemplo =-=-=-=-=.*/ 20 01:40 20 01:45 20 02:44 =-=-=-=-=. olhe as manpages. Vamos usar o exemplo anterior de novo: /* -=-=-=-=-= exemplo =-=-=-=-=.1. normalmente a tela (écran) *E* para um arquivo ao mesmo tempo.1.*/ Como eu gosto do find não resisti e colocarei um comando interessante que usa pipe e xargs: $ find / -perm -2 ! -type l ! -type c | xargs ls -ld > wordwritable. --> tee Outro comando bom de se usar com pipe é o "tee". $ who | cut -c0-9 | echo $ # "xargs" transforma o conteudo de stdin em argumentos $ who | cut -c0-9 | xargs echo meleu hack root /* -=-=-=-=-= exemplo =-=-=-=-=.

Veja um exemplo: /* ----------------. (Para mais detalhes sobre os códigos de retorno. Após cada comando o valor de retorno é gravado na variável $?.*/ <++> BashScript/return. mas não é o único.sh #!/bin/bash read -p "Entre com o nome do diretório: " DIR if ( cd $DIR 2> /dev/null ). 4. quando um comando retorna 0 o if avalia como verdadeiro e quando retorna um não-zero significa falso. que avaliam a expressão de retorno diferente de 0 como verdadeira e 0 como falso. Experimente: $ ls -la |tee conteudo. experimente um "echo $?" depois de algum comando e veja! A avaliação de verdadeiro do bash é exatamente o oposto de outras linguagens de programação (C por exemplo). No bash. then echo -e "'cd $DIR' retornou \"sucesso\" ($?)" else echo -e "'cd $DIR' retornou \"insucesso\" ($?)" fi .também seria escrita na saída padrão. then <instrução(ões) se expressão retornar verdadeiro> else <instrução(ões) se expressão retornar falso> fi Primeiro devemos saber que todos os comandos do UNIX possuem um código de retorno. Se você quer uma referência mais completa veja a manpage do bash.1 if-then-else e afins ==================== A estrutura básica é a seguinte: if <expressão>. olhe a página manual do bash na seção "EXIT STATUS").txt ------------------------------------------------------------------------- 4. Este código tem valor 0 quando a operação ocorre com sucesso e valor diferente de zero quando a operação NÃO termina com sucesso. Comandos de Tomadas de Decisão ****************************** Agora sim o negócio começa a ficar legal! :-) O jeito como as estruturas estão explicadas é o que eu uso.

já o retorno de "cd /dir_invalido" foi 1 porque ocorreu um erro. Isto prova que um shell script usa um shell a parte (shell "filho") e não o shell que chama o script (shell pai)./return.. Por exemplo: "0001" é diferente da string "1" mas o valor numérico é igual.. o parâmetro "-z" verifica se a string é vazia. --> expressões com strings: O sinal de "=" verifica se a primeira string é igual a segunda. test ---Para fazer testes mais arrojados usamos o comando "test".*/ meleu:~$ .sh Entre com o nome do diretório: dir_invalido 'cd dir_invalido' retornou "insucesso" (1) /* -=-=-=-=-= exemplo =-=-=-=-=.*/ O valor de retorno do comando "cd /usr" foi 0 portanto foi executado com sucesso. echo $? 1 $ test "abcd" != "efgh".sh Entre com o nome do diretório: /usr 'cd /usr' retornou "sucesso" (0) meleu:~$ .1. echo $? 0 $ test "abcd" != "abcd". e por aí vai. /* -=-=-= exemplos =-=-=..*/ $ test "abcd" = "abcd". (Chato ficar lendo isso toda hora né? Esta foi a última vez! :P) 4. Se estamos comparando strings ou se estamos comparando números.1.. Continue lendo. e o parâmetro "-n" verifica se a string NÃO é vazia. Existe uma sintaxe para cada tipo de interpretação que queremos dar a um dado. A maneira de usar o test muda de acordo com o que estamos querendo testar.<--> /* ----------------. para que o comando saiba que tipo de comparação estamos fazendo. E por isso usamos sintaxes diferentes./return. echo $? 0 . echo $? 1 $ test "abcd" = "efgh". Agora repare no final que mesmo com um "cd /usr" continuo no diretório HOME (~). o "!=" verifica se a primeira string é diferente da segunda.*/ /* -=-=-=-=-= exemplo =-=-=-=-=.

/* -=-=-=-=-= exemplo =-=-=-=-=. É muito mais prático e bonitinho :P $ test "meleu" = "$nome" é o mesmo que fazer: $ [ "meleu" = "$nome" ] Muito melhor.*/ $ cat strcmp2./strcmp2. fi $ .sh meleu .*/ Uma maneira mais prática de usar o "test" e subistituí-lo pelos [colchetes]. then echo As strings são iguais. echo $? "". then echo As strings são iguais. não acham?! Vamos usar esta notação a partir de agora! Agora vamos a uma dica útil pra hora de fazer comparações entre strings. fi $ ./strcmp. echo $? "meleu".sh #!/bin/bash if [ $1 = $2 ].*/ Aconteceu a mesma coisa que no primeiro exemplo. Uma solução pra que não dê este erro no test é usar aspas duplas.*/ $ cat strcmp1. else echo As strings são diferentes.sh: [: meleu: unary operator expected As strings são diferentes. só que agora temos um else pra ser executado caso a expressao do if retorne falso (ou não-zero)./strcmp.*/ Note que o test deu um erro. echo $? exemplos =-=-=. echo $? "".sh: [: meleu: unary operator expected /* -=-=-=-=-= exemplo =-=-=-=-=.$ test -z 1 $ test -n 0 $ test -n 1 $ test -z 0 /* -=-=-= "meleu".sh #!/bin/bash if [ $1 = $2 ]. Veja só: . /* -=-=-=-=-= exemplo2 =-=-=-=-=.sh meleu ./strcmp1. Primeiro vamos a um exemplo e depois a uma explicação. e por isso retornou um não-zero para o if. Observe o seguinte: /* -=-=-=-=-= exemplo2 =-=-=-=-=.

. 0 $ [ -d /bin/ls ].*/ Com este acontece tudo certo. diferente (Not-Equal). Obviamente se o arquivo não existir ocorrerá um erro. assim: $1=$2 ou "$1"="$2" Desta maneira o test vai retornar sempre verdadeiro. /* -=-=-= exemplo $ [ -f /bin/ls ]. then echo As strings são iguais.*/ echo $? echo $? echo $? =-=-=. São eles: -eq -ne -lt -le -gt -ge igual (EQual)../* -----------------. Não podemos utilizar os operadores que estamos acostumados.) Você também NÃO deve escrever tudo junto. echo $? 0 $ [ 1 -le 1 ]. "<" (Less Than). echo $? 0 . echo $? 0 $ [ $? -lt 5 ]. 1 $ [ -x /bin/ls ]. --> expressões aritméticas Aqui é bem diferente das linguagens de programação comuns. maior que. --> expressões com arquivos O parâmetro "-e" verifica se é um arquivo regular... /* -=-=-= exemplo =-=-=.*/ Lógico que não existem só esses três! Consulte a página man do test que você verá muitos outros parâmetros para expressões com arquivos. ">" (Greater Than). menor ou igual. menor que. como '=' para igual. pois seria como se você estivesse passado somente um parâmetro para ele. '<' para menor e assim por diante.*/ <++> BashScript/strcmp.sh #!/bin/bash if [ "$1" = "$2" ].*/ $ [ 2 -eq 2 ]. maior ou igual. Temos que utilizar outros operadores (que não são tão difíceis de decorar). fi <--> /* -----------------. e o "-x" verifica se o arquivo é executável. o "-d" verifica se é um diretório. "<=" (Less than or Equal).. 0 /* -=-=-= exemplo =-=-=. else echo As strings são diferentes. ">=" (Greater than or Equal).

O elif não precisa disso. Se você pretende usar mais coisa relacionada a matemática. then echo "O valor numérico de $NUM1 e $NUM2 são iguais.*/ <++> BashScript/string_number. echo $? 1 /* -=-=-= exemplo =-=-=." fi <--> /* ----------------. O exemplo a seguir usa o AND e também usa um novo tipo de comando de controle. é verdade) pra ver como é diferente o valor numérico e o valor string de duas variáveis.*/ 2 * 3 + 4 ] 2 * ( 3 + 4 ) ] exemplo =-=-=.*/ Aproveitando o assunto "números" aí vai uma informação útil: Para fazer cálculos aritméticos podemos fazer o seguinte esquema /* -=-=-= $ echo $[ 10 $ echo $[ 14 /* -=-=-= exemplo =-=-=. then echo "O valor string de $NUM1 e $NUM2 são iguais. então aprenda a usar o comando "bc" (via man page ou info).*/ Dê uma olhadinha neste script (meio besta. Mas se vai ficar só no "papai-mamãe" das operações básicas pode ficar usando $(()) ou $[] (OBS." fi if [ $NUM1 -eq $NUM2 ]. --> operadores lógicos (AND e OR) Para usar os operadores lógicos basta usar "-a" para AND e "-o" para OR. . sacou? Você também pode usar $((cifrão-dois-parênteses)) mas os colchetes são bem mais práticos. Muito simples.$ [ 2 -ne 2 ].: em operações de divisão os resultados não são muito satisfatórios)." else echo "O valor string de $NUM1 e $NUM2 são diferentes. o "elif". /* ----------------. só que se você usar "else if" vai precisar de um "fi" para fechar. que é a mesma coisa que "else if".*/ Basta colocar a expressão entre $[cifrão-colchetes].sh #!/bin/bash NUM1=1 NUM2=00001 if [ "$NUM1" = "$NUM2" ]." else echo "O valor numérico de $NUM1 e $NUM2 são diferentes.

1. then MENOR=$NUM1 if [ $NUM2 -le $NUM3 ].2.*/ <++> BashScript/crescente. . let --O let é um comando embutido no bash (e isto quer dizer que se você quiser info sobre ele tem que ver na manpage do bash.*/ O "-o" é no mesmo estilo. mais especificamente no tópico ARITHMETIC EVALUATION). pois sua sintaxe é parecidíssima. 4. then MEIO=$NUM1 MAIOR=$NUM3 else MEIO=$NUM3 MAIOR=$NUM1 fi else MENOR=$NUM3 if [ $NUM1 -le $NUM2 ]. then MEIO=$NUM1 MAIOR=$NUM2 else MEIO=$NUM2 MAIOR=$NUM1 fi fi echo "$MENOR < $MEIO < $MAIOR" <--> /* ----------------. then MENOR=$NUM2 if [ $NUM1 -le $NUM3 ].Preste atenção que é fácil de entender para quem tem noção de algoritmo: /* ----------------. Faça uns testes e verá. then MEIO=$NUM2 MAIOR=$NUM3 else MEIO=$NUM3 MAIOR=$NUM2 fi elif [ $NUM2 -le $NUM3 ]. mas só é usado para expressões aritméticas.sh #!/bin/bash read -p "Entre com o primeiro número: " NUM1 read -p "Entre com o segundo número: " NUM2 read -p "Entre com o terceiro número: " NUM3 # Observe o "-a" (AND) na expressão abaixo if [ $NUM1 -le $NUM2 -a $NUM1 -le $NUM3 ]. Com este comando você pode comparar valores numéricos com os sinais <. Ele é bastante útil para quem está acostumado com programação C.

>=.*/ 4. esac .. ==.. then # poderia ser: if let "$# != 2" echo "Uso: `basename $0` N1 N2" 1>&2 exit 1 fi if (( $1 > $2 )) .>.sh #!/bin/bash if (( $# != 2 )) . then # poderia ser: elif let "$1 == $2" echo "$1 é igual a $2" else echo "$1 é menor que $2" fi <--> /* ----------------. e !=. case ==== A sintaxe do case é: case WORD in padrao1) <lista de comandos> . *) <lista de comandos se nenhum padrao for casado> .*/ <++> BashScript/lettest. <=.2. then # poderia ser: if let "$1 > $2" echo "$1 é maior que $2" elif (( $1 == $2 )) . E mais bastante coisa comum em linguagem C (como por exemplo o ++ e o --).. Alguns exemplos do que você pode fazer: let var++ let var-let "$num > 2" # equivalente a "var=$[ $var + 1 ]" # equivalente a "var=$[ $var .1 ]" # equivalente a "[ $num -gt 2 ]" Outra coisa interessante é que você pode substituir let "expressao" por (( expressao )) Portanto os exemplos acima poderiam ser feitos assim: (( var++ )) (( var-.)) (( $num > 2 )) Veja este script abaixo apenas para entender a utilidade do let: /* ----------------. padrao2) <lista de comandos> .

echo E para dizer ao shell que terminamos uma opção do 'case' usamos dois '.3. Exemplos Variados. e se quisermos podemos começar outro depois disso. sem utilidade prática e meramente ilustrativo (se quer exemplo prático veja na seção 9. que são '*'.: echo .. howto.. . '?' e a '[lista]'..sh #!/bin/bash if [ -z "$1" ]. um '. Ex. Veja este script muito besta.'.3..' serve para dizer ao shell que um comando acabou. Os detalhes destes curingas são explicados na seção "Pathname Expansion" da manpage. Tomadas de decisão com && e || ============================== Esta maneira de tomar decisões é bem compacta. Para os padrões você pode usar uns curingas parecidos com os usados para nomes de arquivos. particularmente. m|M) *) echo "nenhum dos parâmetros definidos foi usado" . ?b) echo "você digitou algum caractere seguido de um 'b'" . 4. Eu. mas não aceita "else". echo MELEU .Como nós sabemos. # esta barra '|' serve como um "ou" echo MELEU. [A-Za-z]c) echo "você digitou um caractere do alfabeto seguido de um 'c'" .*/ <++> BashScript/casetest.-) Veja outros exemplos na seção 9. esac <--> /* ----------------... prefiro usar esta estrutura quando vou fazer uma tomada de decisão e não preciso de "else".*/ Agora pratique um pouco!! .sh): /* ----------------. then echo "Entre com um parâmetro" exit 1 fi case "$1" in *a) echo "você digitou algo que termina com 'a'" .

. não?). Podem ser representadas por (parenteses) ou {chaves}. 4. Vejamos um parecido usando o &&: $ [ -d ~/tempdir ] && ls -ld ~/tempdir Não preciso explicar né? Se você está se perguntando "Mas eu só vou poder usar um único comando?!". FYI: para saber o diretório atual o comando a ser usado é o "pwd". o que comprova que com as {chaves} os comandos são executados no shell atual. /* -=-=-= exemplo =-=-=.*/ [ -d /usr/doc ] && { echo "O diretorio existe" echo "veja o seu conteudo" cd /usr/doc ls } /* -=-=-= exemplo =-=-=.. A diferença é que os (parenteses) executam os comandos numa shell a parte e as {chaves} executam no shell atual.. e neste caso o "mkdir ~/tempdir" será executado.3. Execute comando a seguir e tente entendê-lo (está certo. O || executa o primeiro comando e somente se este retornar não-zero (ocorrer problemas) o segundo será executado. a próxima seção lhe trará respostas. Caso não exista ele retornará 1.*/ E observe que ao final da execução você estará no diretório /usr/doc.A maneira de usar é: comando1 && comando2 comando1 || comando2 O && executa o primeiro comando e somente se este retornar 0 (não ocorrer problemas) o segundo será executado. são vários comandos. mas inicialmente é encarado com um comando só). se você trocar as {chaves} por (parênteses) observará que o seu diretório não se alterará.1 Listas -----As listas de comandos servem para agrupar comandos (meio lógico. Veja um exemplo bem simples: $ [ -d ~/tempdir ] || mkdir ~/tempdir Como você deve estar lembrado. "[ -d ~/tempdir ]" é o mesmo que "test -d ~/tempdir" e retornará 0 se existir o diretório ~/tempdir.. .

assim como eu também fiquei. then echo "Uso: `basename $0` comando1 [comando2 [comandoN. :) Porém é raro a gente usar esta lista de argumentos deste jeito.1.]]" 1>&2 exit 1 fi . Vamos a um exemplo pra você entender direito: /* ----------------. do <comandos que serão executados até que variavel-indice assuma todos os valores da lista-de-argumentos> done A princípio você pode se sentir um pouco confuso com esse negócio de "lista-de-argumentos".*/ <++> BashScript/forsample2.sh #!/bin/bash if [ $# -lt 1 ]. Comandos de Loop **************** Isto é para quando você precisa repetir determinado comando. passando todos os parâmetros "na mão". várias vezes. Uma maneira mais prática é assim: /* ----------------.*/ <++> BashScript/forsample1.sh #!/bin/bash # Exemplo (sem muita utilidade) do uso do comando "for" echo "Mostra o caminho inteiro de alguns comandos" for VAR in ls bc grep sed awk. Funciona da seguinte forma: a variável usada como índice recebe todos os valores usados na lista de argumentos só que um de cada vez.*/ Pois é! É meio esquisito. 5. mas até que é fácil de entender.. quando não tiver mais argumentos o for acaba. do which $VAR done <--> /* ----------------. eu concordo! Mas é o que nós temos..------------------------------------------------------------------------- 5. for === O for funciona da seguinte forma: for variavel-indice in lista-de-argumentos.

Veja este exemplo: /* ----------------. Ele funciona basicamente da seguinte forma: /* -=-=-=-=-= exemplo =-=-=-=-=.for VAR in $@. Existe uma outra maneira que poderíamos ter usado para o mesmo objetivo.*/ Agora para usarmos um for um pouco parecido com o das linguagens de programação convencionais usamos um comandinho chamado "seq". continuando com o próximo arquivo" continue } minuscula=$( echo $maiuscula | tr A-Z a-z ) mv $maiuscula $minuscula done <--> /* ----------------. Para isto basta omitirmos o "in lista-de-argumentos". nós usamos no for os parâmetros passados na linha de comando.*/ No exemplo acima.*/ <++> BashScript/minuscula. do which $VAR done <--> /* ----------------.sh #!/bin/bash # renomeia arquivos que tenham nome em maiusculas para # o equivalente em minusculas [ $# -lt 1 ] && { echo "*** Erro: você precisa passar os arquivos que quer renomear" echo "Uso: Mminusculas arquivo1 [arquivoN]" exit } # repare que o for a seguir nao tem o "in lista-de-argumentos"! for maiuscula do [ -e "$maiuscula" ] || { echo "$maiuscula não existe.*/ $ seq 1 10 1 2 3 4 5 6 7 8 9 10 # pode ser em ordem decrescente também: .

1.$1 / $OP" | bc`" done <--> /* ----------------.).) 5.$ seq 10 1 10 9 8 7 6 5 4 3 2 1 /* -=-=-=-=-= exemplo =-=-=-=-=. do por esta linha: for (( OP=1. OP++ )).$OP = $[ $1 . 5. Para conferir isto basta pegar o script acima (tabuada.sh) e trocar as linhas onde tem for OP in `seq 1 10`. do Só não pode esquecer dos ((dois parênteses)). while .*/ Moleza! .2.*/ <++> BashScript/tabuada. OP <= 10.*/ Fácil não? Agora vejamos um exemplo: /* ----------------.sh #!/bin/bash if [ $# -ne 1 ].$OP ]" done echo for OP in `seq 1 10`. pode tirar proveito da sintaxe do let (já explicado no ponto 4.1. do echo -e "$1 + $OP = $[ $1 + $OP ] \t $1 .1 "for" como na linguagem C ------------------------Se você já é programador C. then echo "Uso: `basename $0` n" echo "Onde 'n' é um número inteiro qualquer" exit 1 fi for OP in `seq 1 10`.2. do echo -e "$1 * $OP = $[ $1 * $OP ] \t \ $1 / $OP = `echo "scale=2.

Veja a expressão básica e saberá: until <expressão>. do echo -n "Número: " read NUM if [ $NUM -gt 0 ].-) Exemplo: /* ----------------. Vamos direto a um exemplo: /* ----------------.*/ 5.3.*/ <++> BashScript/whilesample. do <comandos que serão executados enquanto <expressão> retornar verdadeiro> done Sem muita conversa. until ===== É igual ao while. do echo -ne "$CONT\t" . RESULT=0 NUM=0 echo -e "\e[1mPara sair entre com '-1'.===== Estrutura básica do while: while <expressão>.sh #!/bin/bash CONT=10 until [ $CONT -eq 0 ].sh #!/bin/bash # Script que soma os números positivos que são dados e sai do programa # quando é entrado -1. do <comandos que serão executados enquanto <expressão> retornar FALSO> done Leia direitinho: comandos que serão executados enquanto <expressão> retornar FALSO! .*/ <++> BashScript/untilsample. then let RESULT+=$NUM # para quem não conhece C: VAR1+=VAR2 é a mesma coisa que fazer # VAR1=$[ $VAR1 + $VAR2 ] fi done echo "Soma dos positivos: $RESULT" exit 0 <--> /* ----------------. exceto por um detalhezinho.\e[m" while [ $NUM -ne -1 ].

exit 1. } for FILE in $@. Ele também aceita argumento. --> continue O continue interrompe o loop e faz novamente o teste do comando que está controlando o loop (for.sh #!/bin/bash [ $1 ] || { echo "Entre com o(s) nome(s) do arquivo(s)". etc.sh #!/bin/bash # `true` sempre retorna verdadeiro while true. do read -p "Tente adivinhar o número: " NUM [ "$NUM" -eq 666 ] && break done echo -e "\nVocê acertou! \n" <--> /* ----------------. break e continue ================ Estes comandos são úteis quando usamos loops. do [ -f $FILE ] || { echo -e "\"$FILE\" não é um arquivo\n" continue } cat $FILE >> AllFiles. Para entender nada melhor que um exemplo: /* ----------------.*/ <++> BashScript/concatenar.txt echo -e "\n\n\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n\n" >> AllFiles. Veja este exemplo: /* ----------------. onde 'n' é um número inteiro que indica quantos "done's" pular. da seguinte forma: "break n".txt done . --> break Quebra a execução do loop.*/ O que o break faz é pular a sequência de execução do script para o que vier depois do "done". while.).let CONT-done echo <--> /* ----------------.*/ 5.4.*/ <++> BashScript/breaksample.

lembrando daqueles conceitos passados no tópico 3. (principalmente sobre o read e sobre os redirecionamentos).regiao": /* ----------------. Vamos a eles. Vou tentar passar os esquemas aqui através de exemplos meramente ilustrativos.sh slater nashleon xf eSc2 module hekodangews manalaura blindbard klogd evillord emmanuele . 5. # # Use da seguinte forma: # REGIAO amigo1 amigo2 amigo3 amigoN .echo "Feito!" <--> /* ----------------.*/ O que o continue faz é voltar lá para antes do "do" pra fazer o teste novamente.sh". Como alguns amigos moram em uma mesma região eu não vou ficar repetindo a região para cada um.regiao ############################# # lista de amigos e estados # ############################# # # OBS. Ele também aceita argumento no estilo "continue n" para indicar quantos "do's" voltar.: ISSO NÃO É UM SCRIPT! # # Linhas que COMEÇAM com '#' serão consideradas # comentários pelo script "listamigos.5 Redirecionando loops ==================== Lendo o livro "Linux: Programação Shell" (ver Referências) eu aprendi umas formas de usar redirecionamento para loops.. Portanto o arquivo fica assim: <++> BashScript/amigos.. # Nordeste Sudeste Sul <--> Agora veja o script que usará as informações contidas no arquivo "amigos.*/ <++> BashScript/listamigos. --> "pipeando" para o while Vamos imaginar um arquivo onde eu tenho os nomes de alguns amigos meus e a região onde eles moram.

) egrep -v "^#|^ *$" amigos. Se dentro do loop você quisesse usar o comando read para ler do teclado.regiao" não vai conseguir ver todos. Sabendo que o /dev/tty é o terminal que você está usando.. do echo -e "\e[1m--> Amigos do $REGIAO:\e[m" for amigo in $NOMES . do echo -e "\n\e[32.regiao | while read REGIAO NOMES . Neste caso. o script a seguir será melhor que o "listamigos.2.*/ <++> BashScript/listamigos2. do echo "$amigo" done echo done <--> /* ----------------. Mas a coisa não é tão simples assim.. Pra comprovar isso coloque no final do script listamigos2. /* ----------------. # em seguida vai redirecionar a saída para a entrada do # read que está lá no while (relembre-se do read no # tópico 3.sh".*/ Deu pra sacar direitinho? Qualquer dúvida é só dar uma olhada nas man pages dos comandos que estão gerando as dúvidas.regiao | while read REGIAO NOMES .*/ Se quiser comprovar com seus próprios olhos a necessidade de pegar a entrada de "/dev/tty" é só retirar o "< /dev/tty" naquele read dentro do loop.regiao" # sem exibir as linhas que comecem com um caractere '#' # (considerado comentário) e sem mostrar linhas vazias.sh um "echo bla bla bla" e quando o script mostrar . OBS.: Curiosamente o exit dentro de um loop que recebe dados de um pipe funciona como se fosse um break. pois a lista não caberá numa tela só.sh #!/bin/bash egrep -v "^#|^ *$" amigos. seria necessário pegar a entrada de "/dev/tty". do echo -e "\e[1m$amigo\e[m" done echo -ne "\nEntre <ENTER> para continuar ou 'sair' para sair: " read QUIT < /dev/tty [ "$QUIT" = "sair" ] && exit done <--> /* ----------------.1m--> Amigos do $REGIAO:\e[m" for amigo in $NOMES .#!/bin/bash # o egrep abaixo vai pegar o arquivo "amigos. Se você tiver muitos amigos no arquivo "amigos.

virtualave. # Se quiser fazer um ataque de força bruta # mais eficiente faça em C.*/ <++> BashScript/bruteftp. # Veja mais sobre ataques de força bruta em um # texto que o NashLeon fez em # <http://unsekurity.net> # # verifica se o parâmetro passado é um arquivo [ -f "$1" ] || { echo -e "\e[1mErro na passagem de parâmetros\e[m" echo "Uso: `basename $0` wordlist" exit 1 } WL="$1" echo -e " \e[36. Vejamos um exemplo onde você verá que o exit funciona como o break: /* ----------------.1m ------------------------------. ################################################################## # # Este código é só pra ilustração do texto # "Programação em Bourne-Agai Shell".\e[m " read -p "Host: " HOST read -p "Username: " USER cat $WL | while read PASS do # 230 é o número que recebemos quando entramos com sucesso via ftp ftp -ivn << EoF | grep "^230" &>/dev/null open $HOST user $USER $PASS bye EoF # $? contém o código de retorno do grep [ $? -eq 0 ] && { .1m ------------------------------. Isso ocorre porque durante o "pipeamento" os comandos são executados num subshell (um shell a parte ou shell filho. e o exit faz sair deste subshell."Entre <ENTER> para continuar ou 'sair' para sair: " entre com 'sair'.0.1) # e veja você mesmo os rastros deixados nos arquivos de log.sh #!/bin/bash # ################################################################## # *********** # * ATENÇÃO * # *********** # Não use este script para atacar servidores remotos! Ele deixará # arquivos de log imensos! Use-o apenas em localhost (127. OK? # Na prática mesmo ele não é muito útil. como preferir).1m ataque de força bruta via ftp \e[36.0.\e[37.

Agora veremos um arquivo onde eu tenho os telefones de alguns amigos. Mais sorte da próxima vez! " <--> /* ----------------. --> redirecionando de arquivo para while Esse método é bem esquisitinho. :-) # # Linhas que COMEÇAM com '#' serão consideradas # comentários pelo script "listartel.. # # Use da seguinte forma: # NOME PREFIXO TELEFONE # Com os campos separados por UM ÚNICO <TAB>.regiao". I: ISSO NÃO É UM SCRIPT! # OBS. A disposição das informações dentro do arquivo é um pouco parecida com o "amigos.*/ O "pipeamento" para while também é usado no Mextract.. não adianta # que não vai dar pra sair passando # trote.sh. veja: <++> BashScript/agenda..} done echo -e "\n\e[36. # # Exemplo: # lampiao 12 12345678 # mariabonita 87 87654321 # telefone "dus manu" xf 45 12431412 slater 98 65451654 minduin 45 54871800 nash 23 65576784 evil 23 54654654 heko 43 56465465 esc2 24 46456456 .tel ####################### # Agenda de telefones # ####################### # # OBS.5... II: os números dos telefones deste # arquivo são fictícios..sh". pois o ataque fracassou.1mO ataque foi bem sucedido! \e[m" echo -e "Username: \e[1m$USER\e[m\nPassword: \e[1m$PASS\e[m" exit 0 # lembrando que o exit funciona como se fosse break # $? contém o mesmo valor não-zero que fez parar o loop acima [ $? -ne 0 ] && echo " Você entupiu os arquivos de log por nada. Mas vou colocar ele aí para quem quiser usar.

Então repetindo: neste esquema o exit funciona normalmente! --> redirecionando a saída do loop para a tela Ficou confuso com este título? "Redirecionar a saída do loop para a tela parece ser uma coisa inútil. . I: Neste esquema também é necessário pegar os dados de /dev/tty se você quiser usar o read dentro do loop.tel > $TempFile while read NOME PRE TEL ..# telefone "das mina" emmanuele 87 45646545 maylline 29 65654655 manalaura 82 65416578 erika 65 34245522 <--> Vamos ao script que se utilizará das informações de "agenda. Não é igual ao esquema anterior onde o while recebe dados de um pipe e o exit funciona como se fosse um break.*/ <++> BashScript/listartel. # redirecionando a saída para $TempFile egrep -v "^#|^ *$" agenda.tel": /* ----------------." Aí que você se engana! Vamos ao exemplo onde eu mostrarei a utilidade de se redirecionar desta maneira. basta fazer o seguinte: $ .tel # sem exibir as linhas que comecem com um caractere '#' # (considerado comentário) e sem mostrar linhas vazias.. :) OBS.*/ Agora quando você se sentir solitário e quiser conversar com alguém. pois isso acontece todas as vezes.sh #!/bin/bash TempFile=/tmp/TEMP-$$ # o egrep abaixo vai mostrar o arquivo agenda. II: Se você usar exit dentro do loop usando este esquema. do echo -e "Tel de $NOME: ($PRE)$TEL" done < $TempFile # esse redirecionamento faz com o que o "read" lá no while # leia linha por linha do arquivo $TempFile rm $TempFile <--> /* ----------------.sh | grep emma Aí é só você ligar pra emmanuele e bater um papo legal com ela. OBS./listartel. ele REALMENTE SAIRÁ DO SCRIPT.

*/ <++> BashScript/retornatel. read -p "Pressione <ENTER> para continuar../retornatel.sh que pesquisa o telefone de um determinado amigo (o nome é passado ao script durante sua execução). fará com que os dados impressos para fazer a interface com o usuário não sejam enviados para a saída padrão e por conseguinte não sejam enviados para a variável que está recebendo o número através do método variavel=`programa` Desta maneira. como veremos no script a seguir. Veja o script: /* ----------------. Agora queremos pegar o telefone deste amigo e armazená-lo numa variável da seguinte maneira: FONE=`." fi done > /dev/tty grep "^$NOME" $FILE | cut -f3 <--> /* ----------------. do clear gotoxy 5 1 read -p "Nome a ser pesquisado ('sair' para sair): " NOME [ "X$NOME" = Xsair ] && exit if grep "$NOME" $FILE &>/dev/null .*/ Olha o /dev/tty aí de novo! :P Redirecionando a saída de todo o loop para "/dev/tty". se você quer armazenar o telefone do xf na variável ..$2H" } while true. a saída do script não é somente o número do telefone..sh #!/bin/bash # tá bom. eu sei que não é um exemplo muito útil..tel function gotoxy { [ $# -ne 2 ] && { echo gotoxy: Erro na passagem de parâmetros echo Uso: gotoxy X Y exit 1 } echo -ne "\e[$1.sh` Só que. # é só pra ilustrar a utilidade de redirecionar a saída do loop FILE=agenda.Temos um script chamado retornatel. then break else gotoxy 10 15 echo Nenhum $NOME foi encontrado em $FILE. Existe uma interface com o usuário perguntando qual o nome a ser pesquisado.. tá bom..

Parâmetros com a exceção do $0. sendo que ValorDeRetorno ficará armazenado em "$?". e todas aquelas regras explicadas em 2.sh` E então pesquise por xf. vale observar também que só é possível retornar valores inteiros. Funções ******* Funções são interessantes para quando você precisa fazer uma determinada coisa várias vezes num mesmo script. faça o seguinte: XFTEL=`. function quit { echo -e "\e[1.. se na função tiver "return 123" depois da execução desta instrução "$?" valerá 123. Uma função é como se fosse um script dentro do script.. Depois é só usar echo $XFTEL para ver o telefone do cara..4.32mTCHAU!\e[m" exit } function e { echo -e "\e[1.. que não retorna o nome da função!).XFTEL. Experimente usar o script sem este redirecionamento e pegar o telefone do xf desta maneira que expliquei para apreciar os resultados bizarros.35m$1\e[m" } e Hello e World quit . Por exemplo. Uma função também é capaz de retornar um valor usando o "return ValorDeRetorno". ------------------------------------------------------------------------ 6. explicar com um código sempre é mais fácil! Se você acha que vai se safar do poderoso "Hello World" está muito enganado! Aí vai ele: /* ----------------. $2 para segunda. sendo assim ele também usa o mesmo esquema de parâmetros de um script comum ($1 para primeiro parâmetro. Bem.*/ <++> BashScript/hello./retornatel.sh #!/bin/bash # "Hello World" usado para ilustrar o uso de funções.

saia da frente do computador e vá procurar um livro de matemática!)... then echo "Os dois números são iguais. . Sem falar muito eu já emendo outro código: /* ----------------. :P Se precisar de valores positivos maiores que 256 retorne-o como negativo e depois converta-o para positivo novamente (como? ah meu amigo. .O valor mais alto que uma função pode retornar é 256 e o mais baixo.O return quando executado interrompe a execução da função e a execução passa para a instrução imediatamente posterior a qual a função foi chamada." fi exit 0 <--> /* ----------------..*/ Uhmmm. then echo "É necessário passar dois parâmetros para a função.sh #!/bin/bash PARAM_ERR=-198 # Se for passado mais do que dois parâmetros.*/ Só umas informações adicionais: ..*/ <++> BashScript/maior.echo "Isso aqui não será impresso" <--> /* ----------------. function maior # Retorna o maior de dois números { # OBS: os números comparados precisam ser menores que 257 [ -z "$2" ] && return $PARAM_ERR if [ "$1" -eq "$2" ]. é um número de módulo grande." elif [ $RET_VAL -eq $EQUAL ]." else echo "O maior número é $RET_VAL. then return $EQUAL elif [ "$1" -gt "$2" ]. bem..Se quer saber mais detalhes sobre funções o capítulo 23 do Advanced . then return $1 else return $2 fi } read -p "Numero-1: " N1 read -p "Numero-2: " N2 maior $N1 $N2 RET_VAL=$? if [ $RET_VAL -eq $PARAM_ERR ]. EQUAL=-199 # Retorno se os parâmetros forem iguais..

linuxdoc. # Mais informações sobre este guia em http://www.Bash-Scripting Guide vai lhe ser muito útil.-) /* ----------------.org # Caso não entenda o código.*/ <++> BashScript/romano.$FATOR )) while [ "$RESTO" -ge 0 ]. faça um esforcinho! . . do echo -n $ROMAN (( NUM -= $FATOR )) (( RESTO = $NUM .sh #!/bin/bash # # Código baseado em um do Advanced Bash-Scripting Guide. Fique com mais este código que eu achei bem interessante.-) LIMITE=400 function romano { NUM=$1 FATOR=$2 ROMAN=$3 (( RESTO = $NUM .$FATOR )) done return $NUM } [ "$1" ] || { echo "Uso: `basename $0` NUMERO" exit 1 } [ "$1" -gt 400 ] && { echo "$1 ultrapassa o limite de $LIMITE" exit 1 } NUMERO=$1 romano $NUMERO 100 C NUMERO=$? romano $NUMERO 90 XC NUMERO=$? romano $NUMERO 50 L NUMERO=$? romano $NUMERO 40 XL NUMERO=$? romano $NUMERO 10 X NUMERO=$? romano $NUMERO 9 IX NUMERO=$? .

romano $NUMERO 5 V NUMERO=$? romano $NUMERO 4 IV NUMERO=$? romano $NUMERO 1 I NUMERO=$? echo exit <--> /* ----------------. =) Veja este outro exemplo um pouco mais útil: /* -=-=-= exemplo =-=-=. faça os testes por conta própria! :-) 6. Com isso eu quero dizer que você pode fazer tudo que faz em um shell script na linha de comando. digite o seguinte na sua linha de comando: function heko { echo -e "\e[5. :-) Na linha de comando você declara uma função da mesma maneira que faz num script. Desta vez não darei exemplos.32mHekodangews. then PATH="$PATH:$DIR" else echo "* * * Erro: $DIR nao eh um diretorio" fi done .1.*/ function SetPath { PATH=${PATH:="/bin:/usr/bin"} for DIR in "$@". inclusive criar e utilizar funções (que é o assunto deste tópico). para de enrolar a mina e casa logo! \e[m" } Agora quando você entrar com "heko" na linha de comando será impresso na tela um recadinho para o Hekodangews numa corzinha verde e piscante super-fashion. Por exemplo.*/ Ah! Deixa eu dizer só mais uma coisinha: é possível declarar função(ões) dentro de função..1 Funções como comandos ===================== Antes de começar vamos relembrar um conceito básico: quando se executa um shell script você obtém o mesmo resultado que obteria se digitasse o conteúdo do script no prompt de um shell. Bom chega de falar de coisas óbvias. do if [ -d "$DIR" ]..

Mfunctions # # depois faça o seguinte: # [prompt]$ echo ".*/ <++> BashScript/bacanas/Mfunctions #!/bin/bash # # "INSTALAÇÃO": # copie este arquivo para seu $HOME: # [prompt]$ cp Mfunctions ~/. Uma coisa legal de se fazer é colocar o arquivo com as funções que você quer usar num arquivo oculto no seu $HOME (ex. né? Quando você quiser acrescentar algum diretório no seu PATH basta usar "SetPath dir1 dir2 dirn". ~/.bash_profile você coloca uma linha com o comando "source $HOME/. Lembra-se de eu ficar enchendo o saco dizendo "Quando executamos um shellscript ele é executado num shell a parte (shell filho)"? Pois eu não fiquei enchendo o saco com isso sem motivo.Mfunctions" e pronto.export PATH unset DIR } /* -=-=-= exemplo =-=-=.Mfunctions" >> ~/. ou seja. # # DICA: depois de corretamente instalada.bash_profile # # Dê login novamente ou digite ". E isso é especialmente útil quando temos arquivos com as nossas funções que queremos usar como comandos. O comando source faz com que o script seja executado no shell pai.: $HOME/. use "M<tab><tab>" # para ver as funções disponíveis.MyFunctions".MyFunctions) e no seu $HOME/. ~/. # Agora é só digitar o nome da função. . Veja este arquivo com alguns exemplos de funções: /* ----------------.*/ Acho que deu pra sacar qual é.-) E se você tiver várias idéias de funções legais que queira usar sempre em suas sessões? Vai ter que digitá-las na linha de comando toda hora? Não! Para este propósito o comando "source" pode ser muito útil (informações detalhadas na manpage do bash). # # Funções disponíveis neste arquivo: # + Mecho # + Mcenter # + Mclock # + Mclock2 # + Msetpath # + Mdica # + Marrumanome # + Mnocomments # + Mcalcula # + Mcores # # Aproveite! . é como você estivesse digitando todo o conteúdo do arquivo na linha de comando.

org/zz # # imprime em negrito function Mecho { echo -e "\e[1m$*\e[m" } # imprime em negrito no centro da linha function Mcenter { local POS=$[ ( $COLUMNS . then HEADER=\"Jobs: \$JOBS \$(DiaMesAno)\" else HEADER=\"\$(DiaMesAno)\" fi POS=\$[ (\$COLUMNS .33m" local SCOR="\e[m" alias DiaMesAno='date +'\''%H:%M %e/%m/%y'\' PROMPT_COMMAND=" JOBS=\$(echo \$(jobs | wc -l)) if [ \$JOBS -ne 0 ].`echo -en "$*" | wc -c` ) / 2 ] Mecho "\e[${POS}C$*" } # deixa sempre no cantinho da primeira linha do console: # "[ hora:minuto dia/mes/ano ]". # Se houver algum processo em segundo plano (background) ele também indica.0H\e[K\ \e[\$(echo -n \$POS)C\ $CIANO[$AMARELO \$HEADER $CIANO]$SCOR\ \e[u\e[1A\] $PS1" echo -e "\nMclock ativado!\n" .36m" local AMARELO="\e[1.\$(echo \"\$HEADER\" | wc -c) ) .: graças a esse tal de "oupem sórssi" você pode ler # um código e alterá-lo para que se adeque as suas # necessidades eu que fique ao seu gosto.: nos emuladores de terminal em que eu testei só funcionou no xterm # o rxvt não aceita os códigos de salvar e restaurar a posição do cursor # (respectivamente "\e[s" e "\e[u").# meleu # # P.3 ]" PS1="\[\e[s\e[1. # OBS.S. E # a minha principal fonte foi o funcoeszz do aurélio. Pois foi # isso que eu fiz aqui! Saí olhando as funções que # outras pessoas fizeram e arrumei do meu jeito. # veja em: http://verde666. function Mclock { local CIANO="\e[1.

} for DIR in "$@". then HEADER=\"Jobs: \$JOBS . %e %B %Y'\' PROMPT_COMMAND=" JOBS=\$(echo \$(jobs | wc -l)) if [ \$JOBS -ne 0 ]. then PATH="$DIR:$PATH" else echo "* * * Erro: $DIR não é um diretório" continue fi done export PATH } # # # # # # # # eu tenho no meu home um diretório dicas onde eu vou colocando dicas sobre programas diversos. do if [ -d "$DIR" ].33m" local SCOR="\e[0m" alias Mdate='date +'\''%H:%M . então quando eu me deparo com uma dica sobre o grep.\$(echo \"\$HEADER\" | wc -c) ) / 2 ]" PS1="\[\e[s\e[1.} # Parecido com o Mclock mas fica tudo escrito no centro da primeira linha # e em um formato mais longo.0H\e[K\ \e[\$(echo -n \$POS)C\ $CIANO[$AMARELO \$HEADER $CIANO]$SCOR\ \e[u\e[1A\] $PS1" echo -e "\nMclock2 ativado!\n" } # Adiciona um diretório na sua variável $PATH function Msetpath { local DIR PATH=${PATH:="/bin:/usr/bin"} [ $# -eq 0 ] && { echo "PATH = $PATH".: o aurélio que me deu ESTA dica do diretório "$HOME/dicas". o nome dos arquivos são iguais aos nomes dos programas.%A. . por exemplo. eu faço: [prompt]$ cat dica_grep >> ~/grep esta função serve para visualizar as dicas OBS.$(Mdate)\" else HEADER=\"\$(Mdate)\" fi POS=\$[ (\$COLUMNS . function Mclock2 { local CIANO="\e[1. return.36m" local AMARELO="\e[1.

."$FILE" "$DIR/$NFINAL" # visualiza um arquivo retirando linhas que comecem com um caractere # de comentário (#) e linhas vazias (linhas com espaços não são # vazias) function Mnocomments { [ "$1" ] || { Mecho "Erro: falta argumentos" echo "Uso: Mnocomments arquivo1 [arquivoN ..-) .]" return } # estou usando o more só por causa daqueles ":::::::" que aparecem # quando é passado mais de um arquivo como parâmetro. # e espaços em branco.]' return 1 } local FILE NINICIAL NFINAL DIR for FILE in "$@"._-]/_/g'` done } [ "$NINICIAL" != "$NFINAL" ] && mv -. do [ -f "$FILE" ] || continue NINICIAL=`basename "$FILE"` DIR=`dirname "$FILE"` NFINAL=`echo "$NINICIAL" | sed ' y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ y/ÃãÀàÂâÄäÁáÈèÊêËëÉé/aaaaaaaaaaeeeeeeee/ y/ÌìÎîÏïÍíÕõÒòÔôÖöÓó/iiiiiiiioooooooooo/ y/ÙùÛûÜüÚúÇçÑñ/uuuuuuuuccnn/ s/^-/_/ s/[^a-z0-9.) function Mdica { local DICASDIR=$HOME/dicas [ "$1" ] || { Mecho "Uso: Mdica [assunto]\n" echo "Os assuntos disponíveis são:" ls $DICASDIR return } more $DICASDIR/$1 } # renomeia os arquivos que possuem nomes com caracteres feiosos # fazendo com que letras maiúsculas fiquem minúsculas. símbolos e outras coisas feias fiquem # underline '_' function Marrumanome { [ "$1" ] || { Mecho "Erro: você precisa passar os arquivos que quer renomear"..# valeu rapaz! . .. # letras acentuadas fiquem a letra correspondente sem acento. echo 'Uso: Marrumanome arquivo1 [arquivoN .

Tornando seu script amigável **************************** Alguns comandos úteis que tornam seu script mais "user-friendly". .-) ------------------------------------------------------------------------ 7. # mais uma cortesia do aurélio function Mcores { for LETRA in `seq 0 7`. do SEQ="4$FUNDO. a gente faz uma forcinha pra enteder e no final das contas: o que importa é que funciona! .org/zz>. Vou logo avisando que o ele parece ser daqueles tipos que não ligam para a "limpeza" do código.1'. mas tudo bem. do for BOLD in '' '. $@" | bc } # mostra todas as cores do console e seus respectivos códigos.} \e[m" done echo done done } <--> /* ----------------.3$LETRA" echo -ne "\e[$SEQ${BOLD}m $SEQ${BOLD:..*/ Se você quer ver umas funções porretas que o aurélio fez olhe em <http://verde666.more $@ | egrep -v "^#|^$" } # faz cálculos usando o bc # só pra não precisar ficar fazendo "echo <expressao> | bc" toda hora function Mcalcula { [ "$1" ] || { Mecho "Erro: você precisa passar uma expressão" echo "Uso: Mcalcula <expressão>" echo "Exemplo: Mcalcula '4^2+3*(7-4)'" return 1 } # mude o valor de "scale" se quiser mais de duas casas decimais echo "scale=2. do for FUNDO in `seq 0 7`..

"$2". Portanto dê uma olhada no exemplo a seguir. caso contrário "variavel" receberá '?'. } # observe que 'n' e 'e' precisam de argumentos .. 'b' ou 'c'. Se combinar com algum. "variavel" receberá este caractere. O getopts examina todos os argumentos da linha de comando procurando por argumentos que comecem com o caractere '-'.*/ <++> BashScript/getopts. veja Referências): 1.1.. Veja este exemplo hipotético: getopts 'ab:c' variavel Você poderá usar os parâmetros 'a'. Isto é útil para verificações em loops (como veremos no exemplo abaixo).. e "variavel" receberá este caractere. Mais detalhadamente. Quando acha um argumento começado com '-' o getopts procura em "CadeiaDeOpcoes" se tem algum caractere que combine. Para passar um parâmetro para o script você usa '-c' onde 'c' é o parâmetro. Os passos 1-3 são repetidos até que todos os argumentos da linha de comando tenham sido lidos. exit 1 . por sua vez. Confuso? Numa primeira olhada é confuso mesmo. isso significa que 'b' é um parâmetro que precisa de argumento. Quando acaba de ler todos os argumentos da linha de comando getops retorna um valor falso (não-zero). Não se esqueça de fazer o mais importante: praticar! /* ----------------. é armazenado na variável OPTARG.). 2. execute-o e depois releia este tópico.sh #!/bin/bash USAGE="Uso: `basename $0` [-h] [-n nome] [-e email]" [ $1 ] || { echo $USAGE . getopts ======= Este comando serve para permitir que você use parâmetros na linha de comando de maneira mais eficiente que ficar usando as variáveis de posição de parâmetros ("$1". é muita informação de uma vez só. Sua sintaxe é: getopts 'CadeiaDeOpcoes' variavel Onde "CadeiaDeOpcoes" consiste em cada caractere que o getopts considerará. Hmmm. 4. Este. 3. Note que 'b' é seguido de um ':'. 5. o getopts funciona assim (adaptado do "Teach Yourself Shell Programming in 24 Hours".7..

Você pode ver mais um script que usa getopts no tópico "Exemplos Variados".sh #!/bin/bash function Mecho { echo -e "\e[1m$*\e[m" } . esac done [ $NOME ] && echo $NOME [ $EMAIL ] && echo $EMAIL <--> /* ----------------.*/ Execute este código e tire suas próprias conclusões. do # atente para a utilidade do "case"! .-) case $PARAMETRO in h) echo -n " Script de exemplo de uso do \"getopts\".. select ====== Este comando serve para fazer menus. n) NOME=$OPTARG .while getopts 'hn:e:' PARAMETRO. Veja este exemplo: /* ----------------. 7.*/ <++> BashScript/conta.. Sua sintaxe é um pouco parecida com a do "for": select opcao in lista-de-opcoes A diferença é que o for faz um loop para cada palavra que estiver na "lista-de-opcoes" enquanto o select espera que o usuário escolha uma opção dentre as que estão na lista.2.." . onde o usuário pode escolher uma dentre várias opções. e) EMAIL=$OPTARG . Uso: `basename $0` [opções] Onde as opções podem ser: -n nome -e email -h imprime nome imprime email exibe esta mensagem" . *) echo -n "Entre \"`basename $0` -h\" para ajuda..

do if [ "$opc" = adicao ]. Agora vamos organizar as coisas.$NUM2 = $[ $NUM1 . a utilizada nesse comando é uma caixa do tipo "yesno". valem aqui também. dialog ====== AVISO: o dialog não um comando específico do bash! Estou escrevendo sobre ele porque já vi muita gente querendo informações sobre ele e porque eu particularmente acho ele uma fofura. isso foi só pra você dar uma admirada rápida no dialog. then Mecho "$NUM1 / $NUM2 = `echo "scale=2.. :-) O dialog serve para fazer caixas de diálogo. e a sintaxe básica é assim: dialog [ opcoes de título ] opções da caixa As opções de título são opcionais (por isso que elas estão entre colchetes. then Mecho "$NUM1 + $NUM2 = $[ $NUM1 + $NUM2 ]" elif [ "$opc" = subtracao ]. Para que você possa fazer agora uma apreciação visual do dialog tente o seguinte comando: dialog --yesno "Caixa onde se se escolhe Yes ou No" 0 0 Existem vários tipos de caixas.3. then Mecho "Tchau! " exit else Mecho "Opção inválida! " fi done <--> /* ----------------. duh!). E todas aqueles comentários sobre # o PS1 feitas no tópico 2.. não acha? .$NUM2 ]" elif [ "$opc" = multiplicacao ].*/ Bem prático. then Mecho "$NUM1 . PS3="Opção: " echo read echo read -n "Entre com o primeiro número: " NUM1 -n "Entre com o segundo número: " NUM2 OPCOES="adicao subtracao multiplicacao divisao sair" select opc in $OPCOES. vou explicar alguns parâmetros. as de caixa são obrigatórias. . Bem. then Mecho "$NUM1 * $NUM2 = $[ $NUM1 * $NUM2 ]" elif [ "$opc" = divisao ].-) 7.# ATENÇÃO AQUI: o prompt que o select mostra é controlado pela # variável PS3.2.$NUM1/$NUM2" | bc -l`" elif [ "$opc" = sair ].

que (por incrível que pareça) servem para você determinar a altura e largura da caixa de diálogo. * --yesno "texto" alt larg Faz uma caixa de diálogo com as opções "Yes" e "No". use 0 para altura e largura. retorna 0 e o outro retorna 1. retorna 1. Os botões são "OK" E "Cancel". portanto.3 Redirecionamento). =) * --title "texto" Este vai ser o título da caixa de diálogo. Use as . se selecionado. Se você não tiver saco pra ficar contando quantos caracteres serão usados na caixa. Quando você escolher "OK" o dialog retornará 0. eu chamarei de "alt" e "larg"). o primeiro. A string que você entrar será direcionada para a saída de erro padrão. * --msgbox "texto" alt larg Serve para mostrar uma mensagem e tem um botão de confirmação "OK". mas antes uma informação: Em todos os tipos de caixas existem os argumentos "altura" e "largura" (que para abreviar. * --inputbox "texto" alt larg [string de inicio] Faz uma caixa de entrada de dados.Vá praticando cada um desses parâmetros e vendo o resultado. Lembre-se que as opções da caixa são obrigatórias! * --backtitle "texto" Este parâmetro é para por um título "lá atrás". assim a caixa terá um tamanho de acordo com texto utilizado. assim como em todos os outros tipos de caixas. caso contrário. * --textbox arquivo alt larg É como se fosse um simples visualizador de arquivos texto. se você quer que isto seja gravado use redirecionamento de stderr (ver 3. Agora vamos as opções de caixa. se "string de inicio" for passada o campo de entrada de dados será inicializado por esta string. você pode cancelar via tecla ESC. quando o dialog retornará 255. Tente dialog --backtitle "Micro\$oft Scandisk" --yesno bla 0 0 e veja como o título que aparece lhe trará péssimas lembranças. Se você escolher "Yes" o dialog retorna 0. e.

"OK" retorna 0 e "Cancel" retorna 1. O item que for escolhido será impresso em stderr. você marca os que deseja e dá "OK". O parâmetro "status" serve para você deixar um determinado item selecionado logo de início.setinhas do teclado para se movimentar. Veja um exemplo besta só pra ilustrar: /* ----------------. Como o próprio nome diz. se não entender releia o código: . * --menu "texto" alt larg alt-do-menu item1 "descricao do item1" \ [ itemN "descricao do itemN" ] Note que aquela '\' lá no final da linha significa que o comando continua na próxima linha. esse parâmetro é usado para fazer menus. RET_VAL=$? [ $RET_VAL -eq 0 ] || { echo "Operação cancelada. seus valores podem ser "on" ou "off".*/ * --checklist "texto" alt larg alt-da-lista \ item1 "descricao do item1" status [ item2 "descricao do item2" status ] Note novamente o caractere '\' fazendo o comando continuar na linha abaixo. Veja este exemplo bem interessante (oh! finalmente um exemplo com alguma utilidade!) que usa muitos dos conceitos já ensinados até aqui.*/ <++> BashScript/menudialogtest. Este tipo de caixa é utilizado quando se quer fazer um menu onde pode-se escolher vários itens. } sh $FILE rm $FILE <--> /* ----------------. exit 1.sh #!/bin/bash FILE=/tmp/script-$$ dialog --title "Teste fuleiro da caixa de diálogo \"menu\"" \ --menu "Qual comando você deseja executar?" 0 0 0 \ "pwd" "mostra o diretório atual" \ "ps aux" "lista os processos que estão sendo executados" \ "uname -a" "exibe informações sobre o SO e a máquina local" \ "users" "lista os usuários que estão logados no momento" 2> $FILE # Lembre-se que o item escolhido será impresso em stderr.". o(s) item(ns) que for(em) escolhido(s) serão impressos em stderr. E repare # acima que eu estou redirecionando stderr para um arquivo. Para pesquisar pra frente use '/' e para pesquisar pra trás use '?'. Assim como o "--menu". como por exemplo aquele do pppsetup (slackware) onde você escolhe qual o ttyS do seu modem.

: Se o nome de alguma mp3 for muito grande podem acontecer # resultados bizarros. n) NOME="*$OPTARG" . do case $OPCAO in d) MP3DIR="$OPTARG" .cjb.*/ <++> BashScript/bacanas/mp3select. Pois se detectasse também ocorreriam resultados bizarros. # # Feito por: meleu <meleu@meleu..sh #!/bin/bash # # "Escolhedor" de mp3z feito para ilustrar o uso do 'dialog' # no texto "Programação em Bourne-Again Shell"... then . # # + OBS. #MP3DIR="$HOME/mp3z/" FILE="/tmp/mp3./* ----------------. *) exit 1 .$$" NCOR="\e[m" WHITE="\e[1m" function AjudarSair { echo "Tente \"`basename $0` -h\" para ajuda..)$NCOR Uso: `basename $0` [-d diretorio] [-n nome] [-h] -d diretorio diretório onde serão procuradas as mp3z -n nome nome que será procurado no diretório -h imprime esta mensagem " exit . h) echo -e " ${WHITE}* Meleu's mp3 escolheitor (Tabajara." exit $1 } function ApagarSair { rm $FILE exit $1 } # óia o getopts aê gente! =) while getopts 'd:n:h' OPCAO.. # # Para utilizar este script é necessário ter instalado o mpg123.II: Este script não "detecta" nome de mp3z que contenham # espaços.. Inc.net> # mude a variável MP3DIR e descomente-a para não # precisar passar o diretório toda hora na linha # de comando. :-/ # + OBS. esac done if [ -z "$MP3DIR" ].

mp3 2>/dev/null | grep -v ' '` [ -z "$LISTA" ] && { echo -e "${WHITE}Nenhuma mp3 foi encontrada em \"$MP3DIR\". } # verificando se já existe um processo com o mpg123 MPGPID=`ps ax --format pid. then kill $MPGPID 2>/dev/null || { echo -e "${WHITE}Não foi possível finalizar o mpg123.comm | grep mpg123 | cut -c-6` [ $MPGPID ] && { dialog --backtitle "Selecionador de mp3z" \ --title "O mpg123 JÁ ESTÁ SENDO USADO!" \ --yesno "Deseja finalizá-lo para ouvir a sua lista?" 0 0 RET_VAL=$? if [ $RET_VAL -eq 0 ].$NCOR" AjudarSair 1 elif [ ! -d "$MP3DIR" ]." ApagarSair 1 } else echo "Saindo. then echo -e "$WHITE\"$MP3DIR\" não é um diretório. ApagarSair.$NCOR" AjudarSair 1 fi cd "$MP3DIR" LISTA=`/bin/ls -1 $NOME*..*/ . do echo "$ITEM" "$CONT" off (( CONT++ )) done) 2>> $FILE RET_VAL=$? [ $RET_VAL -ne 0 ] && { echo "Tchau!"." ApagarSair fi } # o sleep é pra garantir que o /dev/dsp estará desocupado sleep 1s cat $FILE | xargs mpg123 2> /dev/null & ApagarSair # EoF # <--> /* ----------------.echo -e "${WHITE}Você precisa indicar em qual diretório estão as mp3z.$NCOR" echo "Pode ser que outro usuário esteja utilizando-o. $NCOR" AjudarSair 1 } CONT=1 dialog --backtitle "Selecionador de mp3z" \ --title "$MP3DIR" \ --checklist "Escolha a música" 0 0 0 \ $(for ITEM in $LISTA ..

* --radiolist "texto" alt larg alt-da-lista \ item1 "descricao do item1" status [ item2 "descricao do item2 status ] Similar ao --checklist porém aqui só se pode fazer uma escolha, quando você seleciona um item desmarca outro. Faça os testes por sua conta.

Chega de moleza! Se quiser saber mais leia a man page do dialog! ;)

------------------------------------------------------------------------

8. Coisas úteis de se aprender *************************** Não basta saber somente sobre o bash! Existem muitas outras coisas fora do bash que você deve usar pra aumentar o poder dos seus scripts. O meu público-alvo são os fuçadores e como tais eles não podem ter preguiça de ler as manpages. Vai lá cara... a manpage é uma grande amiga! ;-) Aqui vai uma lista do que seria bom de você aprender, o que está marcado com um asterisco quer dizer que é muito útil de aprender: + Linguagens: awk; *Expressões Regulares (ERs); + Comandos: *grep; *sed; *cut; tr; paste; sort; uniq; bc; *expr; *wc; eval (na manpage do bash); trap (idem); comm; join; netcat e lynx (ambos são muito úteis se você quer fazer scripts que usem o que a rede tem a nos oferecer. o netcat, vulgo nc, pode ser encontrado em <http://www.atstake.com/research/tools>). Cara... sabendo tudo isso, você já será um iniciado. A partir daí o que manda é a experiência, prática, prática e prática. Muita prática! Um dia eu ainda chego a esse nível... Eu sei que está na lista ali em cima, mas vale salientar: ERs, grep e sed são REALMENTE MÚITO ÚTEIS!!!

------------------------------------------------------------------------

9. Exemplos Variados

***************** É verdade que são poucos exemplos. Eu poderia ficar "enxendo lingüiça" metendo vários exemplos aqui e dizer que escrevi quatro mil linhas de texto, mas acho que não seria uma boa... Se você quer mais exemplos olhe as Referências (principalemente no Adv-Bash-Scr-HOWTO), entre na lista de discussão... enfim: se vire!

9.1. backup.sh ========= /* ----------------- */ <++> BashScript/bacanas/backup.sh #!/bin/bash # OBS.: Por favor melhore este script! :-) # Se o número de parâmetros for menor que 2... [ $# -lt 2 ] && { echo "Uso: `basename $0` destino origem [origem2 origem3...]" exit 1 # ... sai do script } echo "--> Fazendo backup" FILE="${1}_$(/bin/date +%d-%m-%Y).tgz" shift # Aqui está o "segredo": o shift acima é executado para que eu possa # usar "$*" no if abaixo. if tar czf $FILE $* ; then echo "--> Backup feito com sucesso" else echo "--> OCORREU UM ERRO <--" 1>&2 exit 1 fi <--> /* ----------------- */

9.2. howto.sh ======== /* ----------------- */ <++> BashScript/bacanas/howto.sh #!/bin/bash # # ********************************************* # * Script para visualizar HOWTOs rapidamente * # ********************************************* # http://meleu.da.ru # meleu <meleu@meleu.cjb.net> # # Inspirado em um outro script que vi no Tips-HOWTO. # O script do Tips-HOWTO era muito simples, fiz algumas # modificações que são interessantes para nós que falamos # português e de vez em quando temos uns HOWTOs traduzidos, # e ainda fiz um "suporte" aos mini-HOWTOs. ;-) # E mais: se você não lembra direito do nome do HOWTO, pode # passar apenas a(s) primeira(s) letra(s) e/ou usar os curingas

# ('*', '?' e '[]'), mas aconselha-se, neste último caso, o uso de # aspas ("quoting") para evitar que seja passado como parâmetro(s) # o conteúdo do diretório atual. Caso ele encontre mais de um # arquivo para a expressão você poderá escolher através da tela que # aparecerá. # Exemplos: # [prompt]$ howto Net # [prompt]$ howto "*[Bb]ash" # [prompt]$ howto "*Prog" # # Se você ainda não tem e não sabe onde pegar HOWTOs traduzidos # procure em http://ldp-br.conectiva.com.br # # Pré-requisitos para o script funcionar direitinho (ou seja, sem # precisar de alterações): # + os HOWTOs devem estar em "/usr/doc/Linux-HOWTOs"; # + os HOWTOs em português devem estar em "/usr/doc/LinuxHOWTOs.pt"; # + os mini-HOWTOs devem estar em "/usr/doc/Linux-mini-HOWTOs"; # + todos os [mini-]HOWTOs[.pt] devem estar gzipados, se os seus não # estão assim basta entrar no diretório dos HOWTOs e digitar # "gzip *". # # # Se você testou o script, ele funcionou direitinho e você gostou, # então digite "cp howto.sh /usr/local/bin/howto" para que todos do # seu sistema possam utilizá-lo. ;-) # # Aproveite! # Estes são os diretórios onde são instalados os [mini-]HOWTOs no # Slackware. Se a sua distribuição usa um diretório diferente # mude a(s) variável(is) a seguir. HTDIR=/usr/doc/Linux-HOWTOs miniHTDIR=/usr/doc/Linux-mini-HOWTOs PTHTDIR=/usr/doc/Linux-HOWTOs.pt # este é onde eu coloco os traduzidos # Variáveis que indicam as cores (pra não precisar ficar # digitando os códigos ANSI toda hora) BLUE="\e[1;34m" RED="\e[1;31m" NCOLOR="\e[m" function Ler { zless $1 echo -e "${RED}\nTchau!\n$NCOLOR" exit } # Função que mostra a lista dos HOWTOs e sai do script. function Lista { ls -C $HTDIR | less echo -e " ${BLUE}Uso:$NCOLOR `basename $0` [-p | -m] nome-do-HOWTO Faça '`basename $0` -h' para ver a descrição das opções." exit 1

} # se não for passado nenhum parâmetro ele mostra a lista [ -z "$1" ] && Lista # -------------------# ..mensagem de ajuda # ---------------------h) echo -e " ${RED}--[ Lista de opções ]--$NCOLOR -p \t HOWTOs em português -m \t mini-HOWTOs -h \t imprime esta mensagem " exit # depois da mensagem de ajuda. esac # Ao fim deste case $1 tem necessariamente o nome ou a(s) # primeira(s) letra(s) do nome do HOWTO a ser procurado. # ..TESTA PARÂMETROS # -------------------case $1 in # . cd $HTDIR FILE=`ls $1*.gz 2>/dev/null` [ `echo $FILE | wc -w` -gt 1 ] && { PS3="Entre com o número: " select opc in $FILE Sair . do [ "$opc" = "Sair" ] && exit for HOWTO in $FILE . # . sair ..HOWTOs em português # -----------------------p) HTDIR=$PTHTDIR [ -z "$2" ] && Lista shift # Lembra do 'shift'? Aqui ele faz com que o primeiro # parâmetro deixe de ser '-p' para ser o nome-do-HOWTO .mini-HOWTOs # ---------------m) HTDIR=$miniHTDIR [ -z "$2" ] && Lista shift # mesma função do shift no '-p' . do [ "$opc" = "$HOWTO" ] && Ler $HOWTO done done } [ -e "$FILE" ] && Ler $FILE # Isto só será executado se não for encontrado o HOWTO .

sh ========= /* ----------------.sh #!/bin/bash # .*/ 9.ToDo" USAGE="Uso: $PROG [-h|-e]" case $1 in -h) echo " $USAGE -e -h edita a lista de \"Para Fazer\" (To Do) imprime esta mensagem e sai Sem parâmetros $PROG irá mostrar a lista de \"To-Do\". inseretxt..ToDo" echo "Para ajuda tente \"$PROG -h\"" exit 1 } .3.= < E O F > = <--> /* ----------------. esac <--> /* ----------------. *) echo echo echo exit "Parâmetro \"$1\" desconhecido!" "$USAGE" "Entre com \"$PROG -h\" para ajuda.sh #!/bin/bash PROG=`basename $0` EDITOR=`which vi` FILE="$HOME/.*/ <++> BashScript/bacanas/inseretxt.sh ======= /* ----------------." .*/ <++> BashScript/bacanas/todo.ToDo !" echo "Entre \"$PROG -e\" para editar seu ~/.. todo. '') cat $FILE 2> /dev/null || { echo "Você precisa criar o arquivo $HOME/. -e) $EDITOR $FILE exit .*/ 9.echo -e "${RED}* * * HOWTO não encontrado * * *$NCOLOR" echo "Tente '`basename $0` [-p | -m]' para ver a lista" exit 1 # . " exit ..4..

eu escrevi este script.-) meleu. Se você passar como o parâmetro "linha" um número maior que o de linhas total do "ArqOriginal" os "arquivosN" serão inseridos no final do "ArqOriginal". Para fazer isso de uma maneira mais cômoda.1 2>/dev/null` -ge 0 ] 2>/dev/null || { echo -e ${B}Erro: O primeiro parâmetro precisa ser inteiro positivo$N echo $AJUDA exit 1 } ArqOriginal=$2 [ -f $ArqOriginal ] || { echo -e ${B}Erro: \"$ArqOriginal\" não existe ou não é um arquivo regular$N .$N $USO Onde: \"linha\" é a linha onde o texto será inserido \"ArqOriginal\" é o arquivo que receberá os textos \"arquivoN\" são os arquivos que serão inseridos em ArqOriginal " exit } [ $# -lt echo echo echo exit } 3 ] && { -e ${B}Erro: erro na passagem de parâmetros$N $USO $AJUDA -1 Linha=$1 # verificando se $Linha é um número inteiro positivo [ `expr $Linha .. Para informações sobre o uso tente o parâmetro '-h' ou '--help'.# # # # # # # # # # # # # # # # # # # # Muitas vezes durante a escrita do texto "Programação em Bourne-Again Shell" eu precisava inserir um código de um script numa determinada posição do arquivo e esta posição ficava entre muito texto antes e depois dessa linha.. E lembre-se de mais uma coisa: 0 não é um número positivo. Ah! Lembre-se de uma coisa: "linha" precisa ser um inteiro positivo. .]" AJUDA="Tente \"`basename $0` --help\" para ajuda" [ "$1" = '-h' -o "$1" = '--help' ] && { echo -e " ${B}Insere o conteúdo de arquivo(s) dentro de um outro. B="\e[1m" N="\e[m" USO="Uso: `basename $0` linha ArqOriginal arquivo1 [arquivoN .

$N read -n 1 -p "Deseja sobregravá-lo? (s/N) " SN echo [ "$SN" != 'S' -a "$SN" != 's' ] && { echo -e "$B\nOperação cancelada!$N" ApagarSair $Temp 3 } } cat $Temp > $ArqFinal echo -e " ${B}Operação concluída com sucesso. final do arquivo original: sed -n "$Linha. do [ -f "$Arq" ] || { echo -e ${B}OBS.} echo $AJUDA exit 2 function ApagarSair { rm "$1" exit $2 } shift 2 Temp=/tmp/`basename $ArqOriginal`-$$.\$p" $ArqOriginal >> $Temp ArqFinal="$ArqOriginal.tmp # --> início do arquivo original: head -$[$Linha-1] $ArqOriginal > $Temp # --> arquivos que serão inseridos: ContaAcerto=0 for Arq in "$@".: \"$Arq\" não existe ou não é um arquivo regular$N continue } cat $Arq >> $Temp (( ContaAcerto++ )) done [ $ContaAcerto -eq 0 ] && { echo -e ${B}Nenhum arquivo foi inserido em \"$ArqOriginal\"$N ApagarSair $Temp 3 } echo # --> pra terminar.*/ .$N Confira em \"$ArqFinal\" " ApagarSair $Temp <--> /* ----------------.new" [ -e $ArqFinal ] && { echo -e ${B}Já existe um arquivo chamado \"$ArqFinal\".

Mextract.2.ru # # Este script é baseado no Phrack Extraction Utility.sh =========== /* ----------------. read) serve para ignorar o # poder que a contra-barra (backslash) tem de "escapar" os caracteres. TAB.2.*/ <++> BashScript/bacanas/Mextract. # neste script eu usei o IFS com valor nulo (vazio) para que os comandos # considerem espaços que vêm antes de qualquer caractere como parte do # dado. Redirecionando loops" sob o título de "pipeando para o while". segundo para # servir como mais um exemplo no texto "Programação em Bourne-Again Shell". você verá que eles serão desconsiderados # se o IFS tiver seu valor default (espaço. ############# alterar o(s) código(s) extraído(s) e extrair novamente. =P # ############# Se já existirem arquivos com o nome dos que serão extraídos # !CUIDADO! # eles serão sobregravados! Portanto. newline). # # + O cat enviando os dados para o read do while é explicado em # "5. # # # + A função do IFS é explicada no tópico "2. Se você fizer por exemplo "read var" e antes de entrar qualquer # coisa colocar espaços e/ou TAB. conforme explicado em . # e último para extração dos códigos do texto. # # + o set é usado para fazer com que cada palavra (palavra aqui tem um # sentido de conjunto de caracteres separados por aqueles definidos no # IFS) vire um parâmetro posicional.da. primeiro para praticar. se você extrair uma vez.phrack. Em # outras palavras: a opção -r garante que quando o read receber uma # contra-barra ela será passada para a variável sem nenhum valor especial. (mais informações # <http://www. # perderá as alterações feitas! # # # A seguir eu vou comentar sobre o código fazendo referência aos tópicos # do texto "Programação em Bourne-Again Shell".5. Fiz ele.5.org>).sh #!/bin/sh # # **************************** # * Meleu Extraction Utility * # **************************** # http://meleu. Variáveis do Shell". # # + A opção -r no read (explicada em 3.9.

Se existir. esta opção serve para prevenir que alguma # informação que comece com o caractere . Tente # também fazer meios de detecção dos possíveis erros que possam # ocorrer. # # + Bom. ] || { echo -e "${B}Erro: você não tem permissão de escrita neste diretório$N" exit 1 } OldIFS="$IFS" IFS= cat $@ | while read -r LINHA . Leia o código. acho que é isso. faça testes. Substituição de Variáveis" você verá a explicação # de se usar "FILE=${FILE:-.seja considerado uma opção # sendo passada para o set. A opção -. # Ah. set (para editar parâmetros posicionais)". alertar o usuário sobre isso. use o método hacker de # aprender a programar! .quer dizer # "acabaram as opções. # mude o código. Enfim.-) # # # Espero que curta! # meleu <meleu@meleu.4.: Quer um "dever de casa"? Altere o código para que ele verifique # se já existe arquivos com o mesmo nome dos que estão prestes a # serem extraídos.net> # # P. sei lá! Brinque com o código um pouco! =) # B="\e[1m" N="\e[m" [ $# -lt echo echo exit } 1 ] && { -e "${B}Erro: falta parâmetros$N" "Uso: `basename $0` arquivo1 [arquivoN]" 1 [ -w . do FILE=${FILE:-.2. execute-o novamente...5.}/$1 .cjb.$LINHA case "$1" in '<++>') TempIFS="$IFS" IFS=/ set -.# "2.. # leia as manpages em caso de dúvidas. o que vier a partir daqui são os valores dos # parâmetros de posição". # # + No tópico "2. do IFS="$OldIFS" set -. execute-o.. veja o que mudou nos resultados.}/$1".$2 IFS="$TempIFS" while [ $# -gt 1 ]...S.

ensina também a usar cores no console através de códigos de escape ANSI. then echo "* Extraindo $FILE" else echo -e "$B--> houve um erro ao tentar extrair echo -e " unset FILE fi este arquivo será ignorado. Muito bom pra quem está começando neste sistema.*/ ------------------------------------------------------------------------ 10. Adv-Bash-Scr-HOWTO ---> Este já é mais avançado. Referências *********** Guia focalinux --> Na endereço a seguir você encontrará ótimos guias sobre o GNU/Linux.focalinux.$N" [ -d $FILE ] || mkdir $FILE shift . divididos em níveis (iniciante.org Bash-Prog-Intro-HOWTO ---> Bem prático e objetivo. '<-->') . Se você quer realmente se aprofundar no assunto este é o texto que deve . bom pra começar (foi com ele que eu comecei).'$FILE'" done FILE="${FILE:-..}/$1" if echo -n 2>/dev/null > $FILE .. intermediário e avançado). http://www.. *) [ "$FILE" ] && { IFS= echo "$LINHA" >> $FILE } unset FILE . Bash-Prompt-HOWTO ---> Texto bacana que ensina a fazer coisinhas bonitas com o prompt. esac done echo "--> Fim <--" <--> /* ----------------.

html sh.net sed-HOWTO --> Um ótimo texto ensinando sobre o sed! Outra leitura obrigatória! (e outro produto fabricado sob a chancela do aurélio! esse cara deve estar com o saco esticadinho de tanto que eu puxo.br --> Contém alguns materiais legais e scripts de exemplos. o livro é bonzinho. O começo é meio chato. Pode ser encontrado em http://unsekurity.gnu.jonathas.br/manualshell. Veja em http://www.txt Teach Yourself Shell Programming in 24 Hours --> Apesar do título presunçoso.torget.html Bourne-Again SHell Home Page --> Página oficial do Bourne-Again Shell em: http://cnswww. Leitura obrigatória! (esse aurélio é demais mesmo!) =) http://guia-er.underlinux. http://www.em ler! Muitos códigos para se ler e aprender! Todos estes três HOWTOs podem ser encontrados http://www.cwru.underlinux.. Versão online em . =D ) http://verde666/sed Lista de discussão sobre ShellScript --> Precisa falar algo? :P http://br.02/bashref.com.. muito útil! http://sh. Tem algumas coisas interessantes.se/users/d/Devlin/ shell Bash FAQ --> dispensa descrições.br Expressões Regulares --> Um guia sobre expressões regulares (sim! em português!).edu/~chet/bash/bashtop.sourceforge.org/manual/bash2.virtualave.linuxdoc. mas mesmo assim me foi útil.com/group/shellscript Programação em Shell Script --> um texto feito pelo xf.com. ftp://ftp.yahoo. mas depois tem algumas coisas úteis.cwru.com. txt UNIX Bourne Shell Programming --> meio antiguinho (1991).org ou se preferir /usr/doc/Linux-HOWTOs Programação de Shell Scripts --> um texto introdutório feito pelo Nibble.edu/pub/bash/FAQ Bash Reference Manual --> documentação oficial da GNU http://www.net/txts/shscript.groups.cns.

) [aê Julio. Só compre o livro se tiver preguiça de fuçar essa rede maravilhosa que nós temos. Não é pra boicotar o livro! Meta a cara numas bibliotecas e pegue-o pra consultar! (de preferência sem gastar dinheiro..-> Dê uma olhada aqui se quiser saber sobre www.online.bg/OS/unix_power_tools/index.cs.tuiasi.http://library.phrack. diga-se de passagem... Eu encontrei alguns dados errados e/ou incoerentes no livro.ufrj. http://www.brasport.html UNIX Power Tools -> Livro muito bom com várias matérias sobre UNIX em geral.coppe.-) ] Editora: Brasport http://www. você pode aprender as mesmas coisas e muito mais..org (acho que o Meleu Extraction Utility pode perfeitamente suprir suas necessidades. e até mesmo nas manpages. Tem um capítulo sobre shell scripting. Deve haver muitos casos parecidos neste meu texto aqui.ht m Linux: Programação Shell -> Um livrinho interessante que ensina umas coisas legais sobre shellscript.absoluta. assunto que. por favor não me odeie! .org ---------' .org Phrack Extraction Utility --> O utilitário para extração dos códigos-fonte contidos neste texto pode ser encontrado na última versão da Phrack em http://www. =P O ponto forte do livro é o Apêndice sobre o awk. http://docs. mas isso acontece.. pode encontrar por exemplo um material introdutório à awk.pulltheplug.lockabit. www..com --------| wargames.com. Espero que o autor do livro não me odeie pelo que eu vou falar agora (só estou sendo sincero): não vale a pena comprar o livro se você tem acesso a internet! Na net. mas é bom lembrar que os créditos são da Phrack) www.br Autor: Julio Cezar Neves ISBN: 85-7452-076-4 Verdade Absoluta --> Você poderá encontrar um material diversificado sobre UNIX. é muito difícil de encontrar em português.ro/0/linux-unixprogramming.hackerslab.br -.

. Bom.htm http://verde666. num computador com uma configuração de hardware razoável e que daqui a alguns meses já será considerada por muitos como "imprestável".. chega de ficar me lamentando! Vou parar de lamentar e ficar mais um ano estudando.. sem ganhar nada.com.. Já parou pra ver como que os FreeSoftwares rodam bem em máquinas que não são das mais "turbinadas"? Por que será que os softwares da Micro$oft precisam de hardware cada vez mais potentes? Um programador que trabalha na Micro$oft não deve ser nenhum José Mané.org http://meleu. Considerações Finais ******************** OBS. Deixa eu contar uma coisa.. será que ele não tem capacidade de escrever um software levinho? Será que essas megaempresas . Deve ser porque eu pequei demais e tenho que ficar mais um ano pagando por isso.inf. UFA!! Deve fazer aproximadamente um ano que eu comecei a escrever este texto! É isso mesmo! E aí cheguei naquela fase de nossa vida onde pagamos por nossos pecados: vestibular.html http://sh..underlinux..da... É apenas uma conversa. que a gente é otário de ficar trabalhando de graça.net http://eoh-team. Sabe de uma coisa?..br/~asr98/linux/scripts_prog. E sabe por quê? Software Livre meu caro. Não adiantou muita coisa.br/src/index..ru Outros endereços interessantes: ~~~~~~ ~~~~~~~~~ ~~~~~~~~~~~~~ http://unsekurity.. As vezes conversando com outras pessoas sobre o movimento FreeSoftware algumas acham que é maluquice. Software Livre. ficava estudando pro vest o tempo todo não tinha tempo pra ficar no computador.virtualave.. eu não passei. Mas veja bem: "considerada por muitos"..tk ------------------------------------------------------------------------ 11. Cheguei a pensar que nunca ia terminar este texto.Você ainda pode aprender muito lendo outros códigos prontos! Veja alguns em: http://www. Pra mim essa máquina ainda vai durar alguns anos com esta mesma configuração. Eu estou aqui.: Nesta seção não tem nada sobre shell script.ufpr.

A única coisa que o FreeSoftware precisa fazer é aquilo que ele se presta a fazer. UAU!! Quanto dinheiro economizado!!! Agora vamos mais longe.. Mas voltando ao FreeSoftware. E se o governo investisse o que devia em educação não iria precisar ficar inventando essa tal de cota pra gente que tem pele dessa ou daquela cor.de software não têm algum esquema com megaempresas de hardware? Estes softwares são pesados porque necessitam ser assim ou isso é de propósito? Ficam essas perguntas no ar. né? Agora pense no dinheiro gasto com as licenças. Minha modesta maquininha aqui vai durar anos porque eu uso FreeSoftware e esse tipo de software não precisa ser pesado. mora? Algumas pessoas amam programar. E se o cara pegou um programa e gostou muito dele. Agora uma coisa que você pode não ter pensado é que esse dinheiro é PÚ-BLI-CO! É seu dinheiro! É nosso dinheiro! Se o governo usasse Software Livre. Muito também.. Micro$oft Office... não precisa derrubar o concorrente. Outra coisa interessante é que você não precisa pagar pelo FreeSoftware! Isso mesmo! Não precisa pagar pelo software!! Você estuda numa escola que tem um laboratório de informática? Já parou pra pensar em quanto dinheiro foi gasto para pagar a licença de todas aquelas máquinas rodando Micro$oft Windows. não gastaria rios de dinheiro com licenças de softwares proprietários. Mas por que diabos uma pessoa faz FreeSoftware? Vou responder de uma maneira que pessoas de qualquer idade e qualquer região do Brasil entendenda: Porque programar é legal! É arretado de bão! É maneiro! É bacana! É massa! É bom pra chuchu! É uma brasa.. . aqueles profissionais que formarão os profissionais de amanhã. Dando mais valor aos professores. tente mentalizar quantos computadores existem nestes departamentos. Pois FreeSoftware tem que ter código-fonte. não precisa ter interfaces que encham nossos olhos com tanta beleza. mas acha que está faltando aquela funcionalidade.. por exemplo.. E também amam quando alguém gosta de seus programas. E o dinheiro economizado poderia ser investido. Muitos. etc.. amam mais ainda quando muitas pessoas usam e gostam de seus programas. Imagine se todas aquelas máquinas usassem Software Livre. As pessoas teriam acesso a educação e chances para aprender a ser um bom profissional. não precisa de marketing. Imagine os departamentos públicos. no setor de educação básica. Sem firulas ou outras gracinhas. Ele pode pegar o código-fonte e implementar a funcionalidade desejada por si próprio.

------------------------------------------------------------------------ . Quando ele precisar pagar suas contas ele vai mudar de idéia. o meleu é tão sonhador. disponibilizando material pra você usar livremente. E aqui estou eu. É por causa deles que você usa a Internet. com material preparado por estes "malucos". E é por causa desses "malucos-que-trabalham-de-graça" que eu sei tudo que sei. da maneira que achar melhor! Espero que você também se torne uma dessas pessoas que acham que podem fazer algum trabalho de útil para outras pessoas e não ficar apenas se preocupando em acumular riquezas.Algumas pessoas podem falar "Ai que gracinha. mais um "maluco-que-trabalha-de-graça". é por causa de "sonhadores" como eu que você está lendo esse texto.. Mais informações sobre FreeSoftware em http://www. tudo que aprendi veio da Internet. Eu não tenho dinheiro pra gastar fazendo cursos." ou até mesmo "Putz! Coitado desse meleu..".org Como diriam "nuestros hermanos": Hasta luego.gnu. Bom.

Sign up to vote on this title
UsefulNot useful