SlideShare uma empresa Scribd logo
1 de 6
Baixar para ler offline
Linux User                                     Papo de Botequim




                                                                        Papo de Botequim
                                                                        Curso de Shell Script



                                                                                                                                                 Parte IX

                                           Dave Hamilton - www.sxc.hu
                                                                        Hoje vamos aprender mais sobre formatação de cadeias de caracteres,
                                                                        conhecer as principais variáveis do Shell e nos aventurar no (ainda)
                                                                        desconhecido território da expansão de parâmetros. E dá-lhe chope!
                                                                        por Júlio Cezar Neves




     T
           á bom, já sei que você vai querer chope antes de começar,        Bom, a resposta é "mais ou menos". Com estes comandos
           mas tô tão a fi m de te mostrar o que fi z que já vou pedir a    você escreve 90% do que precisa, porém se precisar escrever
           rodada enquanto isso. Aê Chico, manda dois! O dele é sem       algo formatado eles lhe darão muito trabalho. Para formatar a
     colarinho pra não deixar cheiro ruim nesse bigodão…                  saída veremos agora uma instrução muito mais interessante,
        Enquanto o chope não chega, deixa eu te lembrar o que             a printf. Sua sintaxe é a seguinte:
     você me pediu na edição passada: era para refazer
     o programa listartista com a tela formatada e exe-                   Listagem 1: mandamsg.func e pergunta.func
     cução em loop, de forma que ele só termine quando          mandamsg.func
     receber um [ENTER] sozinho como nome do artista.           01 # A função recebe somente um parâmetro
     Eventuais mensagens de erro e perguntas feitas ao          02 # com a mensagem que se deseja exibir.
     usuário deveriam ser mostradas na antepenúltima            03 # Para não obrigar o programador a passar
     linha da tela, utilizando para isso as rotinas externas    04 # a msg entre aspas, usaremos $* (todos
     mandamsg.func e pergunta.func que desenvolvemos            05 # os parâmetro, lembra?) e não $1.
                                                                06 Msg="$*"
     durante nosso papo na edição passada.
                                                                07 TamMsg=${#Msg}
        Primeiramente eu dei uma encolhida nas rotinas
                                                                08 Col=$(((TotCols - TamMsg) / 2))     # Centra msg na linha
     mandamsg.func e pergunta.func, que ficaram como             09 tput cup $LinhaMesg $Col
     na listagem 1. E na listagem 2 você tem o “grandão”,       10 read -n1 -p "$Msg "
     nossa versão refeita do listaartista.
       – Puxa, você chegou com a corda toda! Gostei da          pergunta.func
     forma como você resolveu o problema e estruturou           01 # A função recebe 3 parâmetros na seguinte ordem:
                                                                02 # $1 - Mensagem a ser mostrada na tela
     o programa. Foi mais trabalhoso, mas a apresenta-
                                                                03 # $2 - Valor a ser aceito com resposta padrão
     ção ficou muito legal e você explorou bastante as
                                                                04 # $3 - O outro valor aceito
     opções do comando tput. Vamos testar o resultado
                                                                05 # Supondo que $1=Aceita?, $2=s e $3=n, a linha
     com um álbum do Emerson, Lake & Palmer que                 06 # abaixo colocaria em Msg o valor "Aceita? (S/n)"
     tenho cadastrado.                                          07 Msg="$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)"
                                                                                      08   TamMsg=${#Msg}
     Envenenando a escrita                                                            09   Col=$(((TotCols - TamMsg) / 2))   # Centraliza msg na linha
     Ufa! Agora você já sabe tudo sobre leitura de dados,                             10   tput cup $LinhaMesg $Col
     mas quanto à escrita ainda está apenas engatinhando.                             11   read -n1 -p "$Msg " SN
                                                                                      12   [ ! $SN ] && SN=$2                # Se vazia coloca default em SN
     Já sei que você vai me perguntar: “Ora, não é com o
                                                                                      13   SN=$(echo $SN | tr A-Z a-z)       # A saída de SN será em minúscula
     comando echo e com os redirecionamentos de saída
                                                                                      14   tput cup $LinhaMesg $Col; tput el # Apaga msg da tela
     que se escreve dados?”.


84    junho 2005                     edição 09
                                                                        www.linuxmagazine.com.br
Papo de Botequim               Linux User



                                                                   Listagem 2: listaartista
printf formato [argumento...]     $ cat listartista3.sh
                                  01 #!/bin/bash
  Onde formato é uma cadeia       02 # Dado um artista, mostra as suas musicas
                                  03 # versao 3
de caracteres que contém três
                                  04 LinhaMesg=$((`tput lines` - 3)) # Linha onde as msgs serão mostradas
tipos de objeto: caracteres       05 TotCols=$(tput cols)                # Qtd de colunas na tela para enquadrar msgs
simples, caracteres para es-      06 clear
pecificação de formato (ou de      07 echo "
                                                                  +–––––––––––––––––-----------------------------------+
controle) e seqüência de esca-
                                                                  | Lista Todas as Músicas de um Determinado Artista |
pe no padrão da linguagem                                         | ===== ===== == ======= == == =========== ======= |
C. argumento é a cadeia de                                        |                                                    |
caracteres a ser impressa sob                                     | Informe o Artista:                                 |
                                                                  +––––––––––––––––----------------------------------–-+"
o controle de formato.
                                  08 while true
  Cada um dos caracteres uti-     09 do
lizados é precedido pelo ca-      10     tput cup 5 51; tput ech 31 # ech=Erase chars (31 para não apagar barra vertical)
racter % e, logo a seguir, vem    11     read Nome
a especificação de formato de      12     if [ ! "$Nome" ]               # $Nome esta vazio?
                                  13     then
acordo com a tabela 1.
                                  14          . pergunta.func "Deseja Sair?" s n
  As seqüências de escape         15          [ $SN = n ] && continue
padrão da linguagem C são         16          break
sempre precedidas pelo ca-        17     fi
                                  18     fgrep -iq "^$Nome~" musicas || # fgrep não interpreta ^ como expressão regular
ractere contra-barra (). As
                                  19          {
reconhecidas pelo comando         20          . mandamsg.func "Não existe música desse artista"
printf são as da tabela 2.        21          continue
   Não acaba por aí não! Tem      22          }
                                  23     tput cup 7 29; echo '|                                                       |'
muito mais coisa sobre essa
                                  24     LinAtual=8
instrução, mas como esse é        25     IFS="
um assunto muito cheio de         26 :"
detalhes e, portanto, chato       27     for ArtMus in $(cut -f2 -d^ musicas) # Exclui nome do album
                                  28     do
para explicar e pior ainda para
                                  29          if echo "$ArtMus" | grep -iq "^$Nome~"
ler ou estudar, vamos passar      30          then
direto aos exemplos com co-       31               tput cup $LinAtual 29
mentários. Veja só:               32               echo -n '| "
                                  33               echo $ArtMus | cut -f2 -d~
                                  34               tput cup $LinAtual 82
$ printf "%c" "1 caracter"
                                  35               echo '|'
1$                                36               let LinAtual++
                                  37               if [ $LinAtual -eq $LinhaMesg ]
  Errado! Só listou 1 caractere   38               then
                                  39                   . mandamsg.func "Tecle Algo para Continuar..."
e não saltou linha ao final
                                  40                   tput cup 7 0; tput ed # Apaga a tela a partir da linha 7
                                  41                   tput cup 7 29; echo '|                                                |'
$ printf "%cn" "1 caracter"      42                   LinAtual=8
1                                 43              fi
                                  44          fi
                                  45     done
   Saltou linha mas ainda não     46     tput cup $LinAtual 29; echo '|                                                   |'
listou a cadeia inteira           47     tput cup $((++LinAtual)) 29
                                  48     read -n1 -p "+–––--Tecle Algo para Nova Consulta––––+"
                                  49     tput cup 7 0; tput ed                 # Apaga a tela a partir da linha 7
$ printf "%c caracteren" 1
                                  50 done
1 caractere                   ➟

                                                                                          junho 2005                   edição 09   85
                                                               www.linuxmagazine.com.br
Linux User                 Papo de Botequim




         Tabela 1: Formatos de caractere                  (%) significa o tamanho que a cadeia terá            O bc devolveu duas casas decimais e
                                                          após a execução do comando. Vamos ver             o printf colocou o zero à direita. O co-
      Caractere   A expressão será impressa como:
      c           Caractere simples                       a seguir mais alguns exemplos. Os co-             mando a seguir:
      d           Número no sistema decimal               mandos abaixo:
      e           Notação científica exponencial                                                             $ printf "%on" 10
      f           Número com ponto decimal (float)         $ printf "%dn" 32                                12
      g           O menor entre os formatos %e e %f com   32
                  omissão dos zeros não significativos     $ printf "%10dn" 32                                Converteu o valor 10 para base octal.
      o           Número no sistema octal                            32                                     Para melhorar experimente:
      s           Cadeia de caracteres
      x           Número no sistema hexadecimal
                                                            preenchem a string com espaços em               $ printf "%03on" 27
      %           Imprime um %. Não há nenhum
                  tipo de conversão                       branco à esquerda (oito espaços mais dois         033
                                                          caracteres, 10 dígitos), não com zeros. Já
                                                          no comando abaixo:                                  Assim a conversão fica com mais jeito
       Opa, essa é a forma correta! O %c rece-                                                              de octal, né?. O que este aqui faz?
     beu o valor 1, como queríamos:                       $ printf "%04dn" 32
                                                          0032                                              $ printf "%sn" Peteleca
     $ a=2                                                                                                  Peteleca
     $ printf "%c caracteresn" $a                          O 04 após % significa “formate a string          $ printf "%15sn" Peteleca
     2 caracteres                                         em quatro dígitos, com zeros à esquerda                  Peteleca
                                                          se necessário”. No comando:
         O %c recebeu o valor da variável $a.                                                                 Imprime Peteleca com 15 caracteres.
                                                          $ printf "%en" $(echo "scale=2 ; 100/6" | bc)    A cadeia de caracteres é preenchida com
     $ printf "%10c caracteresn" $a                      1.666000e+01                                      espaços em branco à esquerda. Já no co-
                  2 caracteres                                                                              mando:
     $ printf "%10cn" $a caracteres                        O padrão do %e é seis casas decimais.
                  2                                       Já no comando:                                    $ printf "%-15sNevesn" Peteleca
                  c                                                                                         Peteleca          Neves
                                                          $ printf "%.2en" `echo "scale=2 ; 100/6" | bc`
        Repare que, nos dois últimos exemplos,            1.67e+01                                            O menos (-) colocou espaços em branco
     em virtude do uso do %c, só foi listado                                                                à direita de Peteleca até completar os 15
     um caractere de cada cadeia de caracteres             O .2 especificou duas casas decimais.             caracteres pedidos. E o comando abaixo,
     passada como parâmetro. O valor 10 à                 Observe agora:                                    o que faz?
     frente do c não significa 10 caracteres. Um
     número seguindo o sinal de percentagem               $ printf "%fn" 32.3                              $ printf "%.3sn" Peteleca
                                                          32.300000                                         Pet
         Tabela 2: Seqüências de escape
                                                            O padrão do %f é seis casas decimais.             O .3 manda truncar a cadeia de ca-
     Seqüência        Efeito
                                                          E no comando:                                     racteres após as três primeiras letras. E
     a                Soa o beep
     b                Volta uma posição (backspace)                                                         o comando a seguir:
     f                Salta para a próxima página         $ printf "%.2fn" 32.3
                      lógica ( form feed)                 32.30                                             $ printf "%10.3san" Peteleca
     n                Salta para o início da linha se-                                                             Peta Pet
                      guinte (line feed)                    O .2 especificou duas casas decimais.
     r                Volta para o início da linha cor-
                                                          Agora observe:                                      Imprime a cadeia com 10 caracteres,
                      rente (carriage return)
                                                                                                            truncada após os três primeiros, conca-
     t                Avança para a próxima marca de
                      tabulação                           $ printf "%.3fn" `echo "scale=2 ; 100/6" | bc`   tenada com o caractere a (após o s). E
                                                          33.330                                            esse comando a seguir, o que faz?


86    junho 2005                              edição 09
                                                          www.linuxmagazine.com.br
Papo de Botequim             Linux User



 $ printf “EXEMPLO %xn” 45232                trabalho, principalmente em instalações        (1 minuto). A cada intervalo o Shell fará
 EXEMPLO b0b0                                 com estrutura de diretórios em múltiplos       a verificação antes de exibir o próximo
                                              níveis. Veja o exemplo a seguir:               prompt primário ($PS1). Se essa variável
  Ele transformou o número 45232 para                                                        estiver sem valor ou com um valor menor
hexadecimal (b0b0), mas os zeros não          $ echo $CDPATH                                 ou igual a zero, a busca por novas men-
combinam com o resto. Experimente:           .:..:~:/usr/local                               sagens não será efetuada.
                                              $ pwd                                            PATH » Caminhos que serão pesquisa-
 $ printf “EXEMPLO %Xn” 45232                /home/jneves/LM                                dos para tentar localizar um arquivo espe-
 EXEMPLO B0B0                                 $ cd bin                                       cificado. Como cada script é um arquivo,
                                              $ pwd                                          caso use o diretório corrente (.) na sua
 Assim disfarçou melhor! (repare no X         /usr/local/bin                                 variável $PATH, você não necessitará usar
maiúsculo). Pra terminar, que tal o co-                                                      o comando ./scrp para que o script scrp
mando abaixo:                                   Como /usr/local estava na minha              seja executado. Basta digitar scrp. Este
                                              variável $CDPATH e não existia o diretório     é o modo que prefiro.
 $ printf “%X %XL%Xn” 49354 192 10           bin em nenhum dos seus antecessores (.,          PIPESTATUS » É uma variável do tipo
 C0CA C0LA                                   .. e ~), o comando cd foi executado tendo       vetor (array) que contém uma lista de
                                              como destino /usr/local/bin.                   valores de códigos de retorno do último
   Este aí não é marketing e é bastante         HISTSIZE » Limita o número de ins-           pipeline executado, isto é, um array que
 completo, veja só como funciona:             truções que cabem dentro do arquivo de         abriga cada um dos $? de cada instrução
   O primeiro %X converteu 49354 em he-       histórico de comandos (normalmente             do último pipeline. Para entender melhor,
 xadecimal, resultando em C0CA (leia-se      .bash_history, mas na verdade é o que           veja o exemplo a seguir:
“cê”, “zero”, “cê” e “a”). Em seguida veio    está indicado na variável $HISTFILE). Seu
 um espaço em branco seguido por outro        valor padrão é 500.                            $ who
 %XL. O %X converteu o 192 dando como           HOSTNAME » O nome do host corrente           jneves pts/0 Apr 11 16:26 (10.2.4.144)
 resultado C0 que com o L fez C0L. E final-    (que também pode ser obtido com o co-          jneves pts/1 Apr 12 12:04 (10.2.4.144)
 mente o último parâmetro %X transformou      mando uname -n).                               $ who | grep ^botelho
 o número 10 na letra A.                        LANG » Usada para determinar o idioma        $ echo ${PIPESTATUS[*]}
   Conforme vocês podem notar, a instru-      falado no país (mais especificamente ca-        0 1
 ção é bastante completa e complexa. Ain-     tegoria do locale). Veja um exemplo:
 da bem que o echo resolve quase tudo...                                                       Neste exemplo mostramos que o usu-
   Acertei em cheio quando resolvi expli-     $ date                                         ário botelho não estava “logado”, em
 car o printf através de exemplos, pois       Thu Apr 14 11:54:13 BRT 2005                   seguida executamos um pipeline que
 não saberia como enumerar tantas regri-      $ LANG=pt_BR date                              procurava por ele. Usa-se a notação [*]
 nhas sem tornar a leitura enfadonha.         Qui Abr 14 11:55:14 BRT 2005                   em um array para listar todos os seus
                                                                                             elementos; dessa forma, vimos que a pri-
 Principais variáveis do Shell                 LINENO » O número da linha do script          meira instrução (who) foi bem-sucedida
O Bash possui diversas variáveis que         ou função que está sendo executada.             (código de retorno 0) e a seguinte (grep)
servem para dar informações sobre            Seu uso principal é mostrar mensagens           não (código de retorno 1).
o ambiente ou alterá-lo. São muitas e        de erro juntamente com as variáveis $0            PROMPT_COMMAND » Se esta variável re-
não pretendo mostrar todas elas, mas         (nome do programa) e $FUNCNAME (nome            ceber o nome de um comando, toda vez
uma pequena parte pode lhe ajudar na         da função em execução).                         que você teclar um [ENTER] sozinho no
elaboração de scripts. Veja a seguir as        LOGNAME » Esta variável armazena o            prompt principal ($PS1), esse comando
principais delas:                            nome de login do usuário .                      será executado. É muito útil quando você
  CDPATH » Contém os caminhos que               MAILCHECK » Especifica, em segundos, a        precisa repetindo constantemente uma
serão pesquisados para tentar localizar      freqüência com que o Shell verifica a pre-       determinada instrução.
um diretório especificado. Apesar dessa       sença de correspondência nos arquivos             PS1 » É o prompt principal. No “Papo
variável ser pouco conhecida, seu uso        indicados pela variáveis $MAILPATH ou           de Botequim” usamos os padrões $ para
deve ser incentivado por poupar muito        $MAIL. O tempo padrão é de 60 segundos          usuário comum e # para root, mas é mui-


                                                                                             junho 2005                     edição 09     87
                                                                  www.linuxmagazine.com.br
Linux User               Papo de Botequim




     to freqüente que ele esteja personalizado.    Expansão de parâmetros                         $ cadeia="Papo de Botequim"
     Uma curiosidade é que existe até concurso     Bem, muito do que vimos até agora são          $ echo ${cadeia#*' '}
     de quem programa o $PS1 mais criativo.        comandos externos ao Shell. Eles quebram       de Botequim
       PS2 » Também chamado “prompt de             o maior galho, facilitam a visualização,       $ echo "Conversa "${cadeia#*' '}
     continuação”, é aquele sinal de maior         manutenção e depuração do código, mas          Conversa de Botequim
     (>) que aparece após um [ENTER] sem           não são tão eficientes quanto os intrínse-
     o comando ter sido encerrado.                 cos (built-ins). Quando o nosso problema         No exemplo anterior foi suprimido à
       PWD » Possui o caminho completo             for performance, devemos dar preferência       esquerda tudo o que “casa” com a menor
     ($PATH) do diretório corrente. Tem o          ao uso dos intrínsecos. A partir de agora      ocorrência da expressão *’ ‘, ou seja,
     mesmo efeito do comando pwd.                  vou te mostrar algumas técnicas para o         todos os caracteres até o primeiro espaço
       RANDOM » Cada vez que esta variável é       seu programa pisar no acelerador.              em branco. Esses exemplos também po-
     acessada, devolve um inteiro aleatório en-      Na tabela 3 e nos exemplos a seguir,         deriam ser escritos sem proteger o espaço
     tre 0 e 32767. Para gerar um inteiro entre    veremos uma série de construções cha-          da interpretação do Shell (mas prefiro
     0 e 100, por exemplo, digitamos:              madas expansão (ou substituição) de            protegê-lo para facilitar a legibilidade
                                                   parâmetros (Parameter Expansion), que          do código). Veja só:
     $ echo $((RANDOM%101))                        substituem instruções como o cut, o expr,
     73                                            o tr, o sed e outras de forma mais ágil.       $ echo ${cadeia#* }
                                                     Vamos ver alguns exemplos: se em uma         de Botequim
       Ou seja, pegamos o resto da divisão do      pergunta o S é oferecido como valor de-        $ echo "Conversa "${cadeia#* }
     número randômico gerado por 101 porque        fault (padrão) e a saída vai para a variável   Conversa de Botequim
     o resto da divisão de qualquer número         SN, após ler o valor podemos fazer:
     por 101 varia entre 0 e 100.                                                                   Repare que na construção de expr é
       REPLY » Use esta variável para recuperar    SN=$(SN:-S}                                    permitido o uso de metacaracteres.
     o último campo lido, caso ele não tenha                                                        Utilizando o mesmo valor da variável
     nenhuma variável associada. Exemplo:              Para saber o tamanho de uma cadeia:        cadeia, observe como faríamos para ter
                                                                                                  somente Botequim :
     $ read -p "Digite S ou N: "                   $ cadeia=0123
     Digite S ou N: N                              $ echo ${#cadeia}                              $ echo ${cadeia##*' '}
     $ echo $REPLY                                 4                                              Botequim
     N                                                                                            $ echo "Vamos 'Chopear' no "${cadeia##*' '}
                                                     Para extrair dados de cadeia, da posi-       Vamos 'Chopear' no Botequim
         SECONDS » Esta variável informa, em se-   ção um até o final fazemos:
     gundos, há quanto tempo o Shell corrente                                                       Desta vez suprimimos à esquerda de
     está “de pé”. Use-a para demonstrar a         $ cadeia=abcdef                                cadeia a maior ocorrência da expressão
     estabilidade do Linux e esnobar usuários      $ echo ${cadeia:1}                             expr. Assim como no caso anterior, o uso
     daquela coisa com janelinhas coloridas        bcdef                                          de metacaracteres é permitido.
     que chamam de sistema operacional, mas                                                         Outro exemplo mais útil: para que não
     que necessita de “reboots” freqüentes.          Repare que a origem é zero e não um.         apareça o caminho (path) completo do seu
       TMOUT » Se esta variável contiver um        Vamos extrair 3 caracteres a partir da 2ª      programa ($0) em uma mensagem de erro,
     valor maior do que zero, esse valor           posição da mesma variável cadeia:              inicie o seu texto da seguinte forma:
     será considerado o timeout padrão do
     comando read. No prompt, esse valor           $ echo ${cadeia:2:3}                           echo Uso: ${0##*/} texto da mensagem de erro
     é interpretado como o tempo de espera         cde
     por uma ação antes de expirar a sessão.                                                        Neste exemplo seria suprimido à es-
     Supondo que a variável contenha o valor         Repare que novamente a origem da con-        querda tudo até a última barra (/) do
     30, o Shell encerrará a sessão do usuário     tagem é zero e não um. Para suprimir           caminho, restando somente o nome do
     (ou seja, fará logout) após 30 segundos       tudo à esquerda da primeira ocorrência         programa. O caractere % é simétrico ao
     sem nenhuma ação no prompt.                   de uma cadeia, faça:                           #, veja o exemplo:



88    junho 2005                      edição 09
                                                   www.linuxmagazine.com.br
Papo de Botequim                  Linux User



                    Tabela 3: Tipos de expansão de parâmetros                                          Há várias formas de trocar uma subca-
                                                                                                     deia no início ou no fim de uma variável.
 Expansão de parâmetros Resultado esperado
                                                                                                     Para trocar no início fazemos:
${var:-padrao}             Se var é vazia, o resultado da expressão é padrão
${#cadeia}                 Tamanho de $cadeia
${cadeia:posicao}          Extrai uma subcadeia de $cadeia a partir de posição. Origem zero            $ echo $Passaro
${cadeia:posicao:tamanho}  Extrai uma subcadeia de $cadeia a partir de posição com tamanho             quero quero
                           igual a tamanho. Origem zero                                                $ echo “Como diz o sulista - “${PassaroU
${cadeia#expr}             Corta a menor ocorrência de $cadeia à esquerda da expressão expr           /#quero/não}
${cadeia##expr}            Corta a maior ocorrência de $cadeia à esquerda da expressão expr            Como diz o sulista - não quero
${cadeia%expr}             Corta a menor ocorrência de $cadeia à direita da expressão expr
${cadeia%%expr}            Corta a maior ocorrência de $cadeia à direita da expressão expr
                                                                                                           Para trocar no final fazemos:
${cadeia/subcad1/subcad2} Troca a primeira ocorrência de subcad1 por subcad2
${cadeia//subcad1/subcad2} Troca todas as ocorrências de subcad1 por subcad2
${cadeia/#subcad1/subcad2} Se subcad1 combina com o início de cadeia, então é trocado por subcad2      $ echo “Como diz o nordestino - U

${cadeia/%subcad1/subcad2} Se subcad1 combina com o fim de cadeia, então é trocado por subcad2        “${Passaro/%quero/não}
                                                                                                       Como diz o nordestino - quero não


$ echo $cadeia                                     $ echo ${cadeia/*po/Conversa}                    – Agora já chega, o papo hoje foi chato
Papo de Botequim                                   Conversa de Botequim                               porque teve muita decoreba, mas o que
$ echo ${cadeia%' '*}                              $ echo ${cadeia/????/Conversa}                     mais importa é você ter entendido o
Papo de                                            Conversa de Botequim                               que te falei. Quando precisar, consulte
$ echo ${cadeia%%' '*}                                                                                estes guardanapos onde rabisquei as
Papo                                                Trocando todas as ocorrências de uma              dicas e depois guarde-os para consultas
                                                  subcadeia por outra. O comando:                     futuras. Mas voltando à vaca fria: tá
  Para trocar primeira ocorrência de uma                                                              na hora de tomar outro e ver o jogo do
subcadeia em uma cadeia por outra:                 $ echo ${cadeia//o/a}                              Mengão. Pra próxima vez vou te dar
                                                   Papa de Batequim                                   moleza e só vou cobrar o seguinte: pe-
$ echo $cadeia                                                                                        gue a rotina pergunta.func (da qual
Papo de Botequim                                     Ordena a troca de todos as letras o por          falamos no início do nosso bate-papo
$ echo ${cadeia/de/no}                            a. Outro exemplo mais útil é para contar            de hoje, veja a listagem 1) e otimize-a
Papo no Botequim                                  a quantidade de arquivos existentes no              para que a variável $SN receba o valor
$ echo ${cadeia/de /}                             diretório corrente. Observe o exemplo:              padrão por expansão de parâmetros,
Papo Botequim                                                                                         como vimos.
                                                   $ ls | wc -l                                        E não se esqueça: em caso de dúvidas
  Preste atenção quando for usar metaca-                 30                                          ou falta de companhia para um (ou mais)
racteres! Eles são gulosos e sempre com-                                                             chope é só mandar um e-mail para julio.
binarão com a maior possibilidade; No               O wc põe um monte de espaços em                  neves@gmail.com. E diga para os amigos
exemplo a seguir eu queria trocar Papo de         branco antes do resultado. Para tirá-los:          que quem estiver a fim de fazer um curso
Botequim por Conversa de Botequim:                                                                   porreta de programação em Shell deve
                                                   # QtdArqs recebe a saída do comando               mandar um e-mail para julio.neves@tecnohall.
$ echo $cadeia                                     $ QtdArqs=$(ls | wc -l)                           com.br para informar-se. Valeu!         ■
Papo de Botequim                                   $ echo ${QtdArqs/ * /}
$ echo ${cadeia/*o/Conversa}                       30                                                               Julio Cezar Neves é Analista de Suporte de
                                                                                                    Sobre o autor




Conversatequim                                                                                                      Sistemas desde 1969 e trabalha com Unix
                                                    Nesse exemplo, eu sabia que a saída era                         desde 1980, quando participou do desen-
  A idéia era pegar tudo até o primeiro           composta de brancos e números, por isso                           volvimento do SOX, um sistema operacio-
o, mas acabou sendo trocado tudo até o            montei essa expressão para trocar todos os                        nal similar ao Unix produzido pela Cobra
último o. Isto poderia ser resolvido de           espaços por nada. Note que antes e após o                         Computadores. Pode ser contatado no
diversas maneiras. Eis algumas:                   asterisco (*) há espaços em branco.                               e-mail julio.neves@gmail.com



                                                                                                     junho 2005                                    edição 09     89
                                                                         www.linuxmagazine.com.br

Mais conteúdo relacionado

Mais procurados

Mais procurados (19)

Shell Script
Shell ScriptShell Script
Shell Script
 
Programação em Shell Script
Programação em Shell ScriptProgramação em Shell Script
Programação em Shell Script
 
Perl From Vi, Part I
Perl From Vi, Part IPerl From Vi, Part I
Perl From Vi, Part I
 
Shell Script - Luz e trevas
Shell Script - Luz e trevasShell Script - Luz e trevas
Shell Script - Luz e trevas
 
12 aula - shell script-2015
12   aula - shell script-201512   aula - shell script-2015
12 aula - shell script-2015
 
Shell script
Shell script Shell script
Shell script
 
Python
PythonPython
Python
 
Apostila c
Apostila cApostila c
Apostila c
 
Crash Course Ruby & Rails
Crash Course Ruby & RailsCrash Course Ruby & Rails
Crash Course Ruby & Rails
 
O Que é Shell (bash)
O Que é Shell (bash)O Que é Shell (bash)
O Que é Shell (bash)
 
Aula6 - Linguagem C
Aula6 - Linguagem CAula6 - Linguagem C
Aula6 - Linguagem C
 
Pged 01
Pged 01Pged 01
Pged 01
 
Manual comandos
Manual comandosManual comandos
Manual comandos
 
Aula 02 - Curso PHP e MySQL
Aula 02 - Curso PHP e MySQLAula 02 - Curso PHP e MySQL
Aula 02 - Curso PHP e MySQL
 
Manual-de-php
Manual-de-phpManual-de-php
Manual-de-php
 
Pipeline desdobramento escalonamento
Pipeline desdobramento escalonamentoPipeline desdobramento escalonamento
Pipeline desdobramento escalonamento
 
15080590 aula6-estrutura-de-repeticao
15080590 aula6-estrutura-de-repeticao15080590 aula6-estrutura-de-repeticao
15080590 aula6-estrutura-de-repeticao
 
M5-Desenvolvimento-Paginas-Web
M5-Desenvolvimento-Paginas-WebM5-Desenvolvimento-Paginas-Web
M5-Desenvolvimento-Paginas-Web
 
Aula 01 - Curso PHP e MySQL
Aula 01 - Curso PHP e MySQLAula 01 - Curso PHP e MySQL
Aula 01 - Curso PHP e MySQL
 

Destaque

Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)
Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)
Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)Rafael Alvarez Alonso
 
Projeto Feciarte
Projeto FeciarteProjeto Feciarte
Projeto Feciartearteluanna
 
Trabalho expo pinheiro 2012
Trabalho expo pinheiro 2012Trabalho expo pinheiro 2012
Trabalho expo pinheiro 2012Leonardo Dunham
 
Avc- Acidente Vascular Cerebral
Avc- Acidente Vascular CerebralAvc- Acidente Vascular Cerebral
Avc- Acidente Vascular CerebralGabi Eliza
 
Metodologias da pesquisa qualitativa em educação
Metodologias da pesquisa qualitativa em educaçãoMetodologias da pesquisa qualitativa em educação
Metodologias da pesquisa qualitativa em educaçãogrupopesquisamusicauergs
 
Osso artificiale per test in laboratorio su dispositivi odontoiatrici
Osso artificiale per test in laboratorio su dispositivi odontoiatriciOsso artificiale per test in laboratorio su dispositivi odontoiatrici
Osso artificiale per test in laboratorio su dispositivi odontoiatriciTogetherToSolve
 
THALES DUBAI METRO 3
THALES DUBAI METRO 3THALES DUBAI METRO 3
THALES DUBAI METRO 3Essam Farag
 
Saúde na nigéria
Saúde na nigériaSaúde na nigéria
Saúde na nigériawendel_bac
 
Emprendimeinto clei 5 a2
Emprendimeinto clei 5 a2Emprendimeinto clei 5 a2
Emprendimeinto clei 5 a2Nathanoj Jovans
 
Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"
Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"
Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"Sifnaiko Fos - Σιφναϊκό Φως
 
Fahmi hidayat 1 eb ms.word
Fahmi hidayat   1 eb ms.wordFahmi hidayat   1 eb ms.word
Fahmi hidayat 1 eb ms.wordfahmihid
 
Teste
TesteTeste
TesteSEE
 

Destaque (20)

Estatística
EstatísticaEstatística
Estatística
 
Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)
Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)
Fitxa tasca 2.6.m.c.m. i m.c.d. (per a classe)
 
Projeto Feciarte
Projeto FeciarteProjeto Feciarte
Projeto Feciarte
 
Alianca_marco_2012
Alianca_marco_2012Alianca_marco_2012
Alianca_marco_2012
 
Trabalho expo pinheiro 2012
Trabalho expo pinheiro 2012Trabalho expo pinheiro 2012
Trabalho expo pinheiro 2012
 
Avc- Acidente Vascular Cerebral
Avc- Acidente Vascular CerebralAvc- Acidente Vascular Cerebral
Avc- Acidente Vascular Cerebral
 
Metodologias da pesquisa qualitativa em educação
Metodologias da pesquisa qualitativa em educaçãoMetodologias da pesquisa qualitativa em educação
Metodologias da pesquisa qualitativa em educação
 
Rio mondego
Rio mondegoRio mondego
Rio mondego
 
Osso artificiale per test in laboratorio su dispositivi odontoiatrici
Osso artificiale per test in laboratorio su dispositivi odontoiatriciOsso artificiale per test in laboratorio su dispositivi odontoiatrici
Osso artificiale per test in laboratorio su dispositivi odontoiatrici
 
Oye coño
Oye coñoOye coño
Oye coño
 
THALES DUBAI METRO 3
THALES DUBAI METRO 3THALES DUBAI METRO 3
THALES DUBAI METRO 3
 
Mat79a
Mat79aMat79a
Mat79a
 
Saúde na nigéria
Saúde na nigériaSaúde na nigéria
Saúde na nigéria
 
Emprendimeinto clei 5 a2
Emprendimeinto clei 5 a2Emprendimeinto clei 5 a2
Emprendimeinto clei 5 a2
 
Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"
Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"
Η περίπτωση του "Ομίλου Προβληματισμού για τον εκσυγχρονισμό της κοινωνίας"
 
Fahmi hidayat 1 eb ms.word
Fahmi hidayat   1 eb ms.wordFahmi hidayat   1 eb ms.word
Fahmi hidayat 1 eb ms.word
 
Teste
TesteTeste
Teste
 
Brasil gug
Brasil gugBrasil gug
Brasil gug
 
Você sabe amar
Você sabe amarVocê sabe amar
Você sabe amar
 
15062016104207
1506201610420715062016104207
15062016104207
 

Semelhante a Curso de Shell Script 09/11

Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9Pessoal
 
Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10Pessoal
 
Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3Pessoal
 
Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6Pessoal
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordidaLuciano Ramalho
 
10 Boas Práticas de Programação
10 Boas Práticas de Programação10 Boas Práticas de Programação
10 Boas Práticas de ProgramaçãoCarlos Schults
 
Sapo sessions linux power tools
Sapo sessions linux power toolsSapo sessions linux power tools
Sapo sessions linux power toolsArmando Reis
 
Introdução a Linguagem C
Introdução a Linguagem CIntrodução a Linguagem C
Introdução a Linguagem Capolllorj
 
Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5Pessoal
 
unidade04-c3-handout.pdf
unidade04-c3-handout.pdfunidade04-c3-handout.pdf
unidade04-c3-handout.pdfAlexSouza974126
 
Tradutor de Pig Latin
Tradutor de Pig LatinTradutor de Pig Latin
Tradutor de Pig LatinElen Arantza
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9Nando Vieira
 
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUACândido Sales Gomes
 
C curso - notas de aula
C   curso - notas de aulaC   curso - notas de aula
C curso - notas de aulaLoAlves21
 

Semelhante a Curso de Shell Script 09/11 (20)

Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9Curso de ShellScript - Lm09 shellscript9
Curso de ShellScript - Lm09 shellscript9
 
Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10Curso de ShellScript - Lm10 shellscript10
Curso de ShellScript - Lm10 shellscript10
 
Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3Curso de ShellScript - Lm03 shellscript3
Curso de ShellScript - Lm03 shellscript3
 
Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6Curso de ShellScript - Lm06 shellscript6
Curso de ShellScript - Lm06 shellscript6
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordida
 
10 Boas Práticas de Programação
10 Boas Práticas de Programação10 Boas Práticas de Programação
10 Boas Práticas de Programação
 
Sapo sessions linux power tools
Sapo sessions linux power toolsSapo sessions linux power tools
Sapo sessions linux power tools
 
Introdução a Linguagem C
Introdução a Linguagem CIntrodução a Linguagem C
Introdução a Linguagem C
 
Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5Curso de ShellScript - Lm05 shellscript5
Curso de ShellScript - Lm05 shellscript5
 
Linguagem C clecioamerico
Linguagem C clecioamericoLinguagem C clecioamerico
Linguagem C clecioamerico
 
Cool 3 assembly para linux
Cool 3   assembly para linuxCool 3   assembly para linux
Cool 3 assembly para linux
 
10-Matlab.pdf
10-Matlab.pdf10-Matlab.pdf
10-Matlab.pdf
 
unidade04-c3-handout.pdf
unidade04-c3-handout.pdfunidade04-c3-handout.pdf
unidade04-c3-handout.pdf
 
Palestra Ruby
Palestra RubyPalestra Ruby
Palestra Ruby
 
Tradutor de Pig Latin
Tradutor de Pig LatinTradutor de Pig Latin
Tradutor de Pig Latin
 
Fpar aula5
Fpar aula5Fpar aula5
Fpar aula5
 
Aula de C e C++
Aula de C e C++Aula de C e C++
Aula de C e C++
 
O que mudou no Ruby 1.9
O que mudou no Ruby 1.9O que mudou no Ruby 1.9
O que mudou no Ruby 1.9
 
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
 
C curso - notas de aula
C   curso - notas de aulaC   curso - notas de aula
C curso - notas de aula
 

Curso de Shell Script 09/11

  • 1. Linux User Papo de Botequim Papo de Botequim Curso de Shell Script Parte IX Dave Hamilton - www.sxc.hu Hoje vamos aprender mais sobre formatação de cadeias de caracteres, conhecer as principais variáveis do Shell e nos aventurar no (ainda) desconhecido território da expansão de parâmetros. E dá-lhe chope! por Júlio Cezar Neves T á bom, já sei que você vai querer chope antes de começar, Bom, a resposta é "mais ou menos". Com estes comandos mas tô tão a fi m de te mostrar o que fi z que já vou pedir a você escreve 90% do que precisa, porém se precisar escrever rodada enquanto isso. Aê Chico, manda dois! O dele é sem algo formatado eles lhe darão muito trabalho. Para formatar a colarinho pra não deixar cheiro ruim nesse bigodão… saída veremos agora uma instrução muito mais interessante, Enquanto o chope não chega, deixa eu te lembrar o que a printf. Sua sintaxe é a seguinte: você me pediu na edição passada: era para refazer o programa listartista com a tela formatada e exe- Listagem 1: mandamsg.func e pergunta.func cução em loop, de forma que ele só termine quando mandamsg.func receber um [ENTER] sozinho como nome do artista. 01 # A função recebe somente um parâmetro Eventuais mensagens de erro e perguntas feitas ao 02 # com a mensagem que se deseja exibir. usuário deveriam ser mostradas na antepenúltima 03 # Para não obrigar o programador a passar linha da tela, utilizando para isso as rotinas externas 04 # a msg entre aspas, usaremos $* (todos mandamsg.func e pergunta.func que desenvolvemos 05 # os parâmetro, lembra?) e não $1. 06 Msg="$*" durante nosso papo na edição passada. 07 TamMsg=${#Msg} Primeiramente eu dei uma encolhida nas rotinas 08 Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha mandamsg.func e pergunta.func, que ficaram como 09 tput cup $LinhaMesg $Col na listagem 1. E na listagem 2 você tem o “grandão”, 10 read -n1 -p "$Msg " nossa versão refeita do listaartista. – Puxa, você chegou com a corda toda! Gostei da pergunta.func forma como você resolveu o problema e estruturou 01 # A função recebe 3 parâmetros na seguinte ordem: 02 # $1 - Mensagem a ser mostrada na tela o programa. Foi mais trabalhoso, mas a apresenta- 03 # $2 - Valor a ser aceito com resposta padrão ção ficou muito legal e você explorou bastante as 04 # $3 - O outro valor aceito opções do comando tput. Vamos testar o resultado 05 # Supondo que $1=Aceita?, $2=s e $3=n, a linha com um álbum do Emerson, Lake & Palmer que 06 # abaixo colocaria em Msg o valor "Aceita? (S/n)" tenho cadastrado. 07 Msg="$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)" 08 TamMsg=${#Msg} Envenenando a escrita 09 Col=$(((TotCols - TamMsg) / 2)) # Centraliza msg na linha Ufa! Agora você já sabe tudo sobre leitura de dados, 10 tput cup $LinhaMesg $Col mas quanto à escrita ainda está apenas engatinhando. 11 read -n1 -p "$Msg " SN 12 [ ! $SN ] && SN=$2 # Se vazia coloca default em SN Já sei que você vai me perguntar: “Ora, não é com o 13 SN=$(echo $SN | tr A-Z a-z) # A saída de SN será em minúscula comando echo e com os redirecionamentos de saída 14 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela que se escreve dados?”. 84 junho 2005 edição 09 www.linuxmagazine.com.br
  • 2. Papo de Botequim Linux User Listagem 2: listaartista printf formato [argumento...] $ cat listartista3.sh 01 #!/bin/bash Onde formato é uma cadeia 02 # Dado um artista, mostra as suas musicas 03 # versao 3 de caracteres que contém três 04 LinhaMesg=$((`tput lines` - 3)) # Linha onde as msgs serão mostradas tipos de objeto: caracteres 05 TotCols=$(tput cols) # Qtd de colunas na tela para enquadrar msgs simples, caracteres para es- 06 clear pecificação de formato (ou de 07 echo " +–––––––––––––––––-----------------------------------+ controle) e seqüência de esca- | Lista Todas as Músicas de um Determinado Artista | pe no padrão da linguagem | ===== ===== == ======= == == =========== ======= | C. argumento é a cadeia de | | caracteres a ser impressa sob | Informe o Artista: | +––––––––––––––––----------------------------------–-+" o controle de formato. 08 while true Cada um dos caracteres uti- 09 do lizados é precedido pelo ca- 10 tput cup 5 51; tput ech 31 # ech=Erase chars (31 para não apagar barra vertical) racter % e, logo a seguir, vem 11 read Nome a especificação de formato de 12 if [ ! "$Nome" ] # $Nome esta vazio? 13 then acordo com a tabela 1. 14 . pergunta.func "Deseja Sair?" s n As seqüências de escape 15 [ $SN = n ] && continue padrão da linguagem C são 16 break sempre precedidas pelo ca- 17 fi 18 fgrep -iq "^$Nome~" musicas || # fgrep não interpreta ^ como expressão regular ractere contra-barra (). As 19 { reconhecidas pelo comando 20 . mandamsg.func "Não existe música desse artista" printf são as da tabela 2. 21 continue Não acaba por aí não! Tem 22 } 23 tput cup 7 29; echo '| |' muito mais coisa sobre essa 24 LinAtual=8 instrução, mas como esse é 25 IFS=" um assunto muito cheio de 26 :" detalhes e, portanto, chato 27 for ArtMus in $(cut -f2 -d^ musicas) # Exclui nome do album 28 do para explicar e pior ainda para 29 if echo "$ArtMus" | grep -iq "^$Nome~" ler ou estudar, vamos passar 30 then direto aos exemplos com co- 31 tput cup $LinAtual 29 mentários. Veja só: 32 echo -n '| " 33 echo $ArtMus | cut -f2 -d~ 34 tput cup $LinAtual 82 $ printf "%c" "1 caracter" 35 echo '|' 1$ 36 let LinAtual++ 37 if [ $LinAtual -eq $LinhaMesg ] Errado! Só listou 1 caractere 38 then 39 . mandamsg.func "Tecle Algo para Continuar..." e não saltou linha ao final 40 tput cup 7 0; tput ed # Apaga a tela a partir da linha 7 41 tput cup 7 29; echo '| |' $ printf "%cn" "1 caracter" 42 LinAtual=8 1 43 fi 44 fi 45 done Saltou linha mas ainda não 46 tput cup $LinAtual 29; echo '| |' listou a cadeia inteira 47 tput cup $((++LinAtual)) 29 48 read -n1 -p "+–––--Tecle Algo para Nova Consulta––––+" 49 tput cup 7 0; tput ed # Apaga a tela a partir da linha 7 $ printf "%c caracteren" 1 50 done 1 caractere ➟ junho 2005 edição 09 85 www.linuxmagazine.com.br
  • 3. Linux User Papo de Botequim Tabela 1: Formatos de caractere (%) significa o tamanho que a cadeia terá O bc devolveu duas casas decimais e após a execução do comando. Vamos ver o printf colocou o zero à direita. O co- Caractere A expressão será impressa como: c Caractere simples a seguir mais alguns exemplos. Os co- mando a seguir: d Número no sistema decimal mandos abaixo: e Notação científica exponencial $ printf "%on" 10 f Número com ponto decimal (float) $ printf "%dn" 32 12 g O menor entre os formatos %e e %f com 32 omissão dos zeros não significativos $ printf "%10dn" 32 Converteu o valor 10 para base octal. o Número no sistema octal 32 Para melhorar experimente: s Cadeia de caracteres x Número no sistema hexadecimal preenchem a string com espaços em $ printf "%03on" 27 % Imprime um %. Não há nenhum tipo de conversão branco à esquerda (oito espaços mais dois 033 caracteres, 10 dígitos), não com zeros. Já no comando abaixo: Assim a conversão fica com mais jeito Opa, essa é a forma correta! O %c rece- de octal, né?. O que este aqui faz? beu o valor 1, como queríamos: $ printf "%04dn" 32 0032 $ printf "%sn" Peteleca $ a=2 Peteleca $ printf "%c caracteresn" $a O 04 após % significa “formate a string $ printf "%15sn" Peteleca 2 caracteres em quatro dígitos, com zeros à esquerda Peteleca se necessário”. No comando: O %c recebeu o valor da variável $a. Imprime Peteleca com 15 caracteres. $ printf "%en" $(echo "scale=2 ; 100/6" | bc) A cadeia de caracteres é preenchida com $ printf "%10c caracteresn" $a 1.666000e+01 espaços em branco à esquerda. Já no co- 2 caracteres mando: $ printf "%10cn" $a caracteres O padrão do %e é seis casas decimais. 2 Já no comando: $ printf "%-15sNevesn" Peteleca c Peteleca Neves $ printf "%.2en" `echo "scale=2 ; 100/6" | bc` Repare que, nos dois últimos exemplos, 1.67e+01 O menos (-) colocou espaços em branco em virtude do uso do %c, só foi listado à direita de Peteleca até completar os 15 um caractere de cada cadeia de caracteres O .2 especificou duas casas decimais. caracteres pedidos. E o comando abaixo, passada como parâmetro. O valor 10 à Observe agora: o que faz? frente do c não significa 10 caracteres. Um número seguindo o sinal de percentagem $ printf "%fn" 32.3 $ printf "%.3sn" Peteleca 32.300000 Pet Tabela 2: Seqüências de escape O padrão do %f é seis casas decimais. O .3 manda truncar a cadeia de ca- Seqüência Efeito E no comando: racteres após as três primeiras letras. E a Soa o beep b Volta uma posição (backspace) o comando a seguir: f Salta para a próxima página $ printf "%.2fn" 32.3 lógica ( form feed) 32.30 $ printf "%10.3san" Peteleca n Salta para o início da linha se- Peta Pet guinte (line feed) O .2 especificou duas casas decimais. r Volta para o início da linha cor- Agora observe: Imprime a cadeia com 10 caracteres, rente (carriage return) truncada após os três primeiros, conca- t Avança para a próxima marca de tabulação $ printf "%.3fn" `echo "scale=2 ; 100/6" | bc` tenada com o caractere a (após o s). E 33.330 esse comando a seguir, o que faz? 86 junho 2005 edição 09 www.linuxmagazine.com.br
  • 4. Papo de Botequim Linux User $ printf “EXEMPLO %xn” 45232 trabalho, principalmente em instalações (1 minuto). A cada intervalo o Shell fará EXEMPLO b0b0 com estrutura de diretórios em múltiplos a verificação antes de exibir o próximo níveis. Veja o exemplo a seguir: prompt primário ($PS1). Se essa variável Ele transformou o número 45232 para estiver sem valor ou com um valor menor hexadecimal (b0b0), mas os zeros não $ echo $CDPATH ou igual a zero, a busca por novas men- combinam com o resto. Experimente: .:..:~:/usr/local sagens não será efetuada. $ pwd PATH » Caminhos que serão pesquisa- $ printf “EXEMPLO %Xn” 45232 /home/jneves/LM dos para tentar localizar um arquivo espe- EXEMPLO B0B0 $ cd bin cificado. Como cada script é um arquivo, $ pwd caso use o diretório corrente (.) na sua Assim disfarçou melhor! (repare no X /usr/local/bin variável $PATH, você não necessitará usar maiúsculo). Pra terminar, que tal o co- o comando ./scrp para que o script scrp mando abaixo: Como /usr/local estava na minha seja executado. Basta digitar scrp. Este variável $CDPATH e não existia o diretório é o modo que prefiro. $ printf “%X %XL%Xn” 49354 192 10 bin em nenhum dos seus antecessores (., PIPESTATUS » É uma variável do tipo C0CA C0LA .. e ~), o comando cd foi executado tendo vetor (array) que contém uma lista de como destino /usr/local/bin. valores de códigos de retorno do último Este aí não é marketing e é bastante HISTSIZE » Limita o número de ins- pipeline executado, isto é, um array que completo, veja só como funciona: truções que cabem dentro do arquivo de abriga cada um dos $? de cada instrução O primeiro %X converteu 49354 em he- histórico de comandos (normalmente do último pipeline. Para entender melhor, xadecimal, resultando em C0CA (leia-se .bash_history, mas na verdade é o que veja o exemplo a seguir: “cê”, “zero”, “cê” e “a”). Em seguida veio está indicado na variável $HISTFILE). Seu um espaço em branco seguido por outro valor padrão é 500. $ who %XL. O %X converteu o 192 dando como HOSTNAME » O nome do host corrente jneves pts/0 Apr 11 16:26 (10.2.4.144) resultado C0 que com o L fez C0L. E final- (que também pode ser obtido com o co- jneves pts/1 Apr 12 12:04 (10.2.4.144) mente o último parâmetro %X transformou mando uname -n). $ who | grep ^botelho o número 10 na letra A. LANG » Usada para determinar o idioma $ echo ${PIPESTATUS[*]} Conforme vocês podem notar, a instru- falado no país (mais especificamente ca- 0 1 ção é bastante completa e complexa. Ain- tegoria do locale). Veja um exemplo: da bem que o echo resolve quase tudo... Neste exemplo mostramos que o usu- Acertei em cheio quando resolvi expli- $ date ário botelho não estava “logado”, em car o printf através de exemplos, pois Thu Apr 14 11:54:13 BRT 2005 seguida executamos um pipeline que não saberia como enumerar tantas regri- $ LANG=pt_BR date procurava por ele. Usa-se a notação [*] nhas sem tornar a leitura enfadonha. Qui Abr 14 11:55:14 BRT 2005 em um array para listar todos os seus elementos; dessa forma, vimos que a pri- Principais variáveis do Shell LINENO » O número da linha do script meira instrução (who) foi bem-sucedida O Bash possui diversas variáveis que ou função que está sendo executada. (código de retorno 0) e a seguinte (grep) servem para dar informações sobre Seu uso principal é mostrar mensagens não (código de retorno 1). o ambiente ou alterá-lo. São muitas e de erro juntamente com as variáveis $0 PROMPT_COMMAND » Se esta variável re- não pretendo mostrar todas elas, mas (nome do programa) e $FUNCNAME (nome ceber o nome de um comando, toda vez uma pequena parte pode lhe ajudar na da função em execução). que você teclar um [ENTER] sozinho no elaboração de scripts. Veja a seguir as LOGNAME » Esta variável armazena o prompt principal ($PS1), esse comando principais delas: nome de login do usuário . será executado. É muito útil quando você CDPATH » Contém os caminhos que MAILCHECK » Especifica, em segundos, a precisa repetindo constantemente uma serão pesquisados para tentar localizar freqüência com que o Shell verifica a pre- determinada instrução. um diretório especificado. Apesar dessa sença de correspondência nos arquivos PS1 » É o prompt principal. No “Papo variável ser pouco conhecida, seu uso indicados pela variáveis $MAILPATH ou de Botequim” usamos os padrões $ para deve ser incentivado por poupar muito $MAIL. O tempo padrão é de 60 segundos usuário comum e # para root, mas é mui- junho 2005 edição 09 87 www.linuxmagazine.com.br
  • 5. Linux User Papo de Botequim to freqüente que ele esteja personalizado. Expansão de parâmetros $ cadeia="Papo de Botequim" Uma curiosidade é que existe até concurso Bem, muito do que vimos até agora são $ echo ${cadeia#*' '} de quem programa o $PS1 mais criativo. comandos externos ao Shell. Eles quebram de Botequim PS2 » Também chamado “prompt de o maior galho, facilitam a visualização, $ echo "Conversa "${cadeia#*' '} continuação”, é aquele sinal de maior manutenção e depuração do código, mas Conversa de Botequim (>) que aparece após um [ENTER] sem não são tão eficientes quanto os intrínse- o comando ter sido encerrado. cos (built-ins). Quando o nosso problema No exemplo anterior foi suprimido à PWD » Possui o caminho completo for performance, devemos dar preferência esquerda tudo o que “casa” com a menor ($PATH) do diretório corrente. Tem o ao uso dos intrínsecos. A partir de agora ocorrência da expressão *’ ‘, ou seja, mesmo efeito do comando pwd. vou te mostrar algumas técnicas para o todos os caracteres até o primeiro espaço RANDOM » Cada vez que esta variável é seu programa pisar no acelerador. em branco. Esses exemplos também po- acessada, devolve um inteiro aleatório en- Na tabela 3 e nos exemplos a seguir, deriam ser escritos sem proteger o espaço tre 0 e 32767. Para gerar um inteiro entre veremos uma série de construções cha- da interpretação do Shell (mas prefiro 0 e 100, por exemplo, digitamos: madas expansão (ou substituição) de protegê-lo para facilitar a legibilidade parâmetros (Parameter Expansion), que do código). Veja só: $ echo $((RANDOM%101)) substituem instruções como o cut, o expr, 73 o tr, o sed e outras de forma mais ágil. $ echo ${cadeia#* } Vamos ver alguns exemplos: se em uma de Botequim Ou seja, pegamos o resto da divisão do pergunta o S é oferecido como valor de- $ echo "Conversa "${cadeia#* } número randômico gerado por 101 porque fault (padrão) e a saída vai para a variável Conversa de Botequim o resto da divisão de qualquer número SN, após ler o valor podemos fazer: por 101 varia entre 0 e 100. Repare que na construção de expr é REPLY » Use esta variável para recuperar SN=$(SN:-S} permitido o uso de metacaracteres. o último campo lido, caso ele não tenha Utilizando o mesmo valor da variável nenhuma variável associada. Exemplo: Para saber o tamanho de uma cadeia: cadeia, observe como faríamos para ter somente Botequim : $ read -p "Digite S ou N: " $ cadeia=0123 Digite S ou N: N $ echo ${#cadeia} $ echo ${cadeia##*' '} $ echo $REPLY 4 Botequim N $ echo "Vamos 'Chopear' no "${cadeia##*' '} Para extrair dados de cadeia, da posi- Vamos 'Chopear' no Botequim SECONDS » Esta variável informa, em se- ção um até o final fazemos: gundos, há quanto tempo o Shell corrente Desta vez suprimimos à esquerda de está “de pé”. Use-a para demonstrar a $ cadeia=abcdef cadeia a maior ocorrência da expressão estabilidade do Linux e esnobar usuários $ echo ${cadeia:1} expr. Assim como no caso anterior, o uso daquela coisa com janelinhas coloridas bcdef de metacaracteres é permitido. que chamam de sistema operacional, mas Outro exemplo mais útil: para que não que necessita de “reboots” freqüentes. Repare que a origem é zero e não um. apareça o caminho (path) completo do seu TMOUT » Se esta variável contiver um Vamos extrair 3 caracteres a partir da 2ª programa ($0) em uma mensagem de erro, valor maior do que zero, esse valor posição da mesma variável cadeia: inicie o seu texto da seguinte forma: será considerado o timeout padrão do comando read. No prompt, esse valor $ echo ${cadeia:2:3} echo Uso: ${0##*/} texto da mensagem de erro é interpretado como o tempo de espera cde por uma ação antes de expirar a sessão. Neste exemplo seria suprimido à es- Supondo que a variável contenha o valor Repare que novamente a origem da con- querda tudo até a última barra (/) do 30, o Shell encerrará a sessão do usuário tagem é zero e não um. Para suprimir caminho, restando somente o nome do (ou seja, fará logout) após 30 segundos tudo à esquerda da primeira ocorrência programa. O caractere % é simétrico ao sem nenhuma ação no prompt. de uma cadeia, faça: #, veja o exemplo: 88 junho 2005 edição 09 www.linuxmagazine.com.br
  • 6. Papo de Botequim Linux User Tabela 3: Tipos de expansão de parâmetros Há várias formas de trocar uma subca- deia no início ou no fim de uma variável. Expansão de parâmetros Resultado esperado Para trocar no início fazemos: ${var:-padrao} Se var é vazia, o resultado da expressão é padrão ${#cadeia} Tamanho de $cadeia ${cadeia:posicao} Extrai uma subcadeia de $cadeia a partir de posição. Origem zero $ echo $Passaro ${cadeia:posicao:tamanho} Extrai uma subcadeia de $cadeia a partir de posição com tamanho quero quero igual a tamanho. Origem zero $ echo “Como diz o sulista - “${PassaroU ${cadeia#expr} Corta a menor ocorrência de $cadeia à esquerda da expressão expr /#quero/não} ${cadeia##expr} Corta a maior ocorrência de $cadeia à esquerda da expressão expr Como diz o sulista - não quero ${cadeia%expr} Corta a menor ocorrência de $cadeia à direita da expressão expr ${cadeia%%expr} Corta a maior ocorrência de $cadeia à direita da expressão expr Para trocar no final fazemos: ${cadeia/subcad1/subcad2} Troca a primeira ocorrência de subcad1 por subcad2 ${cadeia//subcad1/subcad2} Troca todas as ocorrências de subcad1 por subcad2 ${cadeia/#subcad1/subcad2} Se subcad1 combina com o início de cadeia, então é trocado por subcad2 $ echo “Como diz o nordestino - U ${cadeia/%subcad1/subcad2} Se subcad1 combina com o fim de cadeia, então é trocado por subcad2 “${Passaro/%quero/não} Como diz o nordestino - quero não $ echo $cadeia $ echo ${cadeia/*po/Conversa} – Agora já chega, o papo hoje foi chato Papo de Botequim Conversa de Botequim porque teve muita decoreba, mas o que $ echo ${cadeia%' '*} $ echo ${cadeia/????/Conversa} mais importa é você ter entendido o Papo de Conversa de Botequim que te falei. Quando precisar, consulte $ echo ${cadeia%%' '*} estes guardanapos onde rabisquei as Papo Trocando todas as ocorrências de uma dicas e depois guarde-os para consultas subcadeia por outra. O comando: futuras. Mas voltando à vaca fria: tá Para trocar primeira ocorrência de uma na hora de tomar outro e ver o jogo do subcadeia em uma cadeia por outra: $ echo ${cadeia//o/a} Mengão. Pra próxima vez vou te dar Papa de Batequim moleza e só vou cobrar o seguinte: pe- $ echo $cadeia gue a rotina pergunta.func (da qual Papo de Botequim Ordena a troca de todos as letras o por falamos no início do nosso bate-papo $ echo ${cadeia/de/no} a. Outro exemplo mais útil é para contar de hoje, veja a listagem 1) e otimize-a Papo no Botequim a quantidade de arquivos existentes no para que a variável $SN receba o valor $ echo ${cadeia/de /} diretório corrente. Observe o exemplo: padrão por expansão de parâmetros, Papo Botequim como vimos. $ ls | wc -l E não se esqueça: em caso de dúvidas Preste atenção quando for usar metaca- 30 ou falta de companhia para um (ou mais) racteres! Eles são gulosos e sempre com- chope é só mandar um e-mail para julio. binarão com a maior possibilidade; No O wc põe um monte de espaços em neves@gmail.com. E diga para os amigos exemplo a seguir eu queria trocar Papo de branco antes do resultado. Para tirá-los: que quem estiver a fim de fazer um curso Botequim por Conversa de Botequim: porreta de programação em Shell deve # QtdArqs recebe a saída do comando mandar um e-mail para julio.neves@tecnohall. $ echo $cadeia $ QtdArqs=$(ls | wc -l) com.br para informar-se. Valeu! ■ Papo de Botequim $ echo ${QtdArqs/ * /} $ echo ${cadeia/*o/Conversa} 30 Julio Cezar Neves é Analista de Suporte de Sobre o autor Conversatequim Sistemas desde 1969 e trabalha com Unix Nesse exemplo, eu sabia que a saída era desde 1980, quando participou do desen- A idéia era pegar tudo até o primeiro composta de brancos e números, por isso volvimento do SOX, um sistema operacio- o, mas acabou sendo trocado tudo até o montei essa expressão para trocar todos os nal similar ao Unix produzido pela Cobra último o. Isto poderia ser resolvido de espaços por nada. Note que antes e após o Computadores. Pode ser contatado no diversas maneiras. Eis algumas: asterisco (*) há espaços em branco. e-mail julio.neves@gmail.com junho 2005 edição 09 89 www.linuxmagazine.com.br