Programação Shell LinuxAqui temos um livro livre e completo sobre ShellOs sedentos do "saber livre" são muito benvindos. |
Comandos Shell Script |
![]() |
|
Home |
Artigos ![]() ![]() |
Comprar o livroChangelogs |
|
Papo de Botequim - Parte IX- Tá bom, já sei que você vai querer chope antes de começar, mas tô tão afim de te mostrar o que fiz que já vou até pedindo a rodada e em seguida vou te mostrar. - Aê Chico, manda dois. O dele é sem colarinho pra não deixar cheiro ruim neste bigodão... - Enquanto o chope não chega deixa eu te relembrar que você me pediu para refazer o - Primeiramente eu dei uma encolhida no $ cat mandamsg.func
# A função recebe somente um parâmetro
# com a mensagem que se deseja exibir,
# para não obrigar ao programador passar
# a msg entre aspas, usaremos $* (todos
# os parâmetro, lembra?) e não $1.
Msg="$*"
TamMsg=${#Msg}
Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha
tput cup $LinhaMesg $Col
read -n1 -p "$Msg "
$ cat pergunta.func
# A função recebe 3 parâmetros na seguinte ordem:
# $1 - Mensagem a ser dada na tela
# $2 - Valor a ser aceito com resposta default
# $3 - O outro valor aceito
# Supondo que $1=Aceita?, $2=s e $3=n, a linha
# abaixo colocaria em Msg o valor "Aceita? (S/n)"
Msg="$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)"
TamMsg=${#Msg}
Col=$(((TotCols - TamMsg) / 2)) # Centra msg na linha
tput cup $LinhaMesg $Col
read -n1 -p "$Msg " SN
[ ! $SN ] && SN=$2 # Se vazia coloca default em SN
SN=$(echo $SN | tr A-Z a-z) # A saída de SN será em minúscula
tput cup $LinhaMesg $Col; tput el # Apaga msg da tela
- E agora aí vai o grandão: $ cat listartista3
#!/bin/bash
# Dado um artista, mostra as suas musicas
# versao 3
LinhaMesg=$((`tput lines` - 3)) # Linha que msgs serão dadas para operador TotCols=$(tput cols) # Qtd colunas da tela para enquadrar msgs clear echo " +----------------------------------------------------+ | Lista Todas as Músicas de um Determinado Artista | | ----- ----- -- ------- -- -- ----------- ------- | | | | Informe o Artista: | +----------------------------------------------------+" while true do tput cup 5 51; tput ech 31 # ech=Erase chars (31 caracteres para não apagar barra vertical) read Nome if [ ! "$Nome" ] # $Nome estah vazio? then . pergunta.func "Deseja Sair?" s n [ $SN = n ] && continue break fi fgrep -iq "^$Nome~" musicas || # fgrep não interpreta ^ como expressão regular { . mandamsg.func "Não existe música deste artista" continue } tput cup 7 29; echo '| |' LinAtual=8 IFS=" :" for ArtMus in $(cut -f2 -d^ musicas) # Exclui nome do album do if echo "$ArtMus" | grep -iq "^$Nome~" then tput cup $LinAtual 29 echo -n '| ' echo $ArtMus | cut -f2 -d~ tput cup $LinAtual 82 echo '|' let LinAtual++ if [ $LinAtual -eq $LinhaMesg ] then . mandamsg.func "Tecle Algo para Continuar..." tput cup 7 0; tput ed # Apaga a tela a partir da linha 7 tput cup 7 29; echo '| |' LinAtual=8 fi fi done tput cup $LinAtual 29; echo '| |' tput cup $((++LinAtual)) 29 read -n1 -p "+-----------Tecle Algo para Nova Consulta------------+" tput cup 7 0; tput ed # Apaga a tela a partir da linha 7 done - Poxa, você chegou com a corda toda! Mas gostei da forma que você resolveu o problema e estruturou o programa. Foi mais trabalhoso mas a apresentação ficou legal e você explorou bastante as opções do +----------------------------------------------------+ | Lista Todas as Músicas de um Determinado Artista | | ----- ----- -- ------- -- -- ----------- ------- | | | | Informe o Artista: Emerson, Lake & Palmer | +----------------------------------------------------+ | | | Jerusalem | | Toccata | | Still ... You Turn Me On | | Benny The Bouncer | | Karn Evil 9 | | | +-----------Tecle Algo para Nova Consulta------------+ Envenenando a escrita- Ufa! Agora você já sabe tudo sobre leitura, mas sobre escrita está apenas engatinhando. Já sei que você vai me perguntar: - Ora, não é com o comando
É, com estes comandos você escreve 90% das coisas necessárias, porém se precisar de escrever algo formatado eles lhe darão muito trabalho. Para formatar a saída veremos agora uma instrução muito interessante - é o printf formato [argumento...]
Onde:
Argumento - é a cadeia a ser impressa sob o controle do formato .
Cada um dos caracteres utilizados para especificação de
As seqüências de escape padrão da linguagem C são sempre precedidas por um contra-barra (
Não acabou por aí não! Tem muito mais coisa sobre a instrução, mas como é muito cheio de detalhes e, portanto, chato para explicar e, pior ainda para ler ou estudar, vamos passar direto aos exemplos com seus comentários, que não estou aqui para encher o saco de ninguém. $ printf "%c" "1 caracter"
1$ Errado! Só listou 1 caractere e não saltou linha ao final
$ printf "%c\n" "1 caracter"
1 Saltou linha mas ainda não listou a cadeia inteira
$ printf "%c caractere\n" 1
1 caractere Esta é a forma correta o %c recebeu o 1
$ a=2
$ printf "%c caracteres\n" $a
2 caracteres O %c recebeu o valor da variável $a
$ printf "%10c caracteres\n" $a
2 caracteres
$ printf "%10c\n" $a caracteres
2
c
Repare que nos dois últimos exemplos, em virtude do E tome de exemplo:
$ printf "%d\n" 32
32
$ printf "%10d\n" 32
32 Preenche com brancos à esquerda e não com zeros
$ printf "%04d\n" 32
0032 04 após % significa 4 dígitos com zeros à esquerda
$ printf "%e\n" $(echo "scale=2 ; 100/6" | bc)
1.666000e+01 O default do %e é 6 decimais
$ printf "%.2e\n" `echo "scale=2 ; 100/6" | bc`
1.67e+01 O .2 especificou duas decimais
$ printf "%f\n" 32.3
32.300000 O default do %f é 6 decimais
$ printf "%.2f\n" 32.3
32.30 O .2 especificou duas decimais
$ printf "%.3f\n" `echo "scale=2 ; 100/6" | bc`
33.330 O bc devolveu 2 decimais. o printf colocou 0 à direita
$ printf "%o\n" 10
12 Converteu o 10 para octal
$ printf "%03o\n" 27
033 Assim a conversão fica com mais jeito de octal, né?
$ printf "%s\n" Peteleca
Peteleca
$ printf "%15s\n" Peteleca
Peteleca Peteleca com 15 caracteres enchidos com brancos
$ printf "%-15sNeves\n" Peteleca
Peteleca Neves O menos (-) encheu à direita com brancos
$ printf "%.3s\n" Peteleca
Pet 3 trunca as 3 primeiras
$ printf "%10.3sa\n" Peteleca
Peta Pet com 10 caracteres concatenado com a (após o s)
$ printf "EXEMPLO %x\n" 45232
EXEMPLO b0b0 Transformou para hexa mas os zeros não combinam
$ printf "EXEMPLO %X\n" 45232
EXEMPLO B0B0 Assim disfarçou melhor (repare o X maiúsculo)
$ printf "%X %XL%X\n" 49354 192 10
C0CA C0LA
O último exemplo não é marketing e é bastante completo, vou comentá-lo passo-a-passo:
Conforme vocês podem notar, a instrução
Creio que quando resolvi explicar o Principais Variáveis do ShellO Bash possui diversas variáveis que servem para dar informações sobre o ambiente ou alterá-lo. Seu número é muito grande e não pretendo mostrar todas, mas uma pequena parte que pode lhe ajudar na elaboração de scripts. Então aí vão as principais:
$ echo $CDPATH
.:..:~:/usr/local
$ pwd
/home/jneves/LM
$ cd bin
$ pwd
/usr/local/bin
Como /usr/local estava na minha variável
$ date
Thu Apr 14 11:54:13 BRT 2005
$ LANG=pt_BR date
Qui Abr 14 11:55:14 BRT 2005
Com a especificação da variável
$ who
jneves pts/0 Apr 11 16:26 (10.2.4.144)
jneves pts/1 Apr 12 12:04 (10.2.4.144)
$ who | grep ^botelho
$ echo ${PIPESTATUS[*]}
0 1
Neste exemplo mostramos que o usuário
Para gerar randomicamente um inteiro entre 0 e 100, fazemos: $ echo $((RANDOM%101))
73
Ou seja pegamos o resto da divisão por
$ read -p "Digite S ou N: "
Digite S ou N: N
$ echo $REPLY
N
Eu sou do tempo que memória era um bem precioso que custava muuuuito caro. Então para pegar um Expansão de parâmetrosBem, muito do que vimos até agora são comandos externos ao Shell. Eles quebram o maior galho, facilitam a visualização, manutenção e depuração do código, mas não são tão eficientes quanto os intrínsecos (built-ins). Quando o nosso problema for performance, devemos dar preferência ao uso dos intrínsecos e a partir de agora vou te mostrar algumas técnicas para o teu programa pisar no acelerador.
Na tabela e exemplos a seguir, veremos uma série de construções chamadas expansão (ou substituição) de parâmetros (Parameter Expansion), que substituem instruções como o
SN=$(SN:-S}
Desta forma se o operador deu um simples
$ cadeia=0123
$ echo ${#cadeia}
4
$ cadeia=abcdef
$ echo ${cadeia:1}
bcdef
Repare que a origem é zero e não um.
$ echo ${cadeia:2:3}
cde
Repare que novamente que a origem da contagem é zero e não um.
$ cadeia="Papo de Botequim"
$ echo ${cadeia#*' '}
de Botequim
$ echo "Conversa "${cadeia#*' '}
Conversa de Botequim
Neste exemplo foi suprimido à esquerda tudo que casasse com a menor ocorrência da expressão Estes exemplos também poderiam ser escritos sem protegermos o espaço da interpretação do Shell (mas prefiro protegê-lo para facilitar a legibilidade do código), veja: $ echo ${cadeia#* }
de Botequim
$ echo "Conversa "${cadeia#* }
Conversa de Botequim
Repare que na construção de
$ echo ${cadeia##*' '}
Botequim
$ echo "Vamos 'Chopear' no "${cadeia##*' '}
Vamos 'Chopear' no Botequim
Desta vez suprimimos à esquerda de cadeia a maior ocorrência da expressão
Outro exemplo mais útil: para que não apareça o caminho (path) completo do seu programa (que, como já sabemos está contido na variável echo Uso: ${0##*/} texto da mensagem de erro
Neste exemplo seria suprimido à esquerda tudo até a última barra (
$ echo $cadeia
Papo de Botequim
$ echo ${cadeia%' '*}
Papo de
$ echo ${cadeia%%' '*}
Papo
$ echo $cadeia
Papo de Botequim
$ echo ${cadeia/de/no}
Papo no Botequim
$ echo ${cadeia/de /}
Papo Botequim
Neste caso preste a atenção quando for usar metacaracteres, eles são gulosos! Eles sempre combinarão com a maior possibilidade, veja o exemplo a seguir onde a intenção era trocar $ echo $cadeia
Papo de Botequim
$ echo ${cadeia/*o/Conversa}
Conversatequim
A idéia era pegar tudo até o primeiro
$ echo ${cadeia/*po/Conversa}
Conversa de Botequim
$ echo ${cadeia/????/Conversa}
Conversa de Botequim
$ echo ${cadeia//o/a}
Papa de Batequim
Trocamos todos as letras $ ls | wc -l
30
Viu? O $ QtdArqs=$(ls | wc -l) # QtdArqs recebe a saída do comando
$ echo ${QtdArqs// /}
30
No último exemplo, como eu sabia que a saída era composta de brancos e números, montei esta expressão para trocar todos os espaços por nada. Repare que após as duas primeiras barras existe um espaço em branco. Outra forma de fazer a mesma coisa seria: $ echo ${QtdArqs/* /}
30
$ echo $Passaro
quero quero
$ echo "Como diz o sulista - "${Passaro/#quero/não}
Como diz o sulista - não quero
Para trocar no final fazemos: $ echo "Como diz o nordestino - "${Passaro/%quero/não}
Como diz o nordestino - quero não
- Agora já chega, o papo hoje foi muito chato porque foi muita decoreba, mas o principal é você ter entendido o que te falei e, quando precisar, consulte estes guardanapos em que rabisquei estas dicas e depois guarde-os para consultas futuras. Mas voltando à vaca fria: tá na hora de tomar outro e ver o jogo do mengão. Na próxima vou te dar moleza e só vou cobrar o seguinte: pegue a rotina - Chico, vê se não esquece de mim e enche meu copo. Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se. Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim. Valeu! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Licença Creative Commons - Atribuição e Não Comercial (CC) 2009 Pelos Frequentadores do Bar do Júlio Neves. Todo o conteúdo desta página pode ser utilizado segundo os termos da Creative Commons License: Atribuição-UsoNãoComercial-PermanênciaDaLicença. |