mini-curso de introdução ao gnu/linux · introdução shell interpretador de comandos script É...
TRANSCRIPT
Min i -Curso de In t rodução ao GNU/L inux
AULA 8
Bruno L. AlbrechtFelipe A. Chies
Lucas F. ZawackiPET Computação UFRGS
Setembro 2009
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 PHP, Perl, Python e Shellscript.
Objetivos
Facilitar tarefas repetitivas do administrador:
Evita a redigitação de comandos;
Podem ser agendadas para execução através da tabela crontab (man cron).
Scripts podem realizar tarefas complexas:
Podemos combinar diversos comandos com controle de fluxo e variáveis
São rápidos de serem criados e não precisam ser compilados.
Hello World
Muito simples!
Crie o arquivo: $ vi hello.sh
#!/bin/bash
echo ”Hello World”
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);
Entre aspas duplas
As aspas vão interpretar as variáveis que estiverem dentro do valor;
Exemplo:
$ variavel="Meu login é: $USER"
$ echo $variavel
#Meu login é: PET
Entre aspas simples
O que estiver entre apóstrofes não será interpretado. Declaração literal;
Exemplo:
$ variavel='Meu login é: $USER'
$ echo $variavel
#Meu login é: $USER
Entre crases
Vão interpretar os comandos declarados.
Se forem combinados com texto numa expressão, deve-se usar as aspas juntamente!!!
Exemplo:
$ variavel=“Meu diretório atual é: `pwd`”
$ echo $variavel
#Meu diretório atual é: /home
Obs.: É o mesmo que $(comando)
var=$(pwd)
Revendo
$ variavel="Eu estou logado como usuário $user"
$ echo $variavel
Eu estou logado como usuário cla
$ variavel='Eu estou logado como usuário $user'
$ echo $variavel
Eu estou logado como usuário $user
$ variavel="Meu diretório atual é o `pwd`"
$ echo $variavel
Meu diretório atual é o /home/cla
Caracteres de Ambiente
Priorizar expressoes ( parenteses em muitas linguagens)
Em shell utiliza-se craze (`)
$ cat < texto | wc -l
9
$ echo ”Meu arquivo tem cat < texto | wc -l linhas”
Meu arquivo tem cat < texto | wc -l linhas
$ echo ”Meu arquivo tem `cat < texto | wc -l` linhas”
Meu arquivo tem 9 linhas
$ echo Meu arquivo tem `cat < texto | wc -l` linhas
Meu arquivo tem 9 linhas
COMANDOS EM SHELL
Linha
Espaçamento
Nome do programa
Opções/parâmetros
Redirecionamentos
Variáveis
$ ls #comando que lista os arq. Do diretorio atual
linux
$ tamanho=5 #atribuindo 5 para a variavel tamanho
$ tamanho = 5 #avalie a diferenca
ENTRADAS E SAÍDAS
STDIN / STDOUT / STDERR
> / >> / < / 2> / 2>>
/dev/null
CatLista o conteúdo do arquivo especificado para a Saída
Padrão
$ cat #testar nao especificando entrada nem saida
$ cat > teste #redicionara entrada padrao para o arquivo teste
$ cat >> teste #avalie a difereca
$ cat < teste #direciona para saida padrao o conteudo de teste
Escrita ”direta”
Para conseguir juntar mais de uma expressao em apenas uma linha utiliza-se o ponto e virgula (;)
$ pwd ; cd /etc; pwd; cd -; pwd
/home/meudir
/etc/
/home/meudir
Observe que cada comando e' executado como um novo shell, por isso a manutencao do diretorio do exemplo acima.
Interação com o usuário
Podemos ler uma variável com o comando read;
read variavel;
Também podemos receber argumentos na chamada do programa:
$0: Nome do script (forma de invocação);
$1: 1o argumento;
$n: argumento n;
$#: número de argumentos recebidos;
$* ou $@: lista todos argumentos;
read
O read recebe uma lista de parâmetros e salva nas variáveis. Se houver mais parâmetros que variáveis, a última recebe o resto.
$ read var1 var2 var3
Papo de Botequim
$ echo $var1
Papo
$ echo $var2
de
$ echo $var3
Botequim
$ read var1 var2
Papo de Botequim
$ echo $var1
Papo
$ echo $var2
de Botequim
Interação com o usuário
Passagem de parametros
$ cat > prog1 #no linux nao precisa ser .exe
#!/bin/bash
# Programa para testar passagem de parametros
echo "Par. 1 -> $1"
echo "Par. 2 -> $2"
echo "Par. 3 -> $3"
#!/bin/bashIndica que todas linhas abaixo deverão ser executadas pelo
bash
Executando
$ prog1 a b c
bash: prog1: comando não encontrado
$ ./prog1 a b c
bash: ./prog1: Permissão negada
$ chmod 755 prog1 #dada permissao de execucao para o prog1
$ ./prog1 a b c
Par. 1 -> a
Par. 2 -> b
Par. 3 -> c
Interação com o usuário
$ cat > prog2; chmod 755 prog2; ./prog2;
#!/bin/bash
echo "Digite alguma coisa: " ; read variavel
echo "Voce digitou: $variavel"
Digite alguma coisa: O PET eh demais!
Voce digitou: O PET eh demais!
Interação com o usuário
Exemplo 2:
#!/bin/bash
echo "Vou buscar dados do sistema. Posso continuar? [sn] "
read RESPOSTA
test "$RESPOSTA" = "n" && exit
echo "Data e Horário:"
date
echo
echo "Uso do disco:"
df
Acessando Parametros
Cabe ressaltar que podemos referênciar apenas 9
parâmetros ao mesmo tempo através das variáveis
$1 até $9.
Para acessarmos os outros parâmetros utilizamos o
comando shift.
Sua sintaxe é shift n, n=1 é o default, onde n indica o
número de parâmetros a ser desprezados,
passando a ser o n+1 o parâmetro $1.
Expressões Aritméticas
Para que o shell execute expressões aritméticas basta utilizar a construção:
$(( expressão ))
echo $((2 + 2))
NUM=20
NUM=$((NUM + 1))
let NUM++ # pós incremento, ou ++NUM (pré)
let NUM-- #pós decremento, ou –NUM (pré)
NUM=$((NUM*3)) #multiplicação
NUM=$((NUM**3)) #potenciação
Expressões Aritméticas
x++ e ++x, x-- e --x: pós e pré (in/de)cremento
x**y: potenciação (xy)
x*y, x/y, x%y: multiplicação, divisão, resto da divisão
x+y, x-y: soma, subtração
<, <=, >, >=: comparações
==, !=: igualdade, desigualdade
&&, ||: AND lógico, OR lógico
MAN
”Programa que ira lhe ensinar a usar outros programas”
O comando man e' a biblioteca de referencia na utilizacao de comandos, ou seja, com ele pode-se descobrir facilmente o que um comando faz e que atributos devem ser passados para ele.
Obs.: sudo apt-get install manpages manpages-dev
$ man cat #para sair aperte 'q'
$ man ls
$ man -k java
$man man
PIPE (|)
”Comunicacao entre programas”
O pipe serve para redirecionar a saída de um comando para a entrada de outro.
$ ls | wc -l
10
#nesse caso o comando wc -l (conta quantas linhas uma entrada possui) recebeu como entrada a saida do comando ls (listagem de arquivos do diretorio atual). Resumidamente, acabamos de contar quantos arquivos temos no nosso diretorio atual.
#para maiores informacoes man wc
*GREP
$ grep felipe ./exemplos/arquivo1
#procura pelas ocorrencias de felipe no arquivo especificado
$ grep grep *.sh
#procura pelas ocorrencias de grep em todos os programas do diretorio
$ who | grep elipe
#procura por elipe na lista de usuarios, man who
$ who | grep '^felipe'
#procura pelo usuario felipe, observe a diferenca do exemplo acima
*GREP
O grep pode ou não usar expressões regulares simples, porém no caso de não usá-las, o fgrep é melhor, por ser mais rápido;
O egrep ("e" de extended, extendido) é muito poderoso no uso de expressões regulares. Por ser o mais lento da família, só deve ser usado quando for necessária a elaboração deuma expressão regular não aceita pelo grep;
O fgrep ("f" de fast, rápido, ou de "file", arquivo) como o nome diz é o rapidinho da família, executa o serviço de forma muito veloz (por vezes é cerca de 30% mais veloz que o grep e 50% mais que o egrep), porém não permite o uso de expressões regulares na pesquisa.
No Linux utilizem SEMPRE grep. egrep e fgrep sao scripts em Shell que chamam o grep.
*GREP
$ egrep (Linux | linux) arquivo
#expressão regular complexa
$ grep [Ll]inux arquivo
#expressão regular
$ ls -l | grep '^l'
lrwxrwxrwx 1 felipe felipe 21 2009-03-01 16:31 downloads -> /media/disk/downloads
lrwxrwxrwx 1 felipe felipe 7 2009-03-03 16:51 grupos -> /grupos
lrwxrwxrwx 1 felipe felipe 9 2009-03-03 16:49 pet-docs -> /pet-docs
lrwxrwxrwx 1 felipe felipe 6 2009-03-03 16:49 users -> /users
CONTROLE DE FLUXO
if COMANDO
then
comandos
else
comandos
fi
for VAR in LISTA
do
comandos
done
until COMANDO
do
comandos
done
while COMANDO
do
comandos
done
O comando test
O canivete suíço dos comandos do shell é o "test", que consegue fazer vários tipos de testes em números, textos e arquivos. Possui várias opções:
Controle de Fluxo
O comando if testa o STDERR (variável de ambiente $?), mas, para ficar semelhante à sintaxe usual, utilizamos o comando test expressão
IF
O comando IF não testa uma condição, mas um comando. Na verdade, ele testa a STDERR, ou seja, a variável deambiente $?
Portanto, não podemos utilizar o IF como em C, por exemplo.
Mas o comando “test” faz com que o IF pareça testar uma “condição”
IF
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
Existe um atalho para o comando test:
[ ] # é preciso ter um espaço depois e um antes dos colchetes.
CASE
Para não precisarmos concatenar milhares de ifs, utilizamos o case:
Não há ;; no último grupo
Para fechar o case, usamos “esac”
Podemos usar wildcards nos padrões de grupos. ex.: [1-4], ?, ??,3|4, ?0|?5, [1234] etc
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
FOR
Um comando muito útil para utilizar o for é o seq, que gera sequências de números:
for numero in um dois três quatro cinco
do
echo "Contando: $numero"
done
for num in $(seq 10)
do
<...>
done
for num in $(seq 6 10)
do
<...>
done
for num in $(seq 0 2 10)
do
<...>
done
FOR
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 par
do
echo "Parâmetro: $par"
done
FOR
Podemos ainda usar uma sintaxe parecida com a do C.
for arq in *
do
let i++;
echo “$i -> $arq”
done
Ou outra forma de for
1 -> arquivo1.txt
2 -> arquivo2.sh
3 -> arquivo3.bla
4 -> arquivo4.doc
etc...
for ((i=0 ; i<=9 ; i++))
do
echo -n “$i “
done
for (( ; i<=9 ; ))
do
let i++;
echo -n “$i “
done
Break e Continue
break: para 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
Para um loop infinito (saindo com break):
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
Utilizando um contador com o while:
Until
Igual ao while, mas o teste é feito após os comandos serem executadosuntil ! who | grep pet
do
sleep 60
done
echo -n “usuário pet foi embora!!”
echo “às $(date “%H:%Mh”)”
I=0; until [ $i -eq 9 ]
do
echo -n “$i ”
let i++; done
$ ./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!!
$./testeuntil
0 1 2 3 4 5 6 7 8
$IFS (Inter Field Separator)
Todos parâmetros (assim como a lista do for) são delimitados pelo conteúdo da variável $IFS, que por default é o espaço em branco. Podemos trocar o valor dessa variável para fazermos leituras mais interessantes!
Lembre-se sempre de salvar o valor original de $IFS antes para poder restaurá-lo depois, pois isso afeta ofuncionamento de outros comandos.
$IFS
$ grep julio /etc/passwd
julio:x:500:544:Julio C. Neves -
7070:/home/julio:/bin/bash
$ oIFS="$IFS" # Salvando IFS
$ IFS=:
$ grep julio /etc/passwd | read lname lixo uid
gid coment home shell
$ echo -e "$lname\n$uid\n$gid\n$coment\n
$home\n$shell" julio
500
544
Julio C. Neves - 7070
/home/julio
/bin/bash
$ IFS="$oIFS" # Restaurando IFS
read extras
Opções:
-p prompt # Escreve o prompt antes defazer a leitura.
-n num # Lê até num caracteres.
-t seg # Espera seg segundos para que a leitura seja concluída.
-s # O que está sendo teclado não aparece na tela.
read – Leitura de arquivos
Podemos fazer a leitura de arquivos basicamente de duas formas:
O while termina quando read alcança um EOF -> leitura mal-sucedida!
while read Linha
do
echo $Linha
done < arquivo
cat arquivo |while read Linha
do
echo $Linha
done
read – leitura de arquivos
Exemplo
#!/bin/bash
# read_arq.sh
# Descrição: Mostra o conteudo do script
($0) na tela
cat $0 | # Passando o arq. do script ($0)
para o while por pipe
while read Linha
do
echo "$Linha"
done #< $0 # Passando o conteudo do
script para o while por redirecionamento
tput
Comando usado para formatar a tela!
Possui inúmeras opções, abaixo seguem algumas:
cup lin col # Posiciona o Cursor
bold # Negrito.
smul # Sublinhado.
blink # Piscando.
sgr0 # Restaura para formato padrão.
reset # Limpa e restaura.
tput
Mais opções:lines # Quantidade de linhas da tela.
cols # Quantidade de colunas da tela.
el # Apaga a linha a partir do cursor.
ed # Apaga a tela a partir do cursor.
il n # Insere n linhas a partir do cursor.
dl n # Remove n linhas a partir do cursor.
ech n # Apaga n chars a partir do cursor.
sc # Salva a posição do cursor.
rc # Restaura para posição do último sc.
tput
Exemplo: Hello World centralizado na tela.
#!/bin/bash
Colunas=`tput cols` # Salvando quantidade colunas
Linhas=`tput lines` # Salvando quantidade linhas
Linha=$((Linhas / 2)) # Qual eh a linha do meio da tela?
Coluna=$(((Colunas - 11) / 2)) # Centrando a mensagem.
tput sc # Salvando posicao do cursor
tput cup $Linha $Coluna # Posicionando para escrever
tput rev # Video reverso .
echo Hello World
tput sgr0 # Restaura video ao normal
tput rc # Restaura cursor aa posição original .
OBS: ${#var} retorna o tamanho da variável.
Bibliografia mínima da aula
Lista completa de referências será dada ao final do curso:http://twiki.softwarelivre.org/bin/view/TWikiBar/WebHome
http://www.rootlinux.com.br/documentos/downloads/apostila-introducao-shell.pdf
http://olinux.uol.com.br/artigos/258/1.html
http://www.devin.com.br/eitch/shell_script/