Curso de Shell Script 04/11

248 visualizações

Publicada em

O garçon já perdeu a conta das cervejas, e o assunto não acaba. Desta vez vamos aprender a testar os mais variados tipos de condições, para podermos controlar a execução de nosso programa de acordo com a entrada fornecida pelo usuário.

0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
248
No SlideShare
0
A partir de incorporações
0
Número de incorporações
1
Ações
Compartilhamentos
0
Downloads
8
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Curso de Shell Script 04/11

  1. 1. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� LINUX USER Papo de Botequim Curso de Shell Script Papo de botequim IV O garçon já perdeu a conta das cervejas, e o assunto não acaba. Desta Dave Hamilton - www.sxc.hu vez vamos aprender a testar os mais variados tipos de condições, para podermos controlar a execução de nosso programa de acordo com a entrada fornecida pelo usuário. POR JULIO CEZAR NEVES E aí cara, tentou fazer o exercício que te pedi em nosso último encontro? – Claro que sim! Em programação, se você não treinar não aprende. Você $ logado jneves jneves pts/0 12:02 (10.2.4.144) jneves está logado Oct 18 U Ah, agora sim! Lembre-se dessa pega- dinha: a maior parte dos comandos tem uma saída padrão e uma saída de erros (o grep é uma das poucas exceções: ele não exibe uma mensagem de erro me pediu um script para informar se Realmente funcionou. Passei meu quando não acha uma cadeia de carac- um determinado usuário, cujo nome nome de usuário como parâmetro e teres) e devemos redirecioná-las para o será passado como parâmetro para o ele disse que eu estava logado, porém buraco negro quando necessário. script, está “logado” (arghh!) ou não. ele imprimiu uma linha extra, que eu Bem, agora vamos mudar de assunto: Fiz o seguinte: não pedi, que é a saída do comando na última vez que nos encontramos who. Para evitar que isso aconteça, é aqui no botequim, quando já estávamos $ cat logado só mandá-la para o buraco negro do de goela seca, você me perguntou como mundo UNIX, o /dev/null. Vejamos se testam condições. Para isso, usamos #!/bin/bash então como ficaria: o comando test # Pesquisa se um usuário está # logado ou não $ cat logado Testes #!/bin/bash Todos estamos acostumados a usar o if who | grep $1 # Pesquisa se uma pessoa está if para testar condições, e estas são then # logada ou não (versão 2) sempre maior que, menor que, maior echo $1 está logado if who | grep $1 > /dev/null ou igual a, menor ou igual a, igual a e else then echo $1 não está no pedaço echo $1 está logado Tabela 1 – Opções do fi else test para arquivos echo $1 não está no pedaço Opção Verdadeiro se – Calma rapaz! Já vi que você chegou fi -e arq arq existe cheio de tesão. Primeiro vamos pedir -s arq arq existe e tem tamanho maior que zero os nossos chopes de praxe e depois Agora vamos aos testes: vamos ao Shell. Chico, traz dois cho- -f arq arq existe e é um arquivo regular pes, um sem colarinho! $ logado jneves -d arq arq existe e é um diretório -r arq arq existe e com direito de leitura – Aaah! Agora que já molhamos os nos- jneves está logado -w arq arq existe e com direito de escrita sos bicos, vamos dar uma olhada nos $ logado chico -x arq arq existe e com direito de execução resultados do seu programa: chico não está no pedaço����������������������������� 84 edição 04 www.linuxmagazine.com.br��������������������������������������������������������������������������������
  2. 2. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Papo de Botequim LINUX USER Tabela 2 – Opções do test No exemplo, testei a existência do cadeia de caracteres “01” é realmente para cadeias de caracteres diretório lmb. Se não existisse (else), ele diferente de “1”. Porém, a coisa muda seria criado. Já sei, você vai criticar a de figura quando as variáveis são testa- Opção Verdadeiro se: minha lógica dizendo que o script não das numericamente, já que o número 1 -z cadeia Tamanho de cadeia é zero está otimizado. Eu sei, mas queria que é igual ao número 01. -n cadeia Tamanho de cadeia é maior que zero cadeia A cadeia cadeia tem tamanho maior que zero você o entendesse assim, para então Para mostrar o uso dos conectores -o c1 = c2 Cadeia c1 e c2 são idênticas poder usar o “ponto-de-espantação” (!) (ou) e -a (e), veja um exemplo “animal”, como um negador do test. Veja só: programado direto no prompt do Bash. Me desculpem os zoólogos, mas eu diferente de. Para testar condições em if test ! -d lmb não entendo nada de reino, fi lo, classe, Shell Script usamos o comando test, só then ordem, família, gênero, espécie e outras que ele é muito mais poderoso do que mkdir lmb coisas do tipo, desta forma o que estou aquilo com que estamos acostuma- fi chamando de família ou de gênero tem dos. Primeiramente, veja na Tabela 1 cd lmb grande chance de estar total e comple- as principais opções (existem muitas tamente incorreto: outras) para testar arquivos em disco Desta forma o diretório lmb seria e na Tabela 2 as principais opções para criado somente se ele ainda não exis- $ Familia=felinae teste de cadeias de caracteres. tisse, e esta negativa deve-se ao ponto $ Genero=gato de exclamação (!) precedendo a opção $ if test $Familia = canidea U Tabela 3 – Opções do -d. Ao fi m da execução desse fragmento -a $Genero = lobo -o $Familia = U test para números de script, com certeza o programa esta- felina -a $Genero = leão ria dentro do diretório lmb. Vamos ver > then Opção Verdadeiro se Significado dois exemplos para entender a diferença > echo Cuidado n1 -eq n2 n1 e n2 são iguais equal na comparação entre números e entre > else n1 -ne n2 n1 e n2 não são iguais not equal cadeias de caracteres. > echo Pode passar a mão n1 -gt n2 n1 é maior que n2 greater than n1 -ge n2 n1 é maior ou igual a n2 greater or equal > fi n1 -lt n2 n1 é menor que n2 less than cad1=1 Pode passar a mão n1 -le n2 n1 é menor ou igual a n2 less or equal cad2=01 if test $cad1 = $cad2 Neste exemplo, caso o animal fosse then da família canídea e (-a) do gênero lobo, Pensa que acabou? Engano seu! Agora echo As variáveis são iguais. ou (-o) da familia felina e (-a) do gênero é hora de algo mais familiar, as famosas else leão, seria dado um alerta, caso contrá- comparações com valores numéricos. echo As variáveis são diferentes. rio a mensagem seria de incentivo. Veja a Tabela 3, e some às opções já fi Atenção: Os sinais de maior (>) no apresentadas os operadores da Tabela 4. início das linhas internas ao if são os Ufa! Como você viu, tem coisa pra Executando o fragmento de programa prompts de continuação (que estão chuchu, e o nosso if é muito mais pode- acima, teremos como resultado: defi nidos na variável $PS2). Quando o roso que o dos outros. Vamos ver em shell identifica que um comando con- uns exemplos como isso tudo funciona. As variáveis são diferentes. tinuará na linha seguinte, automatica- Testamos a existência de um diretório: mente ele coloca este caractere, até que Vamos agora alterá-lo um pouco para o comando seja encerrado. if test -d lmb que a comparação seja numérica: Vamos mudar o exemplo para ver se o then programa continua funcionando: cd lmb cad1=1 else cad2=01 $ Familia=felino mkdir lmb if test $cad1 -eq $cad2 $ Genero=gato cd lmb then $ if test $Familia = felino -o U fi echo As variáveis são iguais. $Familia = canideo -a $Genero = U else onça -o $Genero = lobo Tabela 4 echo As variáveis são diferentes. > then fi > echo Cuidado Operador Finalidade > else Parênteses () 0 E vamos executá-lo novamente: > echo Pode passar a mão > fi Exclamação ! 0 As variáveis são iguais. Cuidado -a 0 -o 0 Como você viu, nas duas execuções Obviamente a operação resultou em obtive resultados diferentes, porque a erro, porque a opção -a tem precedência ����������������������������� www.linuxmagazine.com.br edição 04 85 ��������������������������������������������������������������������������������
  3. 3. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� LINUX USER Papo de Botequim sobre a -o e, dessa, forma o que foi ava- Da mesma forma, para escolhermos mente a legibilidade, pois o comando if liado primeiro foi a expressão: CDs que tenham a participação do irá ficar com a sintaxe semelhante à das Artista1 e do Artista2, não é necessá- outras linguagens; por isso, esse será o $Familia = canideo -a $Genero = U rio montar um if com o conector -o. O modo como o comando test será usado onça egrep também resolve isso para nós. daqui para a frente. Veja como: Se você pensa que acabou, está muito Que foi avaliada como falsa, retor- enganado. Preste atenção à “Tabela Ver- nando o seguinte: $ egrep (Artista1|Artista2) U dade” na Tabela 5. musicas $Familia = felino -o FALSO -o U Tabela 5 - Tabela Verdade $Genero = lobo Ou (nesse caso específico) o próprio Combinação E OU grep poderia nos quebrar o galho: VERDADEIRO-VERDADEIRO TRUE TRUE Que resolvida resulta em: VERDADEIRO-FALSO FALSE TRUE $grep Artista[12] musicas FALSO-VERDADEIRO FALSE TRUE VERDADEIRO -o FALSO -o FALSO FALSO-FALSO FALSE FALSE No egrep acima, foi usada uma Como agora todos os conectores são expressão regular, na qual a barra ver- -o, e para que uma série de expressões tical (|) trabalha como um “ou lógico” e Ou seja, quando o conector é e e a conectadas entre si por diversos “ou” os parênteses são usados para limitar primeira condição é verdadeira, o resul- lógicos seja verdadeira, basta que uma a amplitude deste “ou”. Já no grep da tado fi nal pode ser verdadeiro ou falso, delas o seja. A expressão fi nal resultou linha seguinte, a palavra Artista deve dependendo da segunda condição; já no como VERDADEIRO e o then foi exe- ser seguida por um dos valores da lista conector ou, caso a primeira condição cutado de forma errada. Para que isso formada pelos colchetes ([]), isto é, 1 ou 2. seja verdadeira, o resultado sempre será volte a funcionar façamos o seguinte: verdadeiro. Se a primeira for falsa, o resul- – Tá legal, eu aceito o argumento, o if tado dependerá da segunda condição. $ if test ($Familia = felino U do shell é muito mais poderoso que Ora, os caras que desenvolveram o -o $Familia = canideo) -a U os outros caretas - mas, cá entre nós, interpretador não são bobos e estão ($Genero = onça -o $Genero = U essa construção de if test ... é muito sempre tentando otimizar ao máximo lobo) esquisita, é pouco legível. os algoritmos. Portanto, no caso do > then – É, você tem razão, eu também não conector e, a segunda condição não será > echo Cuidado gosto disso e acho que ninguém gosta. avaliada, caso a primeira seja falsa, já > else Acho que foi por isso que o shell que o resultado será sempre falso. Já > echo Pode passar a mão incorporou outra sintaxe, que substi- com o ou, a segunda será executada > fi tui o comando test. somente caso a primeira seja falsa. Pode passar a mão Aproveitando-se disso, uma forma Para isso vamos pegar aquele exem- abreviada de fazer testes foi criada. O Desta forma, com o uso dos parên- plo para fazer uma troca de diretórios, conector e foi batizado de && e o ou de teses agrupamos as expressões com o que era assim: ||. Para ver como isso funciona, vamos conector -o, priorizando a execução e usá-los como teste no nosso velho resultando em VERDADEIRO -a FALSO. if test ! -d lmb exemplo de troca de diretório, que em Para que seja VERDADEIRO o resul- then sua última versão estava assim: tado de duas expressões ligadas pelo mkdir lmb conector -a, é necessário que ambas fi if [ ! -d lmb ] sejam verdadeiras, o que não é o caso cd lmb then do exemplo acima. Assim, o resultado mkdir lmb fi nal foi FALSO, sendo então o else cor- e utilizando a nova sintaxe, vamos fazê- fi retamente executado. lo assim: cd lmb Se quisermos escolher um CD que tenha faixas de 2 artistas diferentes, nos if [ ! -d lmb ] O código acima também poderia ser sentimos tentados a usar um if com o then escrito de maneira abreviada: conector -a, mas é sempre bom lembrar mkdir lmb que o bash nos oferece muitos recursos fi [ ! -d lmb ] && mkdir lmb e isso poderia ser feito de forma muito cd lmb cd dir mais simples com um único comando grep, da seguinte forma: Ou seja, o comando test pode ser Também podemos retirar a negação (!): substituído por um par de colchetes ([]), $ grep Artista1 musicas | grep U separados por espaços em branco dos [ -d lmb ] || mkdir lmb Artista2 argumentos, o que aumentará enorme- cd dir����������������������������� 86 edição 04 www.linuxmagazine.com.br��������������������������������������������������������������������������������
  4. 4. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Papo de Botequim LINUX USER Tabela 6 diretório para dentro dele. Para execu- sempre estará dentro de lmb, desde que tar mais de um comando dessa forma, tenha permissão para entrar neste dire- Caractere Significado é necessário fazer um grupamento de tório, permissão para criar um subdire- * Qualquer caractere ocorrendo zero ou comandos, o que se consegue com o tório dentro de ../lmb, que haja espaço mais vezes ? Qualquer caractere ocorrendo uma vez uso de chaves ({}). Veja como seria o em disco suficiente... [...] Lista de caracteres modo correto: Vejamos um exemplo didático: depen- | “ou” lógico dendo do valor da variável $opc o script cd lmb || deverá executar uma das opções a { seguir: inclusão, exclusão, alteração ou No primeiro caso, se o primeiro mkdir lmb encerrar sua execução. Veja como fica- comando (o test, que está represen- cd lmb ria o código: tado pelos colchetes) for bem sucedido, } isto é, se o diretório lmb não existir, o if [ $opc -eq 1 ] comando mkdir será executado porque Ainda não está legal porque, caso o then a primeira condição era verdadeira e o diretório não exista, o cd exibirá uma inclusao conector era e. mensagem de erro. Veja o modo certo: elif [ $opc -eq 2 ] No exemplo seguinte, testamos se o then diretório lmb existia (no anterior testa- cd lmb 2> /dev/null || exclusao mos se ele não existia) e, caso isso fosse { elif [ $opc -eq 3 ] verdade, o mkdir não seria executado mkdir lmb then porque o conector era ou. Outra forma cd lmb alteracao de escrever o programa: } elif [ $opc -eq 4 ] then cd lmb || mkdir lmb Como você viu, o comando if nos per- exit mitiu fazer um cd seguro de diversas else Nesse caso, se o comando cd fosse maneiras. É sempre bom lembrar que o echo Digite uma opção entre U mal sucedido, o diretório lmb seria “seguro” a que me refi ro diz respeito ao 1 e 4 criado mas não seria feita a mudança de fato de que ao fi nal da execução você fi ����������������������������� www.linuxmagazine.com.br edição 04 87 ��������������������������������������������������������������������������������
  5. 5. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� LINUX USER Papo de Botequim Quadro 1 - Script case $opc in O comando date informa a data com- bem-educado 1) inclusao ;; pleta do sistema e tem diversas opções 2) exclusao ;; de mascaramento do resultado. Neste #!/bin/bash 3) alteracao ;; comando, a formatação começa com # Programa bem educado que 4) exit ;; um sinal de mais (+) e os caracteres de # dá bom-dia, boa-tarde ou *) echo Digite uma opção U formatação vêm após um sinal de per- # boa-noite conforme a hora entre 1 e 4 centagem (%), assim o %H significa a Hora=$(date +%H) esac hora do sistema. Dito isso, veja o exem- case $Hora in plo no Quadro 1. 0? | 1[01]) echo Bom Dia Como você deve ter percebido, eu Peguei pesado, né? Que nada, vamos ;; usei o asterisco como última opção, isto esmiuçar a resolução: 1[2-7] ) echo Boa Tarde é, se o asterisco atende a qualquer coisa, ;; então servirá para qualquer coisa que 0? | 1 [01] – Zero seguido de qualquer * ) echo Boa Noite não esteja no intervalo de 1 a 4. Outra coisa (?), ou (|) um seguido de zero ;; coisa a ser notada é que o duplo ponto-e- ou um ([01]), ou seja, esta linha "casa" esac vírgula não é necessário antes do esac. com 01, 02, ... 09, 10 e 11; exit Vamos agora fazer um script mais 1 [2-7] – Significa um seguido da lista radical. Ele te dará bom dia, boa tarde de caracteres entre dois e sete, ou seja, Neste exemplo você viu o uso do ou boa noite dependendo da hora em esta linha pega 12, 13, ... 17; comando elif como um substituto ou que for executado, mas primeiramente * – Significa tudo o que não casou com forma mais curta de else if. Essa é uma veja estes comandos: nenhum dos padrões anteriores. sintaxe válida e aceita, mas poderíamos fazer ainda melhor. Para isso usamos o $ date – Cara, até agora eu falei muito e bebi comando case, cuja sintaxe mostramos Tue Nov 9 19:37:30 BRST 2004 pouco. Agora eu vou te passar um a seguir: $ date +%H exercício para você fazer em casa e 19 me dar a resposta da próxima vez em case $var in que nos encontrarmos aqui no bote- padrao1) cmd1 quim, tá legal? cmd2 – Beleza! cmdn ;; – É o seguinte: faça um programa que padrao2) cmd1 receba como parâmetro o nome de cmd2 um arquivo e que quando executado cmdn ;; salve esse arquivo com o nome origi- padraon) cmd1 nal seguido de um til (~) e abra esse cmd2 arquivo dentro do vi para ser editado. cmdn ;; Isso é para ter sempre uma cópia esac de backup do arquivo caso alguém faça alterações indevidas. Obvia- Onde a variável $var é comparada aos mente, você fará as críticas neces- padrões padrao1, ..., padraon. Caso um sárias, como verificar se foi passado dos padrões corresponda à variável, o um parâmetro, se o arquivo indicado bloco de comandos cmd1, ..., cmdn cor- existe... Enfi m, o que te der na telha e respondente é executado até encontrar você achar que deva constar do script. um duplo ponto-e-vírgula (;;), quando Deu pra entender? o fluxo do programa será interrompido – Hum, hum... e desviado para instrução imediata- – Chico, traz mais um, sem colarinho! ■ mente após o comando esac (que, caso não tenham notado, é case ao contrário. Julio Cezar Neves é Ele indica o fi m do bloco de código, da Analista de Suporte de Sistemas desde SOBRE O AUTOR mesma forma que ot comando fi indica 1969 e trabalha com o fi m de um if). Unix desde 1980, Na formação dos padrões, são aceitos quando participou os caracteres mostrados na Tabela 6. do desenvolvimento Para mostrar como o código fica do SOX, um sistema operacional similar ao Unix pro- melhor, vamos repetir o exemplo ante- duzido pela Cobra computadores. rior, só que desta vez usaremos o case Pode ser contatado no e-mail julio. em vez do tradicional bloco de código neves@gmail.com com if ... elif ... else ... fi.����������������������������� 88 edição 04 www.linuxmagazine.com.br��������������������������������������������������������������������������������

×