O documento fornece uma introdução sobre Shell Script, descrevendo os principais tipos de shell, a anatomia de uma linha de comando, atribuição de variáveis, comandos, redirecionamentos e controle de fluxo com if/else e loops.
1. César Vianna - http://about.me/vianna
Curso Shell ScriptFontes utilizadas:
Manual Shell Script de Franco José Vieira da Silva
Curso de Shell Script do Júlio Neves
Livro Programação Shell Linux – 6ª Edição - de Júlio Neves
2. César Vianna - http://about.me/vianna
O Ambiente Linux/Unix
3. César Vianna - http://about.me/vianna
Tipos de Shell
Bourne Shell(sh) – Desenvolvido por Stephen
Bourne do Bell Labs (da AT&T, onde também foi
desenvolvido o sistema operacional Unix),
foi,durante muitos anos, o Shell padrão do
Sistema Operacional Unix.
Korn Shell(ksh) – Desenvolvido por David Korn,
também do Bell Labs, é um superconjunto do sh,
isto é, possui todas as funcionalidades do sh e
a elas agregou muitas outras.
4. César Vianna - http://about.me/vianna
Tipos de Shell
Bourne Again Shell(bash) – Desenvolvido
inicialmente por Brian Fox e Chet Ramey, este é
o Shell do projeto GNU.
C Shell(csh) – Desenvolvido por Bill Joy, da
Universidade Berkley, é o Shell mais utilizado
em ambiente BSD.
5. César Vianna - http://about.me/vianna
Anatomia de uma linha de comando
Shell irá verificar:
Caracteres especiais (reservados)
Se a linha passada é um comando ou uma
atribuição de valores
Digite:
$ ls *
$ ls teste
6. César Vianna - http://about.me/vianna
Atribuição
Linha passada ao Shell contém um “=”
Sem a presença de espaços em branco entre eles
Digite:
$ valor=1000
$ echo valor
$ echo $valor
7. César Vianna - http://about.me/vianna
Comando
Comando é dividido em partes separadas por
espaços em branco
Primeira parte é o nome do programa
Após o nome teremos os argumentos, opções,
parâmetros, redirecionamentos e variáveis
Digite:
$ touch linux
$ x=linux
$ ls x
$ ls $x
8. César Vianna - http://about.me/vianna
Redirecionamentos
Servem para mudar a ordem natural das coisas
Comando para comando (utilizando o | (pipe))
Digite
$ ls -l | more
$ echo 5+2 | bc
9. César Vianna - http://about.me/vianna
Redirecionamentos
Comando para Arquivo com sinal de Maior que (>)
Digite
$ cat linux
$ echo Hello World tem até no shell > linux
$ cat linux
$ echo É bom mesmo esse esquema... > linux
$ cat linux
10. César Vianna - http://about.me/vianna
Redirecionamentos
Podemos combinar redirecionadores
Digite um comando que calcule o produto de
5 e 3 e grave o resultado em um arquivo
11. César Vianna - http://about.me/vianna
Redirecionamentos
Salvar sem substituir (append)
Digite:
$ echo É mais que bom esse esquema... >> linux
$ cat linux
12. César Vianna - http://about.me/vianna
Substituição de Coringas
* - um conjunto de caracteres
? - um caracter
Digite:
$ ls linu?
$ ls l*
13. César Vianna - http://about.me/vianna
Escapando!!
Apóstrofo (')
O Shell não interpreta os caracteres que estão
entre ''
Digite:
$ ls li*
$ ls 'li*'
15. César Vianna - http://about.me/vianna
'Escapando!!'
Aspas (“)
Igual ao aṕostrofo, mas os caracteres cifrão
($), crase (`) e barra invertida () são
interpretados
Digite:
$ echo $valor
$ echo '$valor'
$ echo “$valor”
16. César Vianna - http://about.me/vianna
'Escapando!!'
Outros exemplos:
$ echo
$ echo “”
$ echo ''
$ echo Aula de Shell
$ echo Aula de Shell
$ echo “Aula de Shell”
17. César Vianna - http://about.me/vianna
Variáveis
As Variáveis são identificadas por um cifrão ($)
Digite:
$ echo O $USER está logado agora
$ echo $PATH
$ echo $PWD
18. César Vianna - http://about.me/vianna
Substituições
Varáveis novas recebem valores de varáveis
antigas ou vazio.
O nome das variáveis deve sempre começar com uma
letra ou um caractere _
Digite:
$ 123=x
$ var1=10
$ echo $var1
$ var2=`expr $var1 + 10`
$ echo $var2
20. César Vianna - http://about.me/vianna
Controle de Fluxo
O Shell permite o uso de condicionais e laços
para o controle de fluxo
Digite
$ if ls linux
then echo 'Achou!'
else echo 'Não achou!'
fi
21. César Vianna - http://about.me/vianna
Condições
-eq igual (equal)
-ne diferente (ne=not equal)
-gt maior (greater than)
-ge maior ou igual (greater / equal)
-lt menor (lesse than)
-le menor ou igual (less / equal)
-d se é um diretório (directory)
-e se existe (exists)
-z se é vazio (zero)
-f se contem texto. (filled)
-r se o arquivo possui permissão de leitura (Read)
-w se o arquivo possui permissão de escrita. (Write)
-x se o arquivo é executavel. (eXecutable)
22. César Vianna - http://about.me/vianna
IF
Sua sintaxe básica é:
$ if [condição]
then
comando 1
comando 2
comando N
fi
Utilizando IF e ELSE, crie testes para:
1 - Verificar se duas variáveis x e y são iguais
ou diferentes.
2 – Verificar se o arquivo ~/teste existe. Caso
não exista, criar um arquivo vazio com esse nome.
23. César Vianna - http://about.me/vianna
CASE
O case casa com menu!
Crie um arquivo com extensão “.sh” e com o conteúdo
do exemplo da apostila
Atribua permissão de execução para o arquivo
Execute o arquivo
24. César Vianna - http://about.me/vianna
Repetições (Loop)
Fazer até, fazer até... até quando root quiser!
Utilizaremos os laços:
For
While
Until
25. César Vianna - http://about.me/vianna
FOR
Digite:
$ for i in *
do
echo Arquivo $i
done
Agora adicione um contador ao echo
Dica: n=$(($n+1))
26. César Vianna - http://about.me/vianna
FOR
Outra forma:
$ for ((i=0; i <= $TOTAL; i++))
do
comandos
done
27. César Vianna - http://about.me/vianna
FOR
Crie um script para calcular o fatorial de n
28. César Vianna - http://about.me/vianna
Fatorial com FOR
$ fat=1;n=6
$ for ((i=1; i <= $n; i++))
do
fat=$(($fat*$i))
done
$ echo $fat
30. César Vianna - http://about.me/vianna
Conectores Lógicos
● E - &&
● OU - ||
● O que realiza o teste abaixo?
$ if [ $m -gt 7 ] && [ $f -lt 20 ]
then
echo ap
else
echo rp
fi
31. César Vianna - http://about.me/vianna
Dicas Extras
● Executar um shell filho
$ ( cd /tmp; ls )
● Salvar resultado em variável
$ x=`ls`
$ echo $x
$ echo “$x”
$ echo "$x"|tr "n" ";"
32. César Vianna - http://about.me/vianna
Dado um arquivo com o padrão abaixo e N linhas,
faça um script que leia cada linha e informe se o
respectivo aluno está aprovado ou reprovado.
Para obter aprovação o aluno deve atingir média
das 3 provas maior ou igual a 7 e o número de
faltas deve ser menor que 20.
Padrão do arquivo:
Nome;Nota1;Nota2;Nota3;Faltas
Sugestão de resolução no próximo slide...
33. César Vianna - http://about.me/vianna
#!/bin/bash
for i in `cat alunos.csv`
do
nome=`cut -d";" -f1 <<<$i`
p1=`cut -d";" -f2 <<<$i`
p2=`cut -d";" -f3 <<<$i`
p3=`cut -d";" -f4 <<<$i`
f=`cut -d";" -f5 <<<$i`
media=`expr ( $p1 + $p2 + $p3 ) / 3`
echo "$nome obteve média $media e faltou $f vezes."
if [ $media -ge 7 ] && [ $f -lt 20 ]
then
echo Aluno aprovado
echo
else
echo Aluno reprovado
echo
fi
done
34. César Vianna - http://about.me/vianna
Esse redirecionamento especial permite que repassemos ao
shell um bloco de instruções, delimitadas por um LABEL.
No exemplo abaixo, iniciamos uma conexão ssh para o
endereço local. Após inserimos a marca de início do here
document “<<” (sem aspas). Dentro do bloco de instruções
executaremos o script.sh e encerraremos a conexão ssh. Por
fim, fechamos o bloco com o LABEL.
Assim, o script.sh é executado dentro da conexão ssh, que
pode ser realziada para qualquer computador da rede.
Exemplo:
$ ssh cvianna@127.0.0.1 << LABEL
./script.sh
exit
LABEL
Here Document
35. César Vianna - http://about.me/vianna
Ao trabalharmos com Scripts em Shell, temos a
possibilidade de utilizar passagem de parâmetros ao
Script. Vejamos como:
● Parâmetros ficam armazenados na variável $*
● Essa variável pode ser inicializada de 1 até 9
● Na variável $0, teremos o nome do Script
● A quantidade de parâmetros é informada por $#
Parâmetros
36. César Vianna - http://about.me/vianna
#!/bin/bash
case $2 in
+) echo $(($1+$3)) ;;
-) echo $(($1-$3)) ;;
/) echo $(($1/$3));;
*) echo $(($1*$3));;
*) echo "Você deve escolher uma opção válida, programa terminado
" ;;
esac
Case
38. César Vianna - http://about.me/vianna
O comando grep realiza pesquisas em um arquivo
texto, com ou sem expressões regulares simples.
$ grep bash /etc/passwd
Ele tem um irmão mais rapidinho que não usa
regexp. O Fast Grep
$ fgrep bash /etc/passwd
E um primo bem esperto. O Extended Grep permite
regexp
$ egrep "^[abc]" /etc/passwd
Pesquisando com a família grep
^ - Início de Linha
$ - Final de linha
39. César Vianna - http://about.me/vianna
Dado um aequivo csv com uma lista de verbos
irregulares do inglês, crie um script que receba
como parâmetro um verbo no português e imprima
sua conjugação em inglês.
Pesquisando com a família grep
40. César Vianna - http://about.me/vianna
Podemos pesquisar um conteúdo em vários arquivos.
Crie 3 arquivos com os seguintes conteúdos:
Pesquisando com a família grep
● arquivo2.txt
a
d
e
● arquivo3.txt
a
f
g
● arquivo1.txt
a
b
c
Vamos verificar quais arquivos contém a letra “a”
$ grep a `find . -name “arquivo*”`
E agora os que NÃO contém a letra “d”
$ grep -v d `find . -name “arquivo*”`
41. César Vianna - http://about.me/vianna
O comando wc conta linhas, palavras, bytes,
caracteres...
$ echo Shell| wc -m
O comando acima conta quando caracteres foram
impressos pelo comando echo.
Algo ficou estranho? Então tente:
$ printf Shell| wc -m
WC
42. César Vianna - http://about.me/vianna
● Baseando-se no arquivo de verbos irregulares
● Quantas linhas iniciam pela letra “a”
● Quantas palavras e letras o arquivo contém
● O comando who exibe os usuários logados no
sistema. Digite uma combinação de comandos que
exiba a frase “Existem N usuários conectados ao
sistema”
WC
43. César Vianna - http://about.me/vianna
● O comando cat exibe um arquivo do início ao
fim.
● Já o comando tac exibe no sentido inverso
● Exemplos:
$ seq 1 5 | cat
$ seq 1 5 | tac
Cat e Tac
Opções úteis do cat
-v : exibe controles
-n : exibe o número das linhas
-e : exibe quebra de linha ($)
44. César Vianna - http://about.me/vianna
● O comando head exibe as primeiras linhas de um
arquivo (por padrão 10)
● Podemos utilizar a opção -n X para delimitar a
quantidade de linhas
● Exemplos:
$ seq 1 25 | head
$ seq 1 25 | head -5
● O comando tail faz o mesmo, porém com as linhas
finais
Head e Tail
45. César Vianna - http://about.me/vianna
● Usando head e tail imprima a 10ª linha do
arquivo /etc/passwd
Head e Tail
46. César Vianna - http://about.me/vianna
● A opção -f do comando tail exibe o conteúdo
inserido em um arquivo à medida que ele é
alterado.
● Exemplo:
Em um terminal digite:
$ tail -f arquivo.txt
Em outro digite:
$ echo teste > arquivo.txt
Verifique o resultado do tail
Head e Tail
47. César Vianna - http://about.me/vianna
● O comando tr permite substiuir ou remover
caracteres
● Exemplos:
$ echo caza | tr “z” “s”
$ echo casa | tr “a-z” “A-Z”
● Usando ls -lh e cut, exiba somente a quinta
coluna impressa
● Probmelas?
● O tr -s “ “ resolve!
Trocando e Removendo Caracteres
48. César Vianna - http://about.me/vianna
● Por fim, a opçaõ -d permite remover caracteres
● Exemplos:
$ echo caza | tr “z” “s”
$ echo casa | tr “a-z” “A-Z”
● Usando ls -lh e cut, exiba somente a quinta
coluna impressa
● Probmelas?
● O tr -s “ “ resolve!
Trocando e Removendo Caracteres
49. César Vianna - http://about.me/vianna
● Digite um comando if que verifique se o arquivo
/tmp/aulashell existe. Caso não exista, crie um
arquivo vazio com esse nome.
● Dica: compare com -e
Encolhendo o IF
50. César Vianna - http://about.me/vianna
● O comando exit interrompe um script em qualquer
ponto de sua execução.
● Podemos ainda passar um código de saída que
será armazenado na variável $?
● Exemplo
$ if [ “$#” -ne 3 ]
then
echo “Parâmetros inválidos”
exit 1
fi
Finalizando Scripts
51. César Vianna - http://about.me/vianna
● O comando read lê informações do usuário
● Seguem opções desse comando:
● -p prompt : exibe o prompt digitado antes da
leitura
● -n num : lê a quantidade de caracteres
especificada por num
● -t seg : limita a leitura a seg segundos
● -s : oculta os caracteres digitados
Read
52. César Vianna - http://about.me/vianna
● O while testa um comando e executa um bloco de
instruções enquanto o comando for válido.
● Podemos utilizá-lo para ler arquivos.
$ while read linha
do
echo Valor da linha igual a $linha
done < arquivo
Utilizando While para Ler Arquivos
53. César Vianna - http://about.me/vianna
● Inicializando
$ vetorx=(a b c d e)
$ vetorx[5]=f
● Imprimindo o primeiro registro
$ echo ${vetor[0]}
● Imprimindo todos os registros
$ echo ${vetor[@]}
ou
$ echo ${vetor[*]}
Vetores
54. César Vianna - http://about.me/vianna
● Imprimindo os índices
$ echo ${!vetor[@]}
ou
$ echo ${!vetor[*]}
● Inserindo um elemento ao final do vetor
$ vetor=(${vetor[@]} "$elem")
● Inserindo um elemento no início do vetor
$ vetor=( "$elem" ${vetor[@]} )
Vetores
55. César Vianna - http://about.me/vianna
● Apagando um registro
$ unset vetor[i]
● Apagando o vetor
$ unset vetor
Vetores