curso de shell script 09/11

Download Curso de Shell Script 09/11

If you can't read please download the document

Upload: jose-rodrigo

Post on 09-Aug-2015

158 views

Category:

Technology


1 download

TRANSCRIPT

  1. 1. Linux User Papo de BotequimPapo de BotequimCurso de Shell Script Parte IX Dave Hamilton - www.sxc.huHoje vamos aprender mais sobre formatao de cadeias de caracteres,conhecer as principais variveis do Shell e nos aventurar no (ainda)desconhecido territrio da expanso de parmetros. E d-lhe chope!por Jlio Cezar Neves T bom, j sei que voc vai querer chope antes de comear,Bom, a resposta "mais ou menos". Com estes comandos mas t to a m de te mostrar o que z que j vou pedir avoc escreve 90% do que precisa, porm se precisar escrever rodada enquanto isso. A Chico, manda dois! O dele sem algo formatado eles lhe daro muito trabalho. Para formatar a colarinho pra no deixar cheiro ruim nesse bigodosada veremos agora uma instruo muito mais interessante,Enquanto o chope no chega, deixa eu te lembrar o que a printf. Sua sintaxe a seguinte: voc me pediu na edio passada: era para refazer o programa listartista com a tela formatada e exe- Listagem 1: mandamsg.func e pergunta.func cuo em loop, de forma que ele s termine quandomandamsg.func receber um [ENTER] sozinho como nome do artista. 01 # A funo recebe somente um parmetro Eventuais mensagens de erro e perguntas feitas ao02 # com a mensagem que se deseja exibir. usurio deveriam ser mostradas na antepenltima03 # Para no obrigar o programador a passar linha da tela, utilizando para isso as rotinas externas04 # a msg entre aspas, usaremos $* (todos mandamsg.func e pergunta.func que desenvolvemos05 # os parmetro, lembra?) e no $1.06 Msg="$*" durante nosso papo na edio passada.07 TamMsg=${#Msg}Primeiramente eu dei uma encolhida nas rotinas08 Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha mandamsg.func e pergunta.func, que caram como 09 tput cup $LinhaMesg $Col na listagem 1. E na listagem 2 voc tem o grando, 10 read -n1 -p "$Msg " nossa verso refeita do listaartista. Puxa, voc chegou com a corda toda! Gostei dapergunta.func forma como voc resolveu o problema e estruturou 01 # A funo recebe 3 parmetros 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 padro o cou muito legal e voc explorou bastante as04 # $3 - O outro valor aceito opes do comando tput. Vamos testar o resultado05 # 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 escrita09 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 " SN12 [ ! $SN ] && SN=$2# Se vazia coloca default em SN J sei que voc vai me perguntar: Ora, no com o13 SN=$(echo $SN | tr A-Z a-z) # A sada de SN ser em minscula comando echo e com os redirecionamentos de sada14 tput cup $LinhaMesg $Col; tput el # Apaga msg da tela que se escreve dados?.84junho 2005 edio 09www.linuxmagazine.com.br
  2. 2. Papo de Botequim Linux User Listagem 2: listaartistaprintf formato [argumento...] $ cat listartista3.sh01 #!/bin/bashOnde formato uma cadeia 02 # Dado um artista, mostra as suas musicas03 # versao 3de caracteres que contm trs04 LinhaMesg=$((`tput lines` - 3)) # Linha onde as msgs sero mostradastipos de objeto: caracteres 05 TotCols=$(tput cols)# Qtd de colunas na tela para enquadrar msgssimples, caracteres para es-06 clearpecicao de formato (ou de07 echo "+-----------------------------------+controle) e seqncia de esca-| Lista Todas as Msicas de um Determinado Artista |pe no padro da linguagem | ===== ===== == ======= == == =========== ======= |C. argumento a cadeia de||caracteres a ser impressa sob | Informe o Artista: |+-----------------------------------+"o controle de formato.08 while trueCada um dos caracteres uti- 09 dolizados precedido pelo ca-10 tput cup 5 51; tput ech 31 # ech=Erase chars (31 para no apagar barra vertical)racter % e, logo a seguir, vem11 read Nomea especicao de formato de12 if [ ! "$Nome" ] # $Nome esta vazio?13 thenacordo com a tabela 1.14. pergunta.func "Deseja Sair?" s nAs seqncias de escape 15[ $SN = n ] && continuepadro da linguagem C so 16breaksempre precedidas pelo ca-17 fi18 fgrep -iq "^$Nome~" musicas || # fgrep no interpreta ^ como expresso regularractere contra-barra (). As19{reconhecidas pelo comando 20. mandamsg.func "No existe msica desse artista"printf so as da tabela 2.21continue No acaba por a no! Tem22}23 tput cup 7 29; echo | |muito mais coisa sobre essa24 LinAtual=8instruo, 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 album28 dopara explicar e pior ainda para29if echo "$ArtMus" | grep -iq "^$Nome~"ler ou estudar, vamos passar30thendireto aos exemplos com co- 31 tput cup $LinAtual 29mentrios. 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 then39 . mandamsg.func "Tecle Algo para Continuar..."e no saltou linha ao nal40 tput cup 7 0; tput ed # Apaga a tela a partir da linha 741 tput cup 7 29; echo ||$ printf "%cn" "1 caracter"42 LinAtual=81 43fi44fi45 done Saltou linha mas ainda no 46 tput cup $LinAtual 29; echo | |listou a cadeia inteira 47 tput cup $((++LinAtual)) 2948 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" 150 done1 caractere junho 2005 edio 09 85 www.linuxmagazine.com.br
  3. 3. Linux User Papo de Botequim Tabela 1: Formatos de caractere(%) signica o tamanho que a cadeia terO bc devolveu duas casas decimais eaps a execuo do comando. Vamos ver o printf colocou o zero direita. O co-Caractere A expresso ser impressa como:c Caractere simples a seguir mais alguns exemplos. Os co- mando a seguir:d Nmero no sistema decimal mandos abaixo:e Notao cientca exponencial $ printf "%on" 10f Nmero com ponto decimal (oat) $ printf "%dn" 3212g O menor entre os formatos %e e %f com 32omisso dos zeros no signicativos $ printf "%10dn" 32Converteu o valor 10 para base octal.o Nmero no sistema octal32 Para melhorar experimente:s Cadeia de caracteresx Nmero no sistema hexadecimalpreenchem a string com espaos em $ printf "%03on" 27% Imprime um %. No h nenhumtipo de converso branco esquerda (oito espaos mais dois 033caracteres, 10 dgitos), no com zeros. Jno comando abaixo:Assim a converso ca com mais jeito Opa, essa a forma correta! O %c rece-de octal, n?. O que este aqui faz? beu o valor 1, como queramos: $ printf "%04dn" 320032$ printf "%sn" Peteleca $ a=2Peteleca $ printf "%c caracteresn" $aO 04 aps % signica formate a string$ printf "%15sn" Peteleca 2 caracteres em quatro dgitos, com zeros esquerdaPetelecase necessrio. No comando: O %c recebeu o valor da varivel $a. Imprime Peteleca com 15 caracteres.$ printf "%en" $(echo "scale=2 ; 100/6" | bc)A cadeia de caracteres preenchida com $ printf "%10c caracteresn" $a1.666000e+01espaos em branco esquerda. J no co-2 caracteresmando: $ printf "%10cn" $a caracteresO padro do %e seis casas decimais.2 J no comando:$ printf "%-15sNevesn" Petelecac PetelecaNeves$ printf "%.2en" `echo "scale=2 ; 100/6" | bc`Repare que, nos dois ltimos exemplos,1.67e+01O menos (-) colocou espaos 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 especicou duas casas decimais. caracteres pedidos. E o comando abaixo, passada como parmetro. O valor 10 Observe agora:o que faz? frente do c no signica 10 caracteres. Um nmero seguindo o sinal de percentagem $ printf "%fn" 32.3$ printf "%.3sn" Peteleca32.300000 Pet Tabela 2: Seqncias de escapeO padro do %f seis casas decimais. O .3 manda truncar a cadeia de ca- SeqnciaEfeitoE no comando: racteres aps as trs primeiras letras. E aSoa o beep bVolta uma posio (backspace) o comando a seguir: fSalta para a prxima pgina $ printf "%.2fn" 32.3lgica ( form feed) 32.30 $ printf "%10.3san" Peteleca nSalta para o incio da linha se- Peta Petguinte (line feed)O .2 especicou duas casas decimais. rVolta para o incio da linha cor-Agora observe:Imprime a cadeia com 10 caracteres,rente (carriage return)truncada aps os trs primeiros, conca- tAvana para a prxima marca detabulao $ printf "%.3fn" `echo "scale=2 ; 100/6" | bc` tenada com o caractere a (aps o s). E33.330esse comando a seguir, o que faz?86junho 2005edio 09www.linuxmagazine.com.br
  4. 4. Papo de Botequim Linux User $ printf EXEMPLO %xn 45232trabalho, principalmente em instalaes(1 minuto). A cada intervalo o Shell far EXEMPLO b0b0 com estrutura de diretrios em mltiplos a vericao antes de exibir o prximonveis. Veja o exemplo a seguir: prompt primrio ($PS1). Se essa varivelEle transformou o nmero 45232 paraestiver sem valor ou com um valor menorhexadecimal (b0b0), mas os zeros no$ echo $CDPATH ou igual a zero, a busca por novas men-combinam com o resto. Experimente: .:..:~:/usr/local sagens no ser efetuada.$ pwdPATH Caminhos que sero pesquisa- $ printf EXEMPLO %Xn 45232/home/jneves/LMdos para tentar localizar um arquivo espe- EXEMPLO B0B0 $ cd bin cicado. Como cada script um arquivo,$ pwdcaso use o diretrio corrente (.) na sua Assim disfarou melhor! (repare no X /usr/local/bin varivel $PATH, voc no necessitar usarmaisculo). Pra terminar, que tal o co-o comando ./scrp para que o script scrpmando abaixo: Como /usr/local estava na minhaseja executado. Basta digitar scrp. Estevarivel $CDPATH e no existia o diretrio o modo que prero. $ printf %X %XL%Xn 49354 192 10 bin em nenhum dos seus antecessores (.,PIPESTATUS uma varivel do tipo C0CA C0LA .. e ~), o comando cd foi executado tendo vetor (array) que contm uma lista decomo destino /usr/local/bin. valores de cdigos de retorno do ltimo Este a no marketing e bastante HISTSIZE Limita o nmero de ins- pipeline executado, isto , um array que completo, veja s como funciona: trues que cabem dentro do arquivo de abriga cada um dos $? de cada instruo O primeiro %X converteu 49354 em he- histrico 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 veioest indicado na varivel $HISTFILE). Seu um espao em branco seguido por outrovalor padro 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 nal-(que tambm pode ser obtido com o co-jneves pts/1 Apr 12 12:04 (10.2.4.144) mente o ltimo parmetro %X transformoumando uname -n). $ who | grep ^botelho o nmero 10 na letra A.LANG Usada para determinar o idioma$ echo ${PIPESTATUS[*]} Conforme vocs podem notar, a instru-falado no pas (mais especicamente 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 no estava logado, em car o printf atravs de exemplos, pois Thu Apr 14 11:54:13 BRT 2005 seguida executamos um pipeline que no saberia como enumerar tantas regri-$ LANG=pt_BR dateprocurava por ele. Usa-se a notao [*] 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 variveis do Shell LINENO O nmero da linha do scriptmeira instruo (who) foi bem-sucedidaO Bash possui diversas variveis que ou funo que est sendo executada. (cdigo de retorno 0) e a seguinte (grep)servem para dar informaes sobreSeu uso principal mostrar mensagens no (cdigo de retorno 1).o ambiente ou alter-lo. So muitas ede erro juntamente com as variveis $0PROMPT_COMMAND Se esta varivel re-no pretendo mostrar todas elas, mas (nome do programa) e $FUNCNAME (nomeceber o nome de um comando, toda vezuma pequena parte pode lhe ajudar na da funo em execuo). que voc teclar um [ENTER] sozinho noelaborao de scripts. Veja a seguir asLOGNAME Esta varivel armazena oprompt principal ($PS1), esse comandoprincipais delas:nome de login do usurio .ser executado. muito til quando vocCDPATH Contm os caminhos que MAILCHECK Especica, em segundos, aprecisa repetindo constantemente umasero pesquisados para tentar localizarfreqncia com que o Shell verica a pre- determinada instruo.um diretrio especicado. Apesar dessa sena de correspondncia nos arquivos PS1 o prompt principal. No Papovarivel ser pouco conhecida, seu usoindicados pela variveis $MAILPATH ou de Botequim usamos os padres $ paradeve ser incentivado por poupar muito$MAIL. O tempo padro de 60 segundosusurio comum e # para root, mas mui- junho 2005 edio 09 87www.linuxmagazine.com.br
  5. 5. Linux User Papo de Botequim to freqente que ele esteja personalizado.Expanso de parmetros $ cadeia="Papo de Botequim" Uma curiosidade que existe at concurso Bem, muito do que vimos at agora so$ echo ${cadeia#* } de quem programa o $PS1 mais criativo.comandos externos ao Shell. Eles quebram de Botequim PS2 Tambm chamado prompt de o maior galho, facilitam a visualizao, $ echo "Conversa "${cadeia#* } continuao, aquele sinal de maior manuteno e depurao do cdigo, masConversa de Botequim (>) que aparece aps um [ENTER] sem no so to ecientes quanto os intrnse- 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 preferncia esquerda tudo o que casa com a menor ($PATH) do diretrio corrente. Tem oao uso dos intrnsecos. A partir de agoraocorrncia da expresso * , ou seja, mesmo efeito do comando pwd.vou te mostrar algumas tcnicas para o todos os caracteres at o primeiro espao RANDOM Cada vez que esta varivel seu programa pisar no acelerador.em branco. Esses exemplos tambm po- acessada, devolve um inteiro aleatrio en-Na tabela 3 e nos exemplos a seguir, deriam ser escritos sem proteger o espao tre 0 e 32767. Para gerar um inteiro entreveremos uma srie de construes cha-da interpretao do Shell (mas prero 0 e 100, por exemplo, digitamos:madas expanso (ou substituio) deproteg-lo para facilitar a legibilidade parmetros (Parameter Expansion), quedo cdigo). Veja s: $ echo $((RANDOM%101))substituem instrues como o cut, o expr, 73o 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 diviso dopergunta o S oferecido como valor de-$ echo "Conversa "${cadeia#* } nmero randmico gerado por 101 porquefault (padro) e a sada vai para a varivel Conversa de Botequim o resto da diviso de qualquer nmero SN, aps ler o valor podemos fazer: por 101 varia entre 0 e 100. Repare que na construo de expr REPLY Use esta varivel para recuperarSN=$(SN:-S}permitido o uso de metacaracteres. o ltimo campo lido, caso ele no tenhaUtilizando o mesmo valor da varivel nenhuma varivel associada. Exemplo:Para saber o tamanho de uma cadeia:cadeia, observe como faramos para tersomente Botequim : $ read -p "Digite S ou N: " $ cadeia=0123 Digite S ou N: N$ echo ${#cadeia}$ echo ${cadeia##* } $ echo $REPLY 4Botequim N$ echo "Vamos Chopear no "${cadeia##* } Para extrair dados de cadeia, da posi- Vamos Chopear no Botequim SECONDS Esta varivel informa, em se- o um at o nal fazemos: gundos, h quanto tempo o Shell corrente Desta vez suprimimos esquerda de est de p. Use-a para demonstrar a $ cadeia=abcdefcadeia a maior ocorrncia da expresso estabilidade do Linux e esnobar usurios$ echo ${cadeia:1} expr. Assim como no caso anterior, o uso daquela coisa com janelinhas coloridasbcdefde metacaracteres permitido. que chamam de sistema operacional, mas Outro exemplo mais til: para que no que necessita de reboots freqentes.Repare que a origem zero e no um. aparea o caminho (path) completo do seu TMOUT Se esta varivel contiver umVamos extrair 3 caracteres a partir da 2programa ($0) em uma mensagem de erro, valor maior do que zero, esse valor posio da mesma varivel cadeia:inicie o seu texto da seguinte forma: ser considerado o timeout padro 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 ao antes de expirar a sesso.Neste exemplo seria suprimido es- Supondo que a varivel contenha o valor Repare que novamente a origem da con-querda tudo at a ltima barra (/) do 30, o Shell encerrar a sesso do usurio tagem zero e no um. Para suprimir caminho, restando somente o nome do (ou seja, far logout) aps 30 segundos tudo esquerda da primeira ocorrncia programa. O caractere % simtrico ao sem nenhuma ao no prompt. de uma cadeia, faa: #, veja o exemplo:88junho 2005edio 09 www.linuxmagazine.com.br
  6. 6. Papo de BotequimLinux UserTabela 3: Tipos de expanso de parmetrosH vrias formas de trocar uma subca- deia no incio ou no m de uma varivel. Expanso de parmetros Resultado esperado Para trocar no incio fazemos:${var:-padrao} Se var vazia, o resultado da expresso padro${#cadeia} Tamanho de $cadeia${cadeia:posicao}Extrai uma subcadeia de $cadeia a partir de posio. Origem zero$ echo $Passaro${cadeia:posicao:tamanho}Extrai uma subcadeia de $cadeia a partir de posio com tamanho quero quero igual a tamanho. Origem zero$ echo Como diz o sulista - ${PassaroU${cadeia#expr} Corta a menor ocorrncia de $cadeia esquerda da expresso expr /#quero/no}${cadeia##expr}Corta a maior ocorrncia de $cadeia esquerda da expresso exprComo diz o sulista - no quero${cadeia%expr} Corta a menor ocorrncia de $cadeia direita da expresso expr${cadeia%%expr}Corta a maior ocorrncia de $cadeia direita da expresso expr Para trocar no nal fazemos:${cadeia/subcad1/subcad2} Troca a primeira ocorrncia de subcad1 por subcad2${cadeia//subcad1/subcad2} Troca todas as ocorrncias de subcad1 por subcad2${cadeia/#subcad1/subcad2} Se subcad1 combina com o incio de cadeia, ento trocado por subcad2$ echo Como diz o nordestino - U${cadeia/%subcad1/subcad2} Se subcad1 combina com o m de cadeia, ento trocado por subcad2${Passaro/%quero/no} Como diz o nordestino - quero no$ echo $cadeia $ echo ${cadeia/*po/Conversa} Agora j chega, o papo hoje foi chatoPapo de Botequim Conversa de Botequim porque teve muita decoreba, mas o que$ echo ${cadeia% *}$ echo ${cadeia/????/Conversa} mais importa voc ter entendido oPapo deConversa de Botequim que te falei. Quando precisar, consulte$ echo ${cadeia%% *}estes guardanapos onde rabisquei asPapoTrocando todas as ocorrncias de umadicas e depois guarde-os para consultassubcadeia por outra. O comando: futuras. Mas voltando vaca fria: tPara trocar primeira ocorrncia de umana hora de tomar outro e ver o jogo dosubcadeia em uma cadeia por outra: $ echo ${cadeia//o/a}Mengo. Pra prxima vez vou te dar Papa de Batequim moleza e s vou cobrar o seguinte: pe-$ echo $cadeiague a rotina pergunta.func (da qualPapo de Botequim Ordena a troca de todos as letras o porfalamos no incio do nosso bate-papo$ echo ${cadeia/de/no}a. Outro exemplo mais til para contarde hoje, veja a listagem 1) e otimize-aPapo no Botequima quantidade de arquivos existentes nopara que a varivel $SN receba o valor$ echo ${cadeia/de /} diretrio corrente. Observe o exemplo:padro por expanso de parmetros,Papo Botequim como vimos. $ ls | wc -lE no se esquea: em caso de dvidasPreste ateno quando for usar metaca- 30ou falta de companhia para um (ou mais)racteres! Eles so gulosos e sempre com- chope s mandar um e-mail para julio.binaro com a maior possibilidade; No O wc pe um monte de espaos [email protected]. E diga para os amigosexemplo a seguir eu queria trocar Papo de branco antes do resultado. Para tir-los:que quem estiver a m de fazer um cursoBotequim por Conversa de Botequim: porreta de programao em Shell deve # QtdArqs recebe a sada 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 deSobre o autorConversatequimSistemas desde 1969 e trabalha com UnixNesse exemplo, eu sabia que a sada era desde 1980, quando participou do desen-A idia era pegar tudo at o primeiro composta de brancos e nmeros, por isso volvimento do SOX, um sistema operacio-o, mas acabou sendo trocado tudo at omontei essa expresso para trocar todos osnal similar ao Unix produzido pela Cobraltimo o. Isto poderia ser resolvido de espaos por nada. Note que antes e aps o Computadores. Pode ser contatado nodiversas maneiras. Eis algumas: asterisco (*) h espaos em branco. e-mail [email protected] junho 2005edio 09 89 www.linuxmagazine.com.br