Oficina de ShellScript Segunda Parte Wildcards Variáveis de Ambiente Comandos em Shell Script Parâmetros para o programa Mais comandos /dev/null Bruno L. Albrecht Felipe A. Chies PET Computação UFRGS Wildcards Recurso utilizado para especificar um ou mais arquivos/diretório de uma vez só. Permite a filtragem do que será listado/copiado/ apagado/etc É uma feature que deixa a shell “mais poderosa” que a GUI no trato de arquivos. Quatro tipos: *, ?, [ ] e { } Wildcards *: qualquer coisa! (zero ou mais caracteres) ?: um único caractere qualquer! rm log?.txt → log1.txt, loga.txt, lob[.txt, etc rm *?.* → todos os arquivos não ocultos rm *.txt → apaga todos os arquivos que terminem com .txt Obs.: para nos referirmos a um arquivo que um wildcard no nome, utilizamos '\wildcard' Wildcards [ ] : um dos caracteres listados (ou não) [abcd] : a ou b ou c ou d [ad] : qualquer um no intervalo de 'a' a 'd' [!abcd] : qualquer um, menos a,b,c,d [!ad] : qualquer um, menos os que estão no intervalo de 'a' a 'd' Exemplo: sudo umount /dev/[hs]d[ad][19] desmonta todos os dispositivos Wildcards { } : cada opção separada por vírgulas é considerada apenas uma vez echo t{r,igr,rist}es echo alun{o,a}{,s} tres tigres tristes aluno alunos aluno alunos ShellScript: Introdução Shell Interpretador de comandos; Script É uma descrição geral de qualquer programa escrito em linguagem interpretada, ou seja, não compilada; Temos script em PHP, Ruby, script em PERL e também Shell Script; Objetivos Facilitar as tarefas repetidas do adminstrador: podem ser agendados para execução através da tabela crontab (man cron); Scripts podem fazer tarefas complexas evita a redigitação de comandos; podemos combinar diversos comandos, com controladores de fluxo e variáveis; São “rápidos” de serem criados e não precisam ser compilados; Hello World Muito simples: Muito simples!!! Crie o arquivo: gedit hello.sh & #!/bin/bash echo "Hello World!!!" Para executálo: chmod +x hello.sh ./hello.sh Variáveis O bash reconhece uma variável quando ela começa com $; Declaração: var=“valor” valor pode ser número, frase, outras variáveis ou comando. Pode ser expressado entre “ ”(aspas duplas), ' ' (apóstrofes) ou ` `(crases); Variáveis Aspas duplas: valor da variável será interpretado; variavel="Meu login é: $USER" echo $variavel Meu login é: Bruno Apóstrofes: declaração literal variavel='Meu login é: $USER' echo $variavel Meu login é: $USER Entre crases Crases: vão interpretar os comandos declarados. Se forem combinados com texto numa expressão, devese usar as aspas juntamente!!! variavel=“Meu diretório atual é: `pwd`” echo $variavel Meu diretório atual é: /home/bruno Obs.: É o mesmo que $(comando) var=$(pwd) PARÂMETROS É um array de parâmetros! De $1 a $9 $0 → nome do programa $# → quantidade de parâmetros $* → conjunto de todos os parâmetros Shift n → utilizado para deslocar n parâmetros Variáveis de Ambiente São variáveis LOCAIS ou GLOBAIS já definidas pelo sistema operacioal Podem ser redefinidas Exemplo: O nome do usuário é determinado a partir de uma variável de ambiente: $USER Variáveis de Ambiente Principais variáveis globais: PATH diretório onde podem ser encontrados os executáveis USER nome (login) do usuário HOME diretório home do usuário HOST nome do host (máquina) SHELL shell ativo PS1 mensagem no terminal IFS separador de parâmetros (default: ” ”) A lista completa pode ser obtida através do comando Variáveis de Ambiente Para definir uma variável de ambiente GLOBAL: Para definir uma variável de ambiente LOCAL: VARIAVEL=conteudo Exemplo: export VARIAVEL=conteúdo export PATH=$PATH:/meu_dir Obs.: esta forma de definir variáveis é TEMPORÁRIA, ou seja, apenas enquanto o shell estiver ativo Variáveis de Ambiente Para definir variáveis globais e locais PERMANENTEMENTE, devemos alterar os seguintes arquivos: ~./bashrc → somente para o usuário atual /etc/bash.bashrc → para todos os usuários Imprimir o conteúdo de uma variável: echo $VARIAVEL Deletar uma variável: unset VARIÁVEL Expressões aritméticas Para o Shell executar operações aritméticas, devemos utilizar $((expressão)) echo $((2+2)) var1=$((var2+var1)) Ou então, o comando let: let var1++ let var2 Expressões aritméticas x++, ++x, x, x: [pós,pré][in,de]cremento y x**y: potenciação (x ) x*y, x/y, x%y: multiplicação, divisão, resto <, <=, >, >=, ==, !=: comparações &&, ||: AND e OR lógicos Comandos: test Descrição: testar qualquer coisa! test $var1 lt $var2 Obs.: resultado em $? if O comando if testa o STDERR (variável de ambiente $?), mas, para ficar semelhante à sintaxe do C, utilizamos o comando test If test $variavel gt 10 then echo ”é maior que 10” else echo ”é menor que 10” fi If [ $variavel gt 10 ] then echo ”é maior que 10” else echo ”é menor que 10” fi Atalho do comando test no if: [ expressão ] → não do espaço antes e depois da expressão case Para não precisarmos concatenar milhares de ifs, utilizamos o case: if [ $var eq 1 ] then <comandos> elif [ $var eq 2 ] then <comandos> elif [ $var eq 3 ] then <comandos> elif [ $var eq 4 ] then <comandos> else <comandos> fi case $var in 1) <comandos> ;; 2) <comandos> ;; 3) <comandos> ;; 4) <comandos> ;; *) <comandos> esac Não há ;; no último grupo ● Para fechar o case, usamos “esac” ● Podemos usar wildcards nos padrões de grupos. ex.: [14], ?, ??, 3|4, ?0|?5, [1234] etc ● For for numero in um dois três quatro cinco do echo "Contando: $numero" done Um comando muito útil para utilizar o for é o seq, que gera sequências de números: for num in $(seq 10) do <...> for num in $(seq 0 2 10) done do <...> done for num in $(seq 6 10) do <...> done For for par do echo "Parâmetro: $par" done Neste caso, não colocamos o “in” depois da variável. Isto serve para a variável (no caso “par”) receber cada parâmetro passado para o programa a cada laço do for. For Podemos ainda usar uma sintaxe parecida com a do C. for ((i=0 ; i<=9 ; i++)) do echo n “$i “ done for (( ; i<=9 ; )) do let i++; echo n “$i “ done Outra forma de for for arq in * do let i++; echo “$i > $arq” done 1 > arquivo1.txt 2 > arquivo2.sh 3 > arquivo3.bla 4 > arquivo4.doc etc... Break e Continue break: pára o laço continue: ignora o que tem embaixo e volta para o início do laço for ((i=0 ; ; i++)) do echo n “$i “ if [ i lt 9 ] then continue else break done $ ./testefor 0 1 2 3 4 5 6 7 8 9 for ((i=0 ; ; i++)) do echo n “$i “ if [ i eq 9 ] then break; done $ ./testefor2 0 1 2 3 4 5 6 7 8 9 While Utilizando um contador com o while: i=0 while test i le 10 do i=$((i+1)) echo "Contando: $i" done while : do if test f /tmp/lock then echo "Aguardando lock..." sleep 1 else break fi done Para um loop infinito (saindo com break): Until Igual ao while, mas o teste é feito após os comandos serem executados i=0 until [ $i eq 9 ] do echo n “$i ” let i++ done until ! who | grep pet do sleep 60 done echo n “usuário pet foi embora!!” echo “às $(date “%H:%Mh”)” $./testeuntil 0 1 2 3 4 5 6 7 8 $ $ ./testeuntil2 pet pts/0 Jan 4 16:47 (143.54.12.140) pet pts/0 Jan 4 16:48 (143.54.12.140) ... pet pts/0 Jan 4 17:39 (143.54.12.140) usuário pet foi embora às 17:39h!! $ Interação com o usuário read: recebe uma lista de parâmetros e salva nas variáveis Se houver mais parâmetros do que variáveis, a última recebe o resto echo: imprime uma mensagem no STDOUT $ read var1 var2 var3 Curso de ShellScript $ echo $var1 Curso $ echo $var2 de $ echo $var3 ShellScript $ read var1 var2 Curso de ShellScript $ echo $var1 Curso $ echo $var2 de ShellScript Leitura de Arquivos Duas formas: while read LINHA do echo $LINHA done < arquivo.txt Cat arquivo.txt | while read LINHA do echo $LINHA done O while termina quando o read encontra um EOF (leitura mal sucedida)