SlideShare ist ein Scribd-Unternehmen logo
1 von 6
Downloaden Sie, um offline zu lesen
Linux User                                      Papo de botequim




                                                                         Papo de Botequim
                                                                         Curso de Shell Script



                                                                                                                                   Parte VIII

                                            Dave Hamilton - www.sxc.hu
                                                                         Chegou a hora de fazer como Jack e dividir os programas
                                                                         em pedacinhos. Com funções e chamadas externas
                                                                         os scripts ficam menores, a manutenção mais fácil
                                                                         e ainda por cima reaproveitamos código.
                                                                         por Júlio Cezar Neves




       E
             aê, cara, tudo bem?                                         posicionais ($1, $2, …, $n). Todas as regras que se aplicam
 –            – Tudo beleza! Eu queria te mostrar o que fi z mas já sei
                que você vai querer molhar o bico primeiro, né?
                                                                         à passagem de parâmetros para programas também valem para
                                                                         funções, mas é muito importante realçar que os parâmetros
       – Só pra te contrariar, hoje não quero. Vai, mostra logo aí       passados para um programa não se confundem com aqueles
        o que você fez.                                                  que são passados para suas funções. Isso significa, por exem-
       – Poxa, o exercício que você passou é muito grande. Dá uma        plo, que o $1 de um script é diferente do $1 de uma de suas
        olhada na listagem 1 e vê como eu resolvi:                       funções internas.
       – É, o programa tá legal, tá todo estruturadinho, mas gosta-         Repare que as variáveis $Msg, $TamMsg e $Col são de uso
        ria de fazer alguns poucos comentários: só para relembrar, restrito dessa rotina e, por isso, foram criadas como variáveis
        as seguintes construções: [ ! $Album ] && e [ $Musica ]          locais. A razão é simplesmente a economia de memória, já que
        || representam a mesma coisa, isto é: no caso da primeira,       ao sair da rotina elas serão devidamente detonadas, coisa que
        testamos se a variável $Album não (!) tem nada dentro, então     não aconteceria se eu não tivesse usado esse artifício.
        (&&)… Na segunda, testamos se $Musica tem algum dado,               A linha de código que cria a variável local Msg concatena ao
        senão (||)…                                                      texto recebido ($1) um parêntese, a resposta padrão ($2) em
        Se você reclamou do tamanho do programa, é porque ainda          caixa alta, uma barra, a outra resposta ($3) em caixa baixa
     não te dei algumas dicas. Repare que a maior parte do script        e fi naliza fechando o parêntese. Uso essa convenção para, ao
     é para mostrar mensagens centraliza-
     das na penúltima linha da tela. Repare                                     Listagem 1: musinc5.sh
     ainda que algumas mensagens pedem
                                                01 $ cat musinc5.sh
     um S ou um N como resposta e outras
                                                02 #!/bin/bash
     são só de advertência. Isso é um caso
                                                03 # Cadastra CDs (versao 5)
     típico que pede o uso de funções, que
                                                04 #
     seriam escritas somente uma vez e
                                                05 clear
     executadas em diversos pontos do
                                                06 LinhaMesg=$((`tput lines` - 3)) # Linha onde serão mostradas as msgs para o operador
     script. Vou montar duas funções para
                                                07 TotCols=$(tput cols)             # Qtd colunas da tela para enquadrar msgs
     resolver esses casos e vamos incor-
                                                08 echo “
     porá-las ao seu programa para ver o
                                                                                      Inclusão de Músicas
     resultado fi nal.
                                                                                      ======== == =======
       – Chico! Agora traz dois chopes, um
                                                                     Título do Álbum:
        sem colarinho, para me dar inspira-
                                                                                            | Este campo foi
        ção. E você, de olho na listagem 2.
                                                                     Faixa:                < criado somente para
        Como podemos ver, uma função é
                                                                                            | orientar o preenchimento
     defi nida quando digitamos nome_da_
                                                                     Nome da Música:
     função () e todo o seu corpo está
                                                                     Intérprete:”              # Tela montada com um único echo
     entre chaves ({}). Já conversamos aqui
                                                09 while true
     no boteco sobre passagem de parâ-
                                                10 do
     metros e as funções os recebem da
                                                11     tput cup 5 38; tput el     # Posiciona e limpa linha                             ➟
     mesma forma, isto é, são parâmetros


86    maio 2005                      edição 08
                                                                         www.linuxmagazine.com.br
papo de botequim               Linux User



12    read Album                                                                              mesmo tempo, mostrar as opções dis-
13    [ ! “$Album” ] &&         # Operador deu <ENTER>                                        poníveis e realçar a resposta oferecida
14        {                                                                                   como padrão.
15            Msg=”Deseja Terminar? (S/n)”                                                      Quase no fim da rotina, a resposta
16            TamMsg=${#Msg}                                                                  recebida ($SN) é convertida para caixa
17            Col=$(((TotCols - TamMsg) / 2))        # Centraliza msg na linha                baixa (minúsculas) de forma que no
18            tput cup $LinhaMesg $Col                                                        corpo do programa não precisemos
19            echo “$Msg”                                                                     fazer esse teste. Veja na listagem 3
20            tput cup $LinhaMesg $((Col + TamMsg + 1))                                       como ficaria a função para exibir uma
21            read -n1 SN                                                                     mensagem na tela.
22            tput cup $LinhaMesg $Col; tput el      # Apaga msg da tela                        Essa é uma outra forma de definir
23            [ $SN = “N” -o $SN = “n” ] && continue # $SN é igual a N ou (-o) n?             uma função: não a chamamos, como
24            clear; exit                            # Fim da execução                        no exemplo anterior, usando uma
25        }                                                                                   construção com a sintaxe nome_da_
26    grep “^$Album^” musicas > /dev/null &&                                                 função (), mas sim como function
27        {                                                                                   nome_da_função. Em nada mais ela
28            Msg=”Este álbum já está cadastrado”                                             difere da anterior, exceto que, como
29            TamMsg=${#Msg}                                                                  consta dos comentários, usamos a
30            Col=$(((TotCols - TamMsg) / 2))        # Centraliza msg na linha                variável $* que, como já sabemos,
31            tput cup $LinhaMesg $Col                                                        representa o conjunto de todos os
32            echo “$Msg”                                                                     parâmetros passados ao script, para
33            read -n1                                                                        que o programador não precise usar
34            tput cup $LinhaMesg $Col; tput el      # Apaga msg da tela                      aspas envolvendo a mensagem que
35            continue                               # Volta para ler outro álbum             deseja passar à função.
36        }                                                                                     Para terminar com esse blá-blá-blá,
37    Reg=”$Album^”                         # $Reg receberá os dados para gravação            vamos ver na listagem 4 as alterações
38    oArtista=                             # Variável que guarda artista anterior            no programa quando usamos o con-
39    while true                                                                              ceito de funções:
40    do                                                                                        Repare que a estrutura do script
41        ((Faixa++))                                                                         segue a ordem Variáveis Globais, Fun-
42        tput cup 7 38                                                                       ções e Corpo do Programa. Esta estrutu-
43        echo $Faixa                                                                         ração se deve ao fato de Shell Script ser
44        tput cup 9 38                     # Posiciona para ler música                       uma linguagem interpretada, em que
45        read Musica
                                                                                              o programa é lido da esquerda para
46        [ “$Musica” ] ||                  # Se o operador tiver dado <ENTER>...
                                                                                              a direita e de cima para baixo. Para
47            {
                                                                                              ser vista pelo script e suas funções,
48               Msg=”Fim de Álbum? (S/n)”
                                                                                              uma variável deve ser declarada (ou
49               TamMsg=${#Msg}
                                                                                              inicializada, como preferem alguns)
50               Col=$(((TotCols - TamMsg) / 2))        # Centraliza msg na linha
                                                                                              antes de qualquer outra coisa. Por sua
51               tput cup $LinhaMesg $Col
                                                                                              vez, as funções devem ser declaradas
52               echo “$Msg”
                                                                                              antes do corpo do programa propria-
53                 tput cup $LinhaMesg $((Col + TamMsg + 1)
                                                                                              mente dito. A explicação é simples: o
54                 read -n1 SN
                                                                                              interpretador de comandos do shell
55                 tput cup $LinhaMesg $Col; tput el      # Apaga msg da tela
                                                                                              deve saber do que se trata a função
56                 [ “$SN” = N -o “$SN” = n ] && continue # $SN é igual a N ou (-o) n?
                                                                                              antes que ela seja chamada no pro-
57                 break                                  # Sai do loop para gravar
                                                                                              grama principal.
58              }
                                                                                                Uma coisa bacana na criação de fun-
59          tput cup 11 38                             # Posiciona para ler Artista
                                                                                              ções é fazê-las tão genéricas quanto
60          [ “$oArtista” ] && echo -n “($oArtista) “ # Artista anterior é default
                                                                                              possível, de forma que possam ser
61          read Artista
                                                                                              reutilizadas em outros scripts e apli-
62          [ “$Artista” ] && oArtista=”$Artista”
                                                                                              cativos sem a necessidade de reinven-
63          Reg=”$Reg$oArtista~$Musica:”          # Montando registro
                                                                                              tarmos a roda. As duas funções que
64          tput cup 9 38; tput el                # Apaga Música da tela
                                                                                              acabamos de ver são bons exemplos,
65          tput cup 11 38; tput el               # Apaga Artista da tela
                                                                                              pois é difícil um script de entrada de
66     done
                                                                                              dados que não use uma rotina como
67     echo “$Reg” >> musicas                     # Grava registro no fim do arquivo
                                                                                              a MandaMsg ou que não interaja com
38     sort musicas -0 musicas                    # Classifica o arquivo
                                                                                              o operador por meio de algo seme-
69 done
                                                                                              lhante à Pergunta.


                                                                                            maio 2005                       edição 08     87
                                                                 www.linuxmagazine.com.br
Linux User                Papo de botequim




       Conselho de amigo: crie um arquivo e anexe a ele cada fun-            diretório /home. Só que assim que a execução do script termi-
     ção nova que você criar. Ao final de algum tempo você terá               nou, o sub-shell foi para o beleléu e, com ele, todo o ambiente
     uma bela biblioteca de funções que lhe poupará muito tempo              criado. Agora preste atenção no exemplo abaixo e veja como a
     de programação.                                                         coisa muda de figura:

     O comando source                                                        $ source script_bobo
     Veja se você nota algo de diferente na saída do ls a seguir:            jneves    juliana   paula      silvie
                                                                             $ pwd
     $ ls -la .bash_profile                                                  /home
     -rw-r--r-- 1 Julio unknown    4511 Mar 18 17:45 .bash_profile           $ cd -
                                                                             /home/jneves
       Não olhe a resposta não, volte a prestar atenção! Bem, já que      $ . script_bobo
     você está mesmo sem saco de pensar e prefere ler a resposta,         jneves    juliana paula       silvie
     vou te dar uma dica: acho que você já sabe que o .bash_pro-          $ pwd
     file é um dos scripts que são automaticamente executados             /home
     quando você se “loga” (ARRGGHH! Odeio
     esse termo!) no sistema. Agora olhe nova-                                Listagem 2: Função Pergunta
     mente para a saída do comando ls e me
                                                    01 Pergunta ()
     diga o que há de diferente nela.
                                                    02     {
       Como eu disse, o .bash_profile é exe-
                                                    03       # A função recebe 3 parâmetros na seguinte ordem:
     cutado durante o logon, mas repare que ele
     não tem nenhuma permissão de execução.         04       # $1 - Mensagem a ser mostrada na tela
     Isso acontece porque se você o executasse      05       # $2 - Valor a ser aceito com resposta padrão
     como qualquer outro script careta, no fim       06       # $3 - O outro valor aceito
     de sua execução todo o ambiente por ele        07       # Supondo que $1=Aceita?, $2=s e $3=n, a linha a
     gerado morreria junto com o shell sob o        08       # seguir colocaria em Msg o valor “Aceita? (S/n)”
     qual ele foi executado (você se lembra de      09       local Msg=”$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)”
     que todos os scripts são executados em         10       local TamMsg=${#Msg}
     sub-shells, né?). Pois é para coisas assim     11       local Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha
     que existe o comando source, também            12       tput cup $LinhaMesg $Col
     conhecido por “.” (ponto). Este comando        13       echo “$Msg”
     faz com que o script que lhe for passado       14       tput cup $LinhaMesg $((Col + TamMsg + 1))
     como parâmetro não seja executado em           15       read -n1 SN
     um sub-shell. Mas é melhor um exemplo          16       [ ! $SN ] && SN=$2                     # Se vazia coloca default em SN
     que uma explicação em 453 palavras. Veja       17       echo $SN | tr A-Z a-z                  # A saída de SN será em minúscula
     o scriptzinho a seguir:                        18       tput cup $LinhaMesg $Col; tput el      # Apaga msg da tela
                                                    19         return                                    # Sai da função
     $ cat script_bobo                              20     }
     cd ..
     ls
                                                                               Listagem 3: Função MandaMsg
       Ele simplesmente deveria ir para o dire-
                                                    01 function MandaMsg
     tório acima do diretório atual. Vamos
                                                    02     {
     executar uns comandos envolvendo o
                                                    03          # A função recebe somente um parâmetro
     script_bobo e analisar os resultados:
                                                    04          # com a mensagem que se deseja exibir.
                                                    05          # para não obrigar o programador a passar
     $ pwd
                                                    06          # a msg entre aspas, usaremos $* (todos
     /home/jneves
                                                    07          # os parâmetros, lembra?) e não $1.
     $ script_bobo
                                                    08          local Msg=”$*”
     jneves    juliana   paula     silvie
                                                    09          local TamMsg=${#Msg}
     $ pwd
                                                    10          local Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha
     /home/jneves
                                                    11          tput cup $LinhaMesg $Col
                                                    12          echo “$Msg”
       Se eu mandei ele subir um diretório,
                                                    13          read -n1
     por que não subiu? Opa, peraí que subiu
                                                    14          tput cup $LinhaMesg $Col; tput el      # Apaga msg da tela
     sim! O sub-shell que foi criado para exe-
                                                    15          return                                 # Sai da função
     cutar o script tanto subiu que listou os
                                                    16     }
     diretórios dos quatro usuários abaixo do


88    maio 2005                       edição 08
                                                  www.linuxmagazine.com.br
papo de botequim                       Linux User



                     Listagem 4: musinc6.sh                                52 echo “
                                                                                                                         Inclusão de Músicas
01 $ cat musinc6
                                                                                                                         ======== == =======
02 #!/bin/bash
                                                                                                       Título do Álbum:
03 # Cadastra CDs (versao 6)
                                                                                                       Faixa:
04 #
                                                                                                       Nome da Música:
05 # Área de variáveis globais
                                                                                                       Intérprete:”
06 # Linha onde as mensagens serão exibidas
                                                                           53 while true
07 LinhaMesg=$((`tput lines` - 3))
                                                                           54 do
08 # Quantidade de colunas na tela (para enquadrar as mensagens)
                                                                           55        tput cup 5 38; tput el            # Posiciona e limpa linha
09 TotCols=$(tput cols)
                                                                           56        read Album
10 # Área de funções
                                                                           57        [ ! “$Album” ] &&                 # Operador deu <ENTER>
11 Pergunta ()
                                                                           58              {
12     {
                                                                           59              Pergunta “Deseja Terminar” s n
13     # A função recebe 3 parâmetros na seguinte ordem:
                                                                           60             # Agora só testo caixa baixa
14     # $1 - Mensagem a ser dada na tela
                                                                           61              [ $SN = “n” ] && continue
15     # $2 - Valor a ser aceito com resposta default
                                                                           62              clear; exit                # Fim da execução
16     # $3 - O outro valor aceito
                                                                           63              }
17     # Supondo que $1=Aceita?, $2=s e $3=n, a linha
                                                                           64        grep -iq “^$Album^” musicas 2> /dev/null &&
18     # abaixo colocaria em Msg o valor “Aceita? (S/n)”
                                                                           65              {
19     local Msg=”$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)”
                                                                           66              MandaMsg Este álbum já está cadastrado
20     local TamMsg=${#Msg}
                                                                           67              continue                   # Volta para ler outro álbum
21     # Centraliza a mensagem na linha
                                                                           68              }
22     local Col=$(((TotCols - TamMsg) / 2))
                                                                           69        Reg=”$Album^”          # $Reg receberá os dados de gravação
23     tput cup $LinhaMesg $Col
                                                                           70        oArtista=              # Guardará artista anterior
24     echo “$Msg”
                                                                           71        while true
25     tput cup $LinhaMesg $((Col + TamMsg + 1))
                                                                           72        do
26     read -n1 SN
                                                                           73              ((Faixa++))
27     [ ! $SN ] && SN=$2       # Se vazia, coloca default em SN
                                                                           74              tput cup 7 38
28     echo $SN | tr A-Z a-z # A saída de SN será em minúsculas
                                                                           75              echo $Faixa
29     tput cup $LinhaMesg $Col; tput el      # Apaga msg da tela
                                                                           76              tput cup 9 38              # Posiciona para ler música
30     return                                 # Sai da função
                                                                           77              read Musica
31     }
                                                                           78              [ “$Musica” ] ||     # Se o operador teclou <ENTER>...
32 function MandaMsg
                                                                           79                  {
33     {
                                                                           80                  Pergunta “Fim de Álbum?” s n
34     # A função recebe somente um parâmetro
                                                                           81                  # Agora só testo a caixa baixa
35     # com a mensagem que se deseja exibir;
                                                                           82                  [ “$SN” = n ] && continue
36     # para não obrigar o programador a passar
                                                                           83                  break             # Sai do loop para gravar dados
37     # a msg entre aspas, usaremos $* (todos
                                                                           84                  }
38     # os parâmetro, lembra?) e não $1.
                                                                           85             tput cup 11 38              # Posiciona para ler Artista
39     local Msg=”$*”
                                                                           86             # O artista anterior é o padrão
40     local TamMsg=${#Msg}
                                                                           87             [ “$oArtista” ] && echo -n “($oArtista) “
41     # Centraliza mensagem na linha
                                                                           88             read Artista
42     local Col=$(((TotCols - TamMsg) / 2))
                                                                           89             [ “$Artista” ] && oArtista=”$Artista”
43     tput cup $LinhaMesg $Col
                                                                           90             Reg=”$Reg$oArtista~$Musica:” # Montando registro
44     echo “$Msg”
                                                                           91             tput cup 9 38; tput el           # Apaga Música da tela
45     read -n1
                                                                           92             tput cup 11 38; tput el          # Apaga Artista da tela
46     tput cup $LinhaMesg $Col; tput el # Apaga msg da tela
                                                                           93       done
47     return                                # Sai da função
                                                                           94      # Grava registro no fim do arquivo
48     }
                                                                           95      echo “$Reg” >> musicas
49 # O corpo do programa propriamente dito começa aqui
                                                                           96      # Classifica o arquivo
50 clear
                                                                           97      sort musicas -o musicas
51 # A tela a seguir é montada com um único comando echo
                                                                           98 done




                                                                                                         maio 2005                        edição 08   89
                                                                        www.linuxmagazine.com.br
Linux User               Papo de botequim




                                     Listagem 5: musinc7.sh                                        Ahh! Agora sim! Quando passado
                                                                                                 como parâmetro do comando source,
     01   $ cat musinc7.sh
                                                                                                 o script foi executado no shell cor-
     02   #!/bin/bash
     03   # Cadastra CDs (versao 7)
                                                                                                 rente, deixando nele todo o ambiente
     04   #                                                                                      criado. Agora vamos rebobinar a fita
     05   # Área de variáveis globais                                                            até o início da explicação sobre este
     06   LinhaMesg=$((`tput lines` - 3)) # Linha onde serão mostradas as msgs para o operador   comando. Lá falamos do .bash_pro-
     07   TotCols=$(tput cols)               # Qtd colunas da tela para enquadrar msgs           file e, a esta altura, você já deve saber
     08   # O corpo do programa propriamente dito começa aqui                                    que sua incumbência é, logo após o
     09   clear                                                                                  login, preparar o ambiente de trabalho
     10   echo “                                                                                 para o usuário. Agora entendemos que
                                               Inclusão de Músicas                               é por isso mesmo que ele é executado
                                               ======== == =======                               usando esse artifício.
                              Título do Álbum:                                                      E agora você deve estar se per-
                                                     | Este campo foi                            guntando se é só para isso que esse
                              Faixa:                < criado somente para                        comando serve. Eu lhe digo que sim,
                                                     | orientar o preenchimento                  mas isso nos traz um monte de vanta-
                              Nome da Música:
                                                                                                 gens – e uma das mais usadas é tratar
                              Intérprete:” # Tela montada com um único echo
                                                                                                 funções como rotinas externas. Veja
     11   while true
                                                                                                 na listagem 5 uma outra forma de fazer
     12   do
                                                                                                 o nosso programa para incluir CDs no
     13        tput cup 5 38; tput el                   # Posiciona e limpa linha
     14        read Album
                                                                                                 arquivo musicas.
     15        [ ! “$Album” ] &&                        # Operador deu <ENTER>                     Agora o programa deu uma boa enco-
     16             {                                                                            lhida e as chamadas de função foram
     17             source pergunta.func “Deseja Terminar” s n                                   trocadas por arquivos externos chama-
     18             [ $SN = “n” ] && continue           # Agora só testo a caixa baixa           dos pergunta.func e mandamsg.func,
     19             clear; exit                         # Fim da execução                        que assim podem ser chamados por
     20            }                                                                             qualquer outro programa, dessa forma
     21       grep -iq “^$Album^” musicas 2> /dev/null &&                                       reutilizando o seu código.
     22            {                                                                                Por motivos meramente didáticos, as
     23            . mandamsg.func Este álbum já está cadastrado                                 chamadas a pergunta.func e manda-
     24            continue                             # Volta para ler outro álbum             msg.func estão sendo feitas por source
     25            }                                                                             e por . (ponto) indiscriminadamente,
     26       Reg=”$Album^”                             # $Reg receberá os dados de gravação     embora eu prefira o source que, por
     27           oArtista=                                # Guardará artista anterior
                                                                                                 ser mais visível, melhora a legibili-
     28       while true
                                                                                                 dade do código e facilita sua posterior
     29       do
                                                                                                 manutenção. Veja na listagem 6 como
     30             ((Faixa++))
                                                                                                 ficaram esses dois arquivos.
     31             tput cup 7 38
                                                                                                    Em ambos os arquivos, fiz somente
     32             echo $Faixa
     33             tput cup 9 38                       # Posiciona para ler música              duas mudanças, que veremos nas
     34             read Musica                                                                  observações a seguir. Porém, tenho
     35             [ “$Musica” ] ||                    # Se o operador tiver dado <ENTER>...    mais três observações a fazer:
     36                 {                                                                        1. As variáveis não estão sendo mais
     37                 . pergunta.func “Fim de Álbum?” s n                                      declaradas como locais, porque essa
     38                 [ “$SN” = n ] && continue       # Agora só testo a caixa baixa           é uma diretiva que só pode ser usada
     39                 break                           # Sai do loop para gravar dados          no corpo de funções e, portanto, essas
     40                 }                                                                        variáveis permanecem no ambiente do
     41            tput cup 11 38                               # Posiciona para ler Artista     shell, poluindo-o;
     42            [ “$oArtista” ] && echo -n “($oArtista) “ # Artista anterior é default        2. O comando return não está mais
     43            read Artista                                                                  presente, mas poderia estar sem alte-
     44            [ “$Artista” ] && oArtista=”$Artista”                                         rar em nada a lógica do script, uma
     45            Reg=”$Reg$oArtista~$Musica:”                 # Montando registro              vez que só serviria para indicar um
     46            tput cup 9 38; tput el                       # Apaga Música da tela
                                                                                                 eventual erro por meio de um código
     47            tput cup 11 38; tput el                      # Apaga Artista da tela
                                                                                                 de retorno previamente estabelecido
     48        done
                                                                                                 (por exemplo return 1, return 2, …),
     49        echo “$Reg” >> musicas                   # Grava registro no fim do arquivo
                                                                                                 sendo que o return e return 0 são
     50        sort musicas -o musicas                  # Classifica o arquivo
     51   done
                                                                                                 idênticos e significam que a rotina foi
                                                                                                 executada sem erros;


90   maio 2005                        edição 08
                                                   www.linuxmagazine.com.br
papo de botequim                 Linux User



3. O comando que estamos acostumados                         Listagem 6: pergunta.func e mandamsg.func
   a usar para gerar um código de retorno
                                             01 $ cat pergunta.func
   é o exit, mas a saída de uma rotina
                                             02 # A função recebe 3 parâmetros na seguinte ordem:
   externa não pode ser feita dessa forma
                                             03 # $1 - Mensagem a ser dada na tela
   porque, como ela está sendo executada
                                             04 # $2 - Valor a ser aceito com resposta default
   no mesmo shell do script que o cha-
                                             05 # $3 - O outro valor aceito
   mou, o exit simplesmente encerraria
                                             06 # Supondo que $1=Aceita?, $2=s e $3=n, a linha
   esse shell, terminando a execução de
                                             07 # abaixo colocaria em Msg o valor “Aceita? (S/n)”
   todo o script;
                                             08 Msg=”$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)”
4. De onde veio a variável LinhaMesg? Ela
                                             09 TamMsg=${#Msg}
   veio do script musinc7.sh, porque havia
                                             10 Col=$(((TotCols - TamMsg) / 2))        # Centraliza msg na linha
   sido declarada antes da chamada das
                                             11 tput cup $LinhaMesg $Col
   rotinas (nunca esqueça que o shell que
                                             12 echo “$Msg”
   está interpretando o script e essas roti-
                                             13 tput cup $LinhaMesg $((Col + TamMsg + 1))
   nas é o mesmo);
                                             14 read -n1 SN
5. Se você decidir usar rotinas externas
                                             15 [ ! $SN ] && SN=$2                     # Se vazia coloca default em SN
   não se envergonhe, exagere nos comen-
                                             16 echo $SN | tr A-Z a-z                  # A saída de SN será em minúscula
   tários, principalmente sobre a passagem
                                             17 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela
   dos parâmetros, para facilitar a manu-
                                             18 $ cat mandamsg.func
   tenção e o uso dessa rotina por outros
                                             19 # A função recebe somente um parâmetro
   programas no futuro.
                                             20 # com a mensagem que se deseja exibir;
 – Bem, agora você já tem mais um
                                             21 # para não obrigar o programador a passar
    monte de novidades para melhorar
                                             22 # a msg entre aspas, usaremos $* (todos
    os scripts que fizemos. Você se lem-
                                             23 # os parâmetro, lembra?) e não $1.
    bra do programa listartista.sh no qual
                                             24 Msg=”$*”
    você passava o nome de um artista
                                             25 TamMsg=${#Msg}
    como parâmetro e ele devolvia as suas
                                             26 Col=$(((TotCols - TamMsg) / 2))        # Centraliza msg na linha
    músicas? Ele era como o mostrado aqui
                                             27 tput cup $LinhaMesg $Col
    embaixo na listagem 7.
                                             28 echo “$Msg”
 – Claro que me lembro!
                                             29 read -n1
 – Para firmar os conceitos que te pas-
                                             30 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela
    sei, faça-o com a tela formatada e a
    execução em loop, de forma que ele
    só termine quando receber um Enter no lugar do nome               Não se esqueça: em caso de dúvida ou falta de compa-
    do artista. Suponha que a tela tenha 25 linhas; a cada 22      nhia para um chope, é só mandar um e-mail para o endereço
    músicas listadas o programa deverá dar uma parada para         julio.neves@gmail.com que terei prazer em lhe ajudar. Vou aproveitar
    que o operador possa lê-las. Eventuais mensagens de erro       também para mandar minha propaganda: diga aos amigos que
    devem ser passadas usando a rotina mandamsg.func que           quem estiver a fim de fazer um curso porreta de programação
    acabamos de desenvolver. Chico, manda mais dois!! O meu        em Shell deve mandar um e-mail para julio.neves@tecnohall.com.br
    é com pouca pressão…                                           para informar-se. Até mais!                                       ■

                               Listagem 7: listartista.sh                                                           Informações
 01   $ cat listartista.sh                                                                       [1] Bash, página oficial:
 02   #!/bin/bash                                                                                    http://www.gnu.org/software/bash/bash.html
 03   # Dado um artista, mostra as suas musicas
                                                                                                 [2] Manual de referência do Bash:
 04   # versao 2                                                                                     http://www.gnu.org/software/bash/
 05   if [ $# -eq 0 ]                                                                                manual/bashref.html
 06   then
 07       echo Voce deveria ter passado pelo menos um parametro
 08       exit 1
                                                                                                              Julio Cezar Neves é Analista de Suporte de
                                                                                              Sobre o autor




 09   fi
                                                                                                              Sistemas desde 1969 e trabalha com Unix
 10   IFS=”
 11   :”                                                                                                      desde 1980, quando participou do desen-
 12   for ArtMus in $(cut -f2 -d^ musicas)                                                                    volvimento do SOX, um sistema operacio-
 13   do                                                                                                      nal similar ao Unix produzido pela Cobra
 14        echo “$ArtMus” | grep -i “^$*~” > /dev/null && echo $ArtMus | cut -f2 -d~                          Computadores. Pode ser contatado no
 15   done                                                                                                    e-mail julio.neves@gmail.com



                                                                                               maio 2005                                     edição 08     91
                                                                   www.linuxmagazine.com.br

Weitere ähnliche Inhalte

Was ist angesagt? (12)

Linguagem C - Funções
Linguagem C - FunçõesLinguagem C - Funções
Linguagem C - Funções
 
Stack based overflow
Stack based overflowStack based overflow
Stack based overflow
 
12 aula - shell script-2015
12   aula - shell script-201512   aula - shell script-2015
12 aula - shell script-2015
 
Tutorial Shell Script
Tutorial Shell ScriptTutorial Shell Script
Tutorial Shell Script
 
PHP não é coisa de moleque
PHP não é coisa de molequePHP não é coisa de moleque
PHP não é coisa de moleque
 
Introducao ao Shell Script
Introducao ao Shell ScriptIntroducao ao Shell Script
Introducao ao Shell Script
 
44087090 tutorial-programacao-batch
44087090 tutorial-programacao-batch44087090 tutorial-programacao-batch
44087090 tutorial-programacao-batch
 
Manual comandos
Manual comandosManual comandos
Manual comandos
 
Code authority url amigável usando mod rewrite e php (friendly url and php)
Code authority  url amigável usando mod rewrite e php (friendly url and php)Code authority  url amigável usando mod rewrite e php (friendly url and php)
Code authority url amigável usando mod rewrite e php (friendly url and php)
 
Curso gratuitoshellscript nivel-2
Curso gratuitoshellscript nivel-2Curso gratuitoshellscript nivel-2
Curso gratuitoshellscript nivel-2
 
Gabarito da P1 de PROG
Gabarito da P1 de PROGGabarito da P1 de PROG
Gabarito da P1 de PROG
 
Minicurso Shell Script
Minicurso Shell ScriptMinicurso Shell Script
Minicurso Shell Script
 

Andere mochten auch

IPP Comisión TP viernes 14 a 16 2012
IPP Comisión TP viernes 14 a 16   2012IPP Comisión TP viernes 14 a 16   2012
IPP Comisión TP viernes 14 a 16 2012E.N.M.
 
1 subida serra da groba 1 oficial
1 subida serra da groba 1 oficial1 subida serra da groba 1 oficial
1 subida serra da groba 1 oficialwebmaster82
 
Pattern digitizing and pattern scanning services los angeles ca usa
Pattern digitizing and pattern scanning services los angeles ca usaPattern digitizing and pattern scanning services los angeles ca usa
Pattern digitizing and pattern scanning services los angeles ca usaAlejandro Esparza
 
Vademecum mosse-per-prepararsi-redditest
Vademecum mosse-per-prepararsi-redditestVademecum mosse-per-prepararsi-redditest
Vademecum mosse-per-prepararsi-redditestRedazione Acquaviva Net
 
Benjamin c
Benjamin cBenjamin c
Benjamin cfbcat
 
History of electricity generation and distribution in bangladesh
History of electricity generation and distribution in bangladeshHistory of electricity generation and distribution in bangladesh
History of electricity generation and distribution in bangladeshSuma Akter
 
Eleccions 2012 // Guia de butxaca
Eleccions 2012 // Guia de butxacaEleccions 2012 // Guia de butxaca
Eleccions 2012 // Guia de butxacaGuiadebutxaca
 
Presentación1
Presentación1Presentación1
Presentación1katt271110
 
Desafios da entrega de software para instituição pública em contexto ágil
Desafios da entrega de software para instituição pública em contexto ágilDesafios da entrega de software para instituição pública em contexto ágil
Desafios da entrega de software para instituição pública em contexto ágilViviane Santos
 
Curso de Shell Script 01/11
Curso de Shell Script 01/11Curso de Shell Script 01/11
Curso de Shell Script 01/11Rodrigo Silva
 
Projeto TRACER no ELIES 2013
Projeto TRACER no ELIES 2013Projeto TRACER no ELIES 2013
Projeto TRACER no ELIES 2013TRACER
 
Natura ciclo 18 - dezembro 2012
Natura ciclo 18 - dezembro 2012Natura ciclo 18 - dezembro 2012
Natura ciclo 18 - dezembro 2012Meus Cosméticos
 

Andere mochten auch (20)

Brad baker presentation
Brad baker presentationBrad baker presentation
Brad baker presentation
 
Ficha xogos
Ficha xogosFicha xogos
Ficha xogos
 
IPP Comisión TP viernes 14 a 16 2012
IPP Comisión TP viernes 14 a 16   2012IPP Comisión TP viernes 14 a 16   2012
IPP Comisión TP viernes 14 a 16 2012
 
1 subida serra da groba 1 oficial
1 subida serra da groba 1 oficial1 subida serra da groba 1 oficial
1 subida serra da groba 1 oficial
 
Prueba examen
Prueba examenPrueba examen
Prueba examen
 
Pattern digitizing and pattern scanning services los angeles ca usa
Pattern digitizing and pattern scanning services los angeles ca usaPattern digitizing and pattern scanning services los angeles ca usa
Pattern digitizing and pattern scanning services los angeles ca usa
 
Vademecum mosse-per-prepararsi-redditest
Vademecum mosse-per-prepararsi-redditestVademecum mosse-per-prepararsi-redditest
Vademecum mosse-per-prepararsi-redditest
 
Benjamin c
Benjamin cBenjamin c
Benjamin c
 
Redes
RedesRedes
Redes
 
Bender
BenderBender
Bender
 
History of electricity generation and distribution in bangladesh
History of electricity generation and distribution in bangladeshHistory of electricity generation and distribution in bangladesh
History of electricity generation and distribution in bangladesh
 
Diapositivas astrid
Diapositivas astridDiapositivas astrid
Diapositivas astrid
 
Eleccions 2012 // Guia de butxaca
Eleccions 2012 // Guia de butxacaEleccions 2012 // Guia de butxaca
Eleccions 2012 // Guia de butxaca
 
Presentación1
Presentación1Presentación1
Presentación1
 
Desafios da entrega de software para instituição pública em contexto ágil
Desafios da entrega de software para instituição pública em contexto ágilDesafios da entrega de software para instituição pública em contexto ágil
Desafios da entrega de software para instituição pública em contexto ágil
 
Nuevo silabo 2015 ii
Nuevo silabo 2015 iiNuevo silabo 2015 ii
Nuevo silabo 2015 ii
 
Curso de Shell Script 01/11
Curso de Shell Script 01/11Curso de Shell Script 01/11
Curso de Shell Script 01/11
 
Projeto TRACER no ELIES 2013
Projeto TRACER no ELIES 2013Projeto TRACER no ELIES 2013
Projeto TRACER no ELIES 2013
 
2 2
2 22 2
2 2
 
Natura ciclo 18 - dezembro 2012
Natura ciclo 18 - dezembro 2012Natura ciclo 18 - dezembro 2012
Natura ciclo 18 - dezembro 2012
 

Ähnlich wie Curso de Shell Script 08/11

Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10Pessoal
 
Curso de Shell Script 06/11
Curso de Shell Script 06/11Curso de Shell Script 06/11
Curso de Shell Script 06/11Rodrigo Silva
 
Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3Pessoal
 
Curso de Shell Script 05/11
Curso de Shell Script 05/11Curso de Shell Script 05/11
Curso de Shell Script 05/11Rodrigo Silva
 
Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6Pessoal
 
Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5Pessoal
 
Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9Pessoal
 
C curso - notas de aula
C   curso - notas de aulaC   curso - notas de aula
C curso - notas de aulaLoAlves21
 
Sapo sessions linux power tools
Sapo sessions linux power toolsSapo sessions linux power tools
Sapo sessions linux power toolsArmando Reis
 
Ruby, Rails e Diversão (Campus Party Brasil 2009)
Ruby, Rails e Diversão (Campus Party Brasil 2009)Ruby, Rails e Diversão (Campus Party Brasil 2009)
Ruby, Rails e Diversão (Campus Party Brasil 2009)Julio Monteiro
 
Curso de Shell Script 02/11
Curso de Shell Script 02/11Curso de Shell Script 02/11
Curso de Shell Script 02/11Rodrigo Silva
 
Curso de Shell Script 04/11
Curso de Shell Script 04/11Curso de Shell Script 04/11
Curso de Shell Script 04/11Rodrigo Silva
 
Tradutor de Pig Latin
Tradutor de Pig LatinTradutor de Pig Latin
Tradutor de Pig LatinElen Arantza
 
Curso de shell
Curso de shellCurso de shell
Curso de shellTiago
 

Ähnlich wie Curso de Shell Script 08/11 (20)

Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10
 
Curso de Shell Script 06/11
Curso de Shell Script 06/11Curso de Shell Script 06/11
Curso de Shell Script 06/11
 
Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3
 
Curso de Shell Script 05/11
Curso de Shell Script 05/11Curso de Shell Script 05/11
Curso de Shell Script 05/11
 
Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6
 
Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5
 
Shell script
Shell script Shell script
Shell script
 
Palestra Ruby
Palestra RubyPalestra Ruby
Palestra Ruby
 
Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9
 
10-Matlab.pdf
10-Matlab.pdf10-Matlab.pdf
10-Matlab.pdf
 
Funções em C
Funções em CFunções em C
Funções em C
 
C curso - notas de aula
C   curso - notas de aulaC   curso - notas de aula
C curso - notas de aula
 
Sapo sessions linux power tools
Sapo sessions linux power toolsSapo sessions linux power tools
Sapo sessions linux power tools
 
Linux shell
Linux shellLinux shell
Linux shell
 
Ruby, Rails e Diversão (Campus Party Brasil 2009)
Ruby, Rails e Diversão (Campus Party Brasil 2009)Ruby, Rails e Diversão (Campus Party Brasil 2009)
Ruby, Rails e Diversão (Campus Party Brasil 2009)
 
Curso de Shell Script 02/11
Curso de Shell Script 02/11Curso de Shell Script 02/11
Curso de Shell Script 02/11
 
Curso de Shell Script 04/11
Curso de Shell Script 04/11Curso de Shell Script 04/11
Curso de Shell Script 04/11
 
Tradutor de Pig Latin
Tradutor de Pig LatinTradutor de Pig Latin
Tradutor de Pig Latin
 
Introd aplicjava
Introd aplicjavaIntrod aplicjava
Introd aplicjava
 
Curso de shell
Curso de shellCurso de shell
Curso de shell
 

Curso de Shell Script 08/11

  • 1. Linux User Papo de botequim Papo de Botequim Curso de Shell Script Parte VIII Dave Hamilton - www.sxc.hu Chegou a hora de fazer como Jack e dividir os programas em pedacinhos. Com funções e chamadas externas os scripts ficam menores, a manutenção mais fácil e ainda por cima reaproveitamos código. por Júlio Cezar Neves E aê, cara, tudo bem? posicionais ($1, $2, …, $n). Todas as regras que se aplicam – – Tudo beleza! Eu queria te mostrar o que fi z mas já sei que você vai querer molhar o bico primeiro, né? à passagem de parâmetros para programas também valem para funções, mas é muito importante realçar que os parâmetros – Só pra te contrariar, hoje não quero. Vai, mostra logo aí passados para um programa não se confundem com aqueles o que você fez. que são passados para suas funções. Isso significa, por exem- – Poxa, o exercício que você passou é muito grande. Dá uma plo, que o $1 de um script é diferente do $1 de uma de suas olhada na listagem 1 e vê como eu resolvi: funções internas. – É, o programa tá legal, tá todo estruturadinho, mas gosta- Repare que as variáveis $Msg, $TamMsg e $Col são de uso ria de fazer alguns poucos comentários: só para relembrar, restrito dessa rotina e, por isso, foram criadas como variáveis as seguintes construções: [ ! $Album ] && e [ $Musica ] locais. A razão é simplesmente a economia de memória, já que || representam a mesma coisa, isto é: no caso da primeira, ao sair da rotina elas serão devidamente detonadas, coisa que testamos se a variável $Album não (!) tem nada dentro, então não aconteceria se eu não tivesse usado esse artifício. (&&)… Na segunda, testamos se $Musica tem algum dado, A linha de código que cria a variável local Msg concatena ao senão (||)… texto recebido ($1) um parêntese, a resposta padrão ($2) em Se você reclamou do tamanho do programa, é porque ainda caixa alta, uma barra, a outra resposta ($3) em caixa baixa não te dei algumas dicas. Repare que a maior parte do script e fi naliza fechando o parêntese. Uso essa convenção para, ao é para mostrar mensagens centraliza- das na penúltima linha da tela. Repare Listagem 1: musinc5.sh ainda que algumas mensagens pedem 01 $ cat musinc5.sh um S ou um N como resposta e outras 02 #!/bin/bash são só de advertência. Isso é um caso 03 # Cadastra CDs (versao 5) típico que pede o uso de funções, que 04 # seriam escritas somente uma vez e 05 clear executadas em diversos pontos do 06 LinhaMesg=$((`tput lines` - 3)) # Linha onde serão mostradas as msgs para o operador script. Vou montar duas funções para 07 TotCols=$(tput cols) # Qtd colunas da tela para enquadrar msgs resolver esses casos e vamos incor- 08 echo “ porá-las ao seu programa para ver o Inclusão de Músicas resultado fi nal. ======== == ======= – Chico! Agora traz dois chopes, um Título do Álbum: sem colarinho, para me dar inspira- | Este campo foi ção. E você, de olho na listagem 2. Faixa: < criado somente para Como podemos ver, uma função é | orientar o preenchimento defi nida quando digitamos nome_da_ Nome da Música: função () e todo o seu corpo está Intérprete:” # Tela montada com um único echo entre chaves ({}). Já conversamos aqui 09 while true no boteco sobre passagem de parâ- 10 do metros e as funções os recebem da 11 tput cup 5 38; tput el # Posiciona e limpa linha ➟ mesma forma, isto é, são parâmetros 86 maio 2005 edição 08 www.linuxmagazine.com.br
  • 2. papo de botequim Linux User 12 read Album mesmo tempo, mostrar as opções dis- 13 [ ! “$Album” ] && # Operador deu <ENTER> poníveis e realçar a resposta oferecida 14 { como padrão. 15 Msg=”Deseja Terminar? (S/n)” Quase no fim da rotina, a resposta 16 TamMsg=${#Msg} recebida ($SN) é convertida para caixa 17 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha baixa (minúsculas) de forma que no 18 tput cup $LinhaMesg $Col corpo do programa não precisemos 19 echo “$Msg” fazer esse teste. Veja na listagem 3 20 tput cup $LinhaMesg $((Col + TamMsg + 1)) como ficaria a função para exibir uma 21 read -n1 SN mensagem na tela. 22 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela Essa é uma outra forma de definir 23 [ $SN = “N” -o $SN = “n” ] && continue # $SN é igual a N ou (-o) n? uma função: não a chamamos, como 24 clear; exit # Fim da execução no exemplo anterior, usando uma 25 } construção com a sintaxe nome_da_ 26 grep “^$Album^” musicas > /dev/null && função (), mas sim como function 27 { nome_da_função. Em nada mais ela 28 Msg=”Este álbum já está cadastrado” difere da anterior, exceto que, como 29 TamMsg=${#Msg} consta dos comentários, usamos a 30 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha variável $* que, como já sabemos, 31 tput cup $LinhaMesg $Col representa o conjunto de todos os 32 echo “$Msg” parâmetros passados ao script, para 33 read -n1 que o programador não precise usar 34 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela aspas envolvendo a mensagem que 35 continue # Volta para ler outro álbum deseja passar à função. 36 } Para terminar com esse blá-blá-blá, 37 Reg=”$Album^” # $Reg receberá os dados para gravação vamos ver na listagem 4 as alterações 38 oArtista= # Variável que guarda artista anterior no programa quando usamos o con- 39 while true ceito de funções: 40 do Repare que a estrutura do script 41 ((Faixa++)) segue a ordem Variáveis Globais, Fun- 42 tput cup 7 38 ções e Corpo do Programa. Esta estrutu- 43 echo $Faixa ração se deve ao fato de Shell Script ser 44 tput cup 9 38 # Posiciona para ler música uma linguagem interpretada, em que 45 read Musica o programa é lido da esquerda para 46 [ “$Musica” ] || # Se o operador tiver dado <ENTER>... a direita e de cima para baixo. Para 47 { ser vista pelo script e suas funções, 48 Msg=”Fim de Álbum? (S/n)” uma variável deve ser declarada (ou 49 TamMsg=${#Msg} inicializada, como preferem alguns) 50 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha antes de qualquer outra coisa. Por sua 51 tput cup $LinhaMesg $Col vez, as funções devem ser declaradas 52 echo “$Msg” antes do corpo do programa propria- 53 tput cup $LinhaMesg $((Col + TamMsg + 1) mente dito. A explicação é simples: o 54 read -n1 SN interpretador de comandos do shell 55 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela deve saber do que se trata a função 56 [ “$SN” = N -o “$SN” = n ] && continue # $SN é igual a N ou (-o) n? antes que ela seja chamada no pro- 57 break # Sai do loop para gravar grama principal. 58 } Uma coisa bacana na criação de fun- 59 tput cup 11 38 # Posiciona para ler Artista ções é fazê-las tão genéricas quanto 60 [ “$oArtista” ] && echo -n “($oArtista) “ # Artista anterior é default possível, de forma que possam ser 61 read Artista reutilizadas em outros scripts e apli- 62 [ “$Artista” ] && oArtista=”$Artista” cativos sem a necessidade de reinven- 63 Reg=”$Reg$oArtista~$Musica:” # Montando registro tarmos a roda. As duas funções que 64 tput cup 9 38; tput el # Apaga Música da tela acabamos de ver são bons exemplos, 65 tput cup 11 38; tput el # Apaga Artista da tela pois é difícil um script de entrada de 66 done dados que não use uma rotina como 67 echo “$Reg” >> musicas # Grava registro no fim do arquivo a MandaMsg ou que não interaja com 38 sort musicas -0 musicas # Classifica o arquivo o operador por meio de algo seme- 69 done lhante à Pergunta. maio 2005 edição 08 87 www.linuxmagazine.com.br
  • 3. Linux User Papo de botequim Conselho de amigo: crie um arquivo e anexe a ele cada fun- diretório /home. Só que assim que a execução do script termi- ção nova que você criar. Ao final de algum tempo você terá nou, o sub-shell foi para o beleléu e, com ele, todo o ambiente uma bela biblioteca de funções que lhe poupará muito tempo criado. Agora preste atenção no exemplo abaixo e veja como a de programação. coisa muda de figura: O comando source $ source script_bobo Veja se você nota algo de diferente na saída do ls a seguir: jneves juliana paula silvie $ pwd $ ls -la .bash_profile /home -rw-r--r-- 1 Julio unknown 4511 Mar 18 17:45 .bash_profile $ cd - /home/jneves Não olhe a resposta não, volte a prestar atenção! Bem, já que $ . script_bobo você está mesmo sem saco de pensar e prefere ler a resposta, jneves juliana paula silvie vou te dar uma dica: acho que você já sabe que o .bash_pro- $ pwd file é um dos scripts que são automaticamente executados /home quando você se “loga” (ARRGGHH! Odeio esse termo!) no sistema. Agora olhe nova- Listagem 2: Função Pergunta mente para a saída do comando ls e me 01 Pergunta () diga o que há de diferente nela. 02 { Como eu disse, o .bash_profile é exe- 03 # A função recebe 3 parâmetros na seguinte ordem: cutado durante o logon, mas repare que ele não tem nenhuma permissão de execução. 04 # $1 - Mensagem a ser mostrada na tela Isso acontece porque se você o executasse 05 # $2 - Valor a ser aceito com resposta padrão como qualquer outro script careta, no fim 06 # $3 - O outro valor aceito de sua execução todo o ambiente por ele 07 # Supondo que $1=Aceita?, $2=s e $3=n, a linha a gerado morreria junto com o shell sob o 08 # seguir colocaria em Msg o valor “Aceita? (S/n)” qual ele foi executado (você se lembra de 09 local Msg=”$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)” que todos os scripts são executados em 10 local TamMsg=${#Msg} sub-shells, né?). Pois é para coisas assim 11 local Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha que existe o comando source, também 12 tput cup $LinhaMesg $Col conhecido por “.” (ponto). Este comando 13 echo “$Msg” faz com que o script que lhe for passado 14 tput cup $LinhaMesg $((Col + TamMsg + 1)) como parâmetro não seja executado em 15 read -n1 SN um sub-shell. Mas é melhor um exemplo 16 [ ! $SN ] && SN=$2 # Se vazia coloca default em SN que uma explicação em 453 palavras. Veja 17 echo $SN | tr A-Z a-z # A saída de SN será em minúscula o scriptzinho a seguir: 18 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela 19 return # Sai da função $ cat script_bobo 20 } cd .. ls Listagem 3: Função MandaMsg Ele simplesmente deveria ir para o dire- 01 function MandaMsg tório acima do diretório atual. Vamos 02 { executar uns comandos envolvendo o 03 # A função recebe somente um parâmetro script_bobo e analisar os resultados: 04 # com a mensagem que se deseja exibir. 05 # para não obrigar o programador a passar $ pwd 06 # a msg entre aspas, usaremos $* (todos /home/jneves 07 # os parâmetros, lembra?) e não $1. $ script_bobo 08 local Msg=”$*” jneves juliana paula silvie 09 local TamMsg=${#Msg} $ pwd 10 local Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha /home/jneves 11 tput cup $LinhaMesg $Col 12 echo “$Msg” Se eu mandei ele subir um diretório, 13 read -n1 por que não subiu? Opa, peraí que subiu 14 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela sim! O sub-shell que foi criado para exe- 15 return # Sai da função cutar o script tanto subiu que listou os 16 } diretórios dos quatro usuários abaixo do 88 maio 2005 edição 08 www.linuxmagazine.com.br
  • 4. papo de botequim Linux User Listagem 4: musinc6.sh 52 echo “ Inclusão de Músicas 01 $ cat musinc6 ======== == ======= 02 #!/bin/bash Título do Álbum: 03 # Cadastra CDs (versao 6) Faixa: 04 # Nome da Música: 05 # Área de variáveis globais Intérprete:” 06 # Linha onde as mensagens serão exibidas 53 while true 07 LinhaMesg=$((`tput lines` - 3)) 54 do 08 # Quantidade de colunas na tela (para enquadrar as mensagens) 55 tput cup 5 38; tput el # Posiciona e limpa linha 09 TotCols=$(tput cols) 56 read Album 10 # Área de funções 57 [ ! “$Album” ] && # Operador deu <ENTER> 11 Pergunta () 58 { 12 { 59 Pergunta “Deseja Terminar” s n 13 # A função recebe 3 parâmetros na seguinte ordem: 60 # Agora só testo caixa baixa 14 # $1 - Mensagem a ser dada na tela 61 [ $SN = “n” ] && continue 15 # $2 - Valor a ser aceito com resposta default 62 clear; exit # Fim da execução 16 # $3 - O outro valor aceito 63 } 17 # Supondo que $1=Aceita?, $2=s e $3=n, a linha 64 grep -iq “^$Album^” musicas 2> /dev/null && 18 # abaixo colocaria em Msg o valor “Aceita? (S/n)” 65 { 19 local Msg=”$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)” 66 MandaMsg Este álbum já está cadastrado 20 local TamMsg=${#Msg} 67 continue # Volta para ler outro álbum 21 # Centraliza a mensagem na linha 68 } 22 local Col=$(((TotCols - TamMsg) / 2)) 69 Reg=”$Album^” # $Reg receberá os dados de gravação 23 tput cup $LinhaMesg $Col 70 oArtista= # Guardará artista anterior 24 echo “$Msg” 71 while true 25 tput cup $LinhaMesg $((Col + TamMsg + 1)) 72 do 26 read -n1 SN 73 ((Faixa++)) 27 [ ! $SN ] && SN=$2 # Se vazia, coloca default em SN 74 tput cup 7 38 28 echo $SN | tr A-Z a-z # A saída de SN será em minúsculas 75 echo $Faixa 29 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela 76 tput cup 9 38 # Posiciona para ler música 30 return # Sai da função 77 read Musica 31 } 78 [ “$Musica” ] || # Se o operador teclou <ENTER>... 32 function MandaMsg 79 { 33 { 80 Pergunta “Fim de Álbum?” s n 34 # A função recebe somente um parâmetro 81 # Agora só testo a caixa baixa 35 # com a mensagem que se deseja exibir; 82 [ “$SN” = n ] && continue 36 # para não obrigar o programador a passar 83 break # Sai do loop para gravar dados 37 # a msg entre aspas, usaremos $* (todos 84 } 38 # os parâmetro, lembra?) e não $1. 85 tput cup 11 38 # Posiciona para ler Artista 39 local Msg=”$*” 86 # O artista anterior é o padrão 40 local TamMsg=${#Msg} 87 [ “$oArtista” ] && echo -n “($oArtista) “ 41 # Centraliza mensagem na linha 88 read Artista 42 local Col=$(((TotCols - TamMsg) / 2)) 89 [ “$Artista” ] && oArtista=”$Artista” 43 tput cup $LinhaMesg $Col 90 Reg=”$Reg$oArtista~$Musica:” # Montando registro 44 echo “$Msg” 91 tput cup 9 38; tput el # Apaga Música da tela 45 read -n1 92 tput cup 11 38; tput el # Apaga Artista da tela 46 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela 93 done 47 return # Sai da função 94 # Grava registro no fim do arquivo 48 } 95 echo “$Reg” >> musicas 49 # O corpo do programa propriamente dito começa aqui 96 # Classifica o arquivo 50 clear 97 sort musicas -o musicas 51 # A tela a seguir é montada com um único comando echo 98 done maio 2005 edição 08 89 www.linuxmagazine.com.br
  • 5. Linux User Papo de botequim Listagem 5: musinc7.sh Ahh! Agora sim! Quando passado como parâmetro do comando source, 01 $ cat musinc7.sh o script foi executado no shell cor- 02 #!/bin/bash 03 # Cadastra CDs (versao 7) rente, deixando nele todo o ambiente 04 # criado. Agora vamos rebobinar a fita 05 # Área de variáveis globais até o início da explicação sobre este 06 LinhaMesg=$((`tput lines` - 3)) # Linha onde serão mostradas as msgs para o operador comando. Lá falamos do .bash_pro- 07 TotCols=$(tput cols) # Qtd colunas da tela para enquadrar msgs file e, a esta altura, você já deve saber 08 # O corpo do programa propriamente dito começa aqui que sua incumbência é, logo após o 09 clear login, preparar o ambiente de trabalho 10 echo “ para o usuário. Agora entendemos que Inclusão de Músicas é por isso mesmo que ele é executado ======== == ======= usando esse artifício. Título do Álbum: E agora você deve estar se per- | Este campo foi guntando se é só para isso que esse Faixa: < criado somente para comando serve. Eu lhe digo que sim, | orientar o preenchimento mas isso nos traz um monte de vanta- Nome da Música: gens – e uma das mais usadas é tratar Intérprete:” # Tela montada com um único echo funções como rotinas externas. Veja 11 while true na listagem 5 uma outra forma de fazer 12 do o nosso programa para incluir CDs no 13 tput cup 5 38; tput el # Posiciona e limpa linha 14 read Album arquivo musicas. 15 [ ! “$Album” ] && # Operador deu <ENTER> Agora o programa deu uma boa enco- 16 { lhida e as chamadas de função foram 17 source pergunta.func “Deseja Terminar” s n trocadas por arquivos externos chama- 18 [ $SN = “n” ] && continue # Agora só testo a caixa baixa dos pergunta.func e mandamsg.func, 19 clear; exit # Fim da execução que assim podem ser chamados por 20 } qualquer outro programa, dessa forma 21 grep -iq “^$Album^” musicas 2> /dev/null && reutilizando o seu código. 22 { Por motivos meramente didáticos, as 23 . mandamsg.func Este álbum já está cadastrado chamadas a pergunta.func e manda- 24 continue # Volta para ler outro álbum msg.func estão sendo feitas por source 25 } e por . (ponto) indiscriminadamente, 26 Reg=”$Album^” # $Reg receberá os dados de gravação embora eu prefira o source que, por 27 oArtista= # Guardará artista anterior ser mais visível, melhora a legibili- 28 while true dade do código e facilita sua posterior 29 do manutenção. Veja na listagem 6 como 30 ((Faixa++)) ficaram esses dois arquivos. 31 tput cup 7 38 Em ambos os arquivos, fiz somente 32 echo $Faixa 33 tput cup 9 38 # Posiciona para ler música duas mudanças, que veremos nas 34 read Musica observações a seguir. Porém, tenho 35 [ “$Musica” ] || # Se o operador tiver dado <ENTER>... mais três observações a fazer: 36 { 1. As variáveis não estão sendo mais 37 . pergunta.func “Fim de Álbum?” s n declaradas como locais, porque essa 38 [ “$SN” = n ] && continue # Agora só testo a caixa baixa é uma diretiva que só pode ser usada 39 break # Sai do loop para gravar dados no corpo de funções e, portanto, essas 40 } variáveis permanecem no ambiente do 41 tput cup 11 38 # Posiciona para ler Artista shell, poluindo-o; 42 [ “$oArtista” ] && echo -n “($oArtista) “ # Artista anterior é default 2. O comando return não está mais 43 read Artista presente, mas poderia estar sem alte- 44 [ “$Artista” ] && oArtista=”$Artista” rar em nada a lógica do script, uma 45 Reg=”$Reg$oArtista~$Musica:” # Montando registro vez que só serviria para indicar um 46 tput cup 9 38; tput el # Apaga Música da tela eventual erro por meio de um código 47 tput cup 11 38; tput el # Apaga Artista da tela de retorno previamente estabelecido 48 done (por exemplo return 1, return 2, …), 49 echo “$Reg” >> musicas # Grava registro no fim do arquivo sendo que o return e return 0 são 50 sort musicas -o musicas # Classifica o arquivo 51 done idênticos e significam que a rotina foi executada sem erros; 90 maio 2005 edição 08 www.linuxmagazine.com.br
  • 6. papo de botequim Linux User 3. O comando que estamos acostumados Listagem 6: pergunta.func e mandamsg.func a usar para gerar um código de retorno 01 $ cat pergunta.func é o exit, mas a saída de uma rotina 02 # A função recebe 3 parâmetros na seguinte ordem: externa não pode ser feita dessa forma 03 # $1 - Mensagem a ser dada na tela porque, como ela está sendo executada 04 # $2 - Valor a ser aceito com resposta default no mesmo shell do script que o cha- 05 # $3 - O outro valor aceito mou, o exit simplesmente encerraria 06 # Supondo que $1=Aceita?, $2=s e $3=n, a linha esse shell, terminando a execução de 07 # abaixo colocaria em Msg o valor “Aceita? (S/n)” todo o script; 08 Msg=”$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)” 4. De onde veio a variável LinhaMesg? Ela 09 TamMsg=${#Msg} veio do script musinc7.sh, porque havia 10 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha sido declarada antes da chamada das 11 tput cup $LinhaMesg $Col rotinas (nunca esqueça que o shell que 12 echo “$Msg” está interpretando o script e essas roti- 13 tput cup $LinhaMesg $((Col + TamMsg + 1)) nas é o mesmo); 14 read -n1 SN 5. Se você decidir usar rotinas externas 15 [ ! $SN ] && SN=$2 # Se vazia coloca default em SN não se envergonhe, exagere nos comen- 16 echo $SN | tr A-Z a-z # A saída de SN será em minúscula tários, principalmente sobre a passagem 17 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela dos parâmetros, para facilitar a manu- 18 $ cat mandamsg.func tenção e o uso dessa rotina por outros 19 # A função recebe somente um parâmetro programas no futuro. 20 # com a mensagem que se deseja exibir; – Bem, agora você já tem mais um 21 # para não obrigar o programador a passar monte de novidades para melhorar 22 # a msg entre aspas, usaremos $* (todos os scripts que fizemos. Você se lem- 23 # os parâmetro, lembra?) e não $1. bra do programa listartista.sh no qual 24 Msg=”$*” você passava o nome de um artista 25 TamMsg=${#Msg} como parâmetro e ele devolvia as suas 26 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha músicas? Ele era como o mostrado aqui 27 tput cup $LinhaMesg $Col embaixo na listagem 7. 28 echo “$Msg” – Claro que me lembro! 29 read -n1 – Para firmar os conceitos que te pas- 30 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela sei, faça-o com a tela formatada e a execução em loop, de forma que ele só termine quando receber um Enter no lugar do nome Não se esqueça: em caso de dúvida ou falta de compa- do artista. Suponha que a tela tenha 25 linhas; a cada 22 nhia para um chope, é só mandar um e-mail para o endereço músicas listadas o programa deverá dar uma parada para julio.neves@gmail.com que terei prazer em lhe ajudar. Vou aproveitar que o operador possa lê-las. Eventuais mensagens de erro também para mandar minha propaganda: diga aos amigos que devem ser passadas usando a rotina mandamsg.func que quem estiver a fim de fazer um curso porreta de programação acabamos de desenvolver. Chico, manda mais dois!! O meu em Shell deve mandar um e-mail para julio.neves@tecnohall.com.br é com pouca pressão… para informar-se. Até mais! ■ Listagem 7: listartista.sh Informações 01 $ cat listartista.sh [1] Bash, página oficial: 02 #!/bin/bash http://www.gnu.org/software/bash/bash.html 03 # Dado um artista, mostra as suas musicas [2] Manual de referência do Bash: 04 # versao 2 http://www.gnu.org/software/bash/ 05 if [ $# -eq 0 ] manual/bashref.html 06 then 07 echo Voce deveria ter passado pelo menos um parametro 08 exit 1 Julio Cezar Neves é Analista de Suporte de Sobre o autor 09 fi Sistemas desde 1969 e trabalha com Unix 10 IFS=” 11 :” desde 1980, quando participou do desen- 12 for ArtMus in $(cut -f2 -d^ musicas) volvimento do SOX, um sistema operacio- 13 do nal similar ao Unix produzido pela Cobra 14 echo “$ArtMus” | grep -i “^$*~” > /dev/null && echo $ArtMus | cut -f2 -d~ Computadores. Pode ser contatado no 15 done e-mail julio.neves@gmail.com maio 2005 edição 08 91 www.linuxmagazine.com.br