Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introduo
O que so os shell scripts? Shell scripts so conjuntos de comandos armazenados
em um arquivo texto que so executados seqencialmente. Nesta primeira parte,
faremos uma introduo sobre o shell, o formato desses arquivos e variveis de
ambiente.
O que Shell
Shell, ou interpretador de comandos, o programa disparado logo aps o login
responsvel por "pegar" os comandos do usurio, interpret-los e executar uma
determinada ao.
Por exemplo, quando voc escreve no console "ls" e pressiona <enter>, o shell l
essa string e verifica se existe algum comando interno (embutido no prprio shell)
com esse nome. Se houver, ele executa esse comando interno. Caso contrrio, ele
vai procurar no PATH por algum programa que tenha esse nome. Se encontrar, ele
executa esse programa, caso contrrio, ele retorna uma mensagem de erro. Para
cada terminal ou console aberto, existe um shell sendo executado. Quando voc
entra no seu Linux, ele apresenta o login, para digitar o usurio e a senha. Ao
digitar um par usurio/senha correto, o Linux abre automaticamente um shell, que
vai ficar esperando seus comandos. Veja o exemplo abaixo:
Welcome to Linux Slackware 7.1 kernel 2.2.16.
matrix login: neo
Password:
Linux 2.2.16.
Last login: Mon Sep 25 10:41:12 -0300 2000 on tty1.
No mail.
neo@matrix:~$
Essa ultima linha o shell. Se voc der o comando "ps", vai ver que um dos
programas rodando o seu shell:
neo@matrix:~$ ps
PID TTY TIME CMD
164 tty2 00:00:00 bash
213 tty2 00:00:00 ps
neo@matrix:~$
Ou seja, o shell utilizado nesse console o bash, que est rodando com PID 164.
Existem diversos tipos de shell: bash, csh, ksh, ash, etc. O mais utilizado
atualmente o bash (GNU Bourne-Again SHell). Por isso, tomaremos ele como
referncia.
Resumindo essa seo, importante saber que para cada terminal ou console
aberto, tem-se um shell rodando. Assim, se voc tem 3 xterms abertos na interface
grfica, vai ter um shell para cada xterm.
Ao executar o shell script, o shell atual (no qual voc deu o comando) abre um novo
shell para executar o script. Assim, os scripts so executados em um shell prprio (a
menos que se especifique, ao chamar o script, para execut-lo no shell atual). Isso
ser importante quando formos tratar de variveis de ambiente.
Variveis do ambiente
Uma varivel onde o shell armazena determinados valores para utilizao
posterior.
Toda varivel possui um nome e um valor associado a ela, podendo ser este ltimo
vazio. Para listar as variveis atualmente definidas no shell digite o comando set .
Para se definir uma varivel, basta utilizar a sntaxe: nome_da_varivel=valor .
Por exemplo, queremos definir uma varivel chamada "cor" com o valor de "azul":
neo@matrix:~$ cor=azul
Para utilizar o valor de uma varivel, s colocar um sinal de "$" seguido do nome
da varivel - o shell automaticamente substitui pelo valor da varivel:
neo@matrix:~$ echo cor
cor
neo@matrix:~$ echo $cor
azul
Em alguns casos, aconselhvel colocar o nome da varivel entre chaves ({}). Por
exemplo, se eu quero imprimir "azul-escuro", como faria? Simplesmente echo
$cor-escuro ?? No funcionaria, pois o bash vai procurar uma varivel de nome
"cor-escuro". Portanto, temos que colocar o nome "cor" entre chaves para delimitar
o nome da varivel:
neo@matrix:~$ echo ${cor}-escuro
azul-escuro
Algumas variveis j so predefinidas no shell, como o PATH, que, como foi dito
antes, armazena o caminho dos programas. Por exemplo, a minha varivel PATH
contm:
neo@matrix:~$ echo $PATH
/usr/local/bin:/usr/bin: /bin: /usr/X11R6/bin: /usr/openwin/bin:
/usr/games: /opt/kde/bin: /usr/share/texmf/bin: /etc/script
Ou seja, quando digito um comando, como "ls", o shell vai comear a procur-lo
em /usr/local/bin, se no encontr-lo, vai procurar em /usr/bin e assim por diante.
Repare que os diretrios so separados por um sinal de dois pontos (:).
importante destacar que o shell possui vrias variveis pr-definidas, ou seja, que
possuem um significado especial para ele, entre elas: PATH, PWD, PS1, PS2, USER e
UID.
Assim, quando iniciamos um novo shell (ao executar o nosso script), essas variveis
especiais so "herdadas" do shell pai (o que executou o shell filho). Outras variveis
definidas pelo usurio, como a varivel "cor" no so passadas do shell pai para o
filho.
Quando o script terminar, o seu shell (shell filho) simplesmente desaparece e com
ele tambm as suas variveis, liberando o espao ocupado na memria.
Concluso
Na prxima aula do nosso curso de shell script iremos aprender alguns comandos
especiais para tornar nossos script mais poderosos, fazendo coisas mais elaboradas
do que apenas executar programas seqencialmente. Entre eles, podemos destacar
os comandos de lao, como "if", "for", "while", "case" etc.
Introduo
Na aula de hoje vamos falar sobre execuo de programas em primeiro plano (fg foreground) e em segundo plano (bg - background), redirecionamento de sadas e
tambm sobre os cdigos de escape dos programas.
Somente aps isso vamos ter a linha de comando de volta para podermos continuar
trabalhando.
E se pudssemos dizer ao shell para executar um programa e nos retornar a linha de
comando sem ficar esperando o tal programa terminar? Seria muito melhor, no? Em
alguns casos seria. E podemos fazer isso.
Uma maneira fcil colocar o sinal de & depois de um comando. No exemplo acima
ficaria:
neo@matrix:~$ cp arquivo1 arquivo2 &
[1] 206
neo@matrix:~$
Pronto, assim que teclarmos [enter], teremos a nossa linha de comando de volta e
mais duas informaes: "[1] 206".
A primeira informao ([1]) chama-se job. Ela identifica os programas que esto
sendo executados em bg (background). Por exemplo, se executarmos mais um
programa em bg enquanto este "cp" est sendo executado, o novo programa recebe
o job de nmero 2 ([2]) e assim por diante.
A segunda informao (206) o pid do programa, ou seja, o nmero de processo
que o kernel d a esse programa.
Mas a temos um pequeno problema. Digamos que voc queira trazer o programa
para fg, por exemplo, se o programa executado em bg for um tocador de mp3 e
voc quiser mudar a msica. Como fazemos? Usamos o comando fg [job] (intuitivo,
no ?) do bash. No exemplo acima, digamos que eu execute o "cp" em bg, mas
depois queira traz-lo para fg para cancel-lo. Seria simples:
neo@matrix:~$ cp arquivo1 arquivo2 &
[1] 206
neo@matrix:~$ fg 1
cp arquivo1 arquivo2
Assim trazemos o "cp" para primeiro plano e a linha de comando s retorna quando
ele terminar.
Opcional
Uma outra maneira de colocar um programa para rodar em bg utilizando um
truque do bash (no sei se esta opo est disponvel em outros shells).Digamos que
voc execute o comando "cp" e esquea de colocar o sinal "&". E a? Tem que ficar
esperando acabar ou cancelar o comando? No, podemos teclar: Ctrl + Z.
Ao fazer isso, paramos a execuo do programa. Ento s dar o comando bg [job]
(intuitivo tambm, n?):
neo@matrix:~$ cp arquivo1 arquivo2
* aqui teclamos Ctrl + Z *
[1]+ Stopped cp -i arquivo1 arquivo2
neo@matrix:~$ bg 1
[1]+ cp -i arquivo1 arquivo2 &
neo@matrix:~$
Quando teclamos o Ctrl + Z, o bash nos diz que o job 1 foi parado ([1]+ Stopped) e
quando executamos "bg 1" ele nos diz que o comando voltou a ser executado, mas
em bg (repare o sinal de "&" no final da linha): [1]+ cp -i arquivo1 arquivo2 &.
Redirecionamento de sadas
Muitos programas que executamos geram sadas no console, ou sejam, emitem
Cdigos de Escape
Toda vez que executamos um programa em Unix, ele retorna um cdigo de escape
ao finalizar. Esse cdigo reflete a condio em que o programa finalizou. Se ocorreu
tudo certo e o programa terminou normalmente, ele retorna 0. Se ocorreu algum
problema, o programa retorna um cdigo diferente de 0, geralmente variando com o
problema ocorrido.
Esse cdigo de retorno extremamente importante em shell script, pois assim que
testamos se uma certa ao ocorreu bem ou teve problemas.Esse cdigo
armazenado pelo bash numa varivel chamada "?" (isso mesmo, somente o sinal de
interrogao ;-)).
Por exemplo, vamos executar um "ls" em um diretrio que existe e ver o cdigo de
retorno:
neo@matrix:~$ ls /boot
System.map boot.0300 boot.b boot_message.txt chain.b config map os2_d.b
neo@matrix:~$ echo $? 0
neo@matrix:~$
Ou seja, o "ls" foi executado normalmente, retornando 0. Agora vamos execut-lo
num diretrio que no existe:
neo@matrix:~$ ls /diretorio_invalido
/bin/ls: /diretorio_invalido: Arquivo ou diretrio no encontrado
neo@matrix:~$ echo $?
1
neo@matrix:~$
Como esperado, obtemos o retorno de erro 1.
Alguns programas tem muitos cdigos de retorno. Por exemplo, os cdigos de
retorno do "pppd" vo at o 19. Assim possvel saber porque ele foi finalizado. Se
voc colocar uma senha errada no pppd e tentar conectar, ele vai terminar com o
cdigo 19.
man pppd
...
17 The PPP negotiation failed because serial loopback was detected.
18 The init script failed (returned a non-zero exit status).
Concluso
Como todos os programas tem que terminar com um cdigo de retorno que tenha
algum significado, nossos shell scripts tambm tero que finalizar indicando o que
aconteceu, se ocorreu tudo bem ou se ouve erro. Mas isso discutiremos melhor mais
pra frente.
O importante aqui saber que todos os programas terminam com um cdigo de
retorno, os quais usaremos nos nossos scripts para testar o trmino dos programas.
Introduo
Nesta terceira parte do nosso curso de shell script, vamos tratar de
"condicionais".Condicionais so comandos que avaliam uma expresso. Se ela for
verdadeira, uma determinada rotina executada. Caso contrrio, outra rotina pode
ser executada.
O famoso "if"
O bash nos oferece, entre outros, o comando IF (ele um comando embutido no
bash e no um programa como o "ls", o "cp" etc.). A forma mais simples de
representar uma condicional utilizando o IF, da seguinte forma bsica:
if [condio];
then comandos1;
else comandos2;
fi;
Se [condio] for verdadeira, os comandos1 so executados. Se for falsa, os
comandos2 so executados.Mas para o IF, o que uma condio verdadeira ou uma
falsa?
Como foi explicado na aula anterior, TODO comando em Unix tem um cdigo de
retorno. Geralmente o cdigo "0" (zero) significa que o comando foi executado
perfeitamente e terminou bem. Cdigos maiores que zero significam que alguma
O comando "test"
Bom, aprendemos que o IF avalia a cdigo de retorno de um comando. Mas muitas
vezes, para no dizer a maioria, ns queremos avaliar "expresses", ou seja,
verificar se uma varivel igual a outra, se ela esta vazia etc.
Para isso, ns temos outro comando chamado "test" (intuitivo o nome, no?). Ele
funciona da seguinte maneira: test [expresso].
O test pode testar operaes de trs tipos: strings, arquivos e aritmticas.
Expresses usando strings:
O test pode apenas comparar strings, ou seja, verificar se uma igual a outra, e
verificar se uma string vazia ou no. Vamos aos exemplos para facilitar o
entendimento:
neo@matrix:~$ test "a" = "a"
neo@matrix:~$ echo $?
0
neo@matrix:~$
neo@matrix:~$
1
neo@matrix:~$
neo@matrix:~$
0
Aqui comparamos a string "a" com "b". Como era de se esperar, o primeiro retornou
verdadeiro (zero), pois a = a e o segundo retornou falso. No terceiro, o smbolo "!="
significa "diferente".
neo@matrix:~$
neo@matrix:~$
1
neo@matrix:~$
neo@matrix:~$
0
neo@matrix:~$
neo@matrix:~$
0
neo@matrix:~$
neo@matrix:~$
1
test -z "neo"
echo $?
test -z ""
echo $?
test -n "neo"
echo $?
test -n ""
echo $?
test -e /vmlinuz
echo $?
test -d /vmlinuz
echo $?
test -e /usr
echo $?
test -d /usr
echo $?
test /usr -nt /vmlinuz
echo $?
-N arquivo - Verdadeiro se arquivo foi modificado desde a ultima vez que foi lido.
Expresses Aritmticas
Expresses aritmticas consistem com comparar dois nmeros, verificando se so
iguais, ou se o primeiro maior que o segundo etc.
Infelizmente no podemos apenas utilizar os smbolos conhecidos para igual (=),
maior que (>), menor que (<) etc. Temos que usar operadores reconhecidos pelo
"test". Assim, no podemos fazer: "test 1 = 1", devemos utilizar o operador "-eq"
(equal): "test 1 -eq 1". A seguir, temos uma lista dos operadores:
Alguns exemplos:
neo@matrix:~$
neo@matrix:~$
0
neo@matrix:~$
neo@matrix:~$
1
neo@matrix:~$
neo@matrix:~$
0
neo@matrix:~$
neo@matrix:~$
0
test 1 -lt 2
echo $?
test 1 -gt 2
echo $?
test 2 -gt 1
echo $?
test 2 -ge 2
echo $?
Para finalizar, vamos fazer duas consideraes. A primeira de que o comando "test"
pode ser substituido por um par de colchetes [ ]. Assim, o comando test "a" = "b"
pode ser escrito como [ "a" = "b" ] .
Essa segunda nomenclatura fica mais fcil e simples, principalmente quando
estamos utilizando IF:
if [ -e /vmlinuz ]; mais intuitivo e simples que if test -e /vmlinuz; .
A segunda considerao que, obviamente, podemos utilizar variveis no lugar dos
argumentos (caso contrrio, ficaria difcil utilizar comandos de condicionais em shell
script). Assim, se tivermos duas variaveis, valor1=5 e valor2=8:
[ "$valor1" = "$valor2" ] , [ "$valor1" -lt "$valor2" ] etc.
importante colocarmos os valores entre aspas duplas ("), pois assim o bash pode
substituir o que se encontra dentro dessas aspas. Se colocarmos entre aspas simples
('), impedimos o bash de alterar o que se encontra dentro delas. Se no utilizarmos
as aspas duplas, vamos ter problemas, principalmente ao trabalharmos com string.
Por exemplo, queremos comparar dois nomes, que se encontram em duas
variaveis:nome1="fulano de tal" e nome2="ciclano".Montando nossa expresso
condicional: [ "$nome1" = "$nome2" ].O bash ir expandir isso para: [ "fulano de
tal" = "ciclano" ], ficando claramente definidos o primeiro e o segundo argumento.
Agora, se no usarmos aspas: [ $nome1 = $nome2 ]. O bash ir expandir isso para:
[ fulano de tal = ciclano ]. Perceba que os argumentos se misturam e o bash no vai
saber o que comparar.Por isso importante colocarmos os argumentos entre aspas
duplas.
Concluso
Resumindo, aprendemos na aula de hoje como utilizar comandos condicionais. Isso
ser fundamental nas proximas aulas, onde iremos tratar os comandos de lao,
como o while. No perca!
Nesta aula vamos aprender sobre comandos de lao como o while, for, case e select.
Eles nos permitem executar alguns comandos diversas vezes, sob determinadas
condies e at montar menuzinhos para interagir com o usurio.
While
Este provavelmente o comando de lao mais utilizado em programao. Seu
entendimento simples. Ele testa uma condio (como faz o IF) e executa um
conjunto de comandos se esta condio for verdadeira. Aps a execuo desses
comandos, ele torna a testar a condio e se esta for verdadeira, ele reexecuta os
comandos e assim por diante.
Sua sintaxe a seguinte:
while [ condio ];
do
comando 1;
comando 2;
...
done;
Analisando:
Na primeira linha temos a condio: enquanto o valor da varivel x ( $x ) for menor-
igual ( -le ) a 10, faa: mostre "Execuo nmero: " e o valor de x ($x). Faa x = x
+ 1. Isso no bash feito pelo comando $(( )). Ele realiza operaes algbricas com
variveis. No caso acima, estamos somando x + 1 e colocando o resultado no
prprio x.
Preste ateno, que as linhas do While precisam de um ";" para terminar, exceto a
que contm o "do", pois ele representa o comeo do bloco de comandos.
Quando executamos o script acima, temos uma contagem de 1 at 10:
neo@matrix:~$ x=0; while [ "$x" -lt 10 ]; do x=$((x+1)); echo
"Execuo nmero: $x"; done;
Execuo nmero: 1
Execuo nmero: 2
...
Execuo nmero: 10
neo@matrix:~$
O While tem muita utilidade em programao, mas fica difcil dar exemplos usando
somente ele, pois geralmente ele est associado a execuo de outros programas e
rotinas mais complexas.
Eu costumo usar ele, por exemplo, quando quero que o napster fique tentando
conectar, pois quando ele vai tentar conectar o servidor e no consegue, ele
simplesmente termina. Ai eu coloco o while testando a cdigo de retorno dele
(lembram da varivel $? ) e enquanto estiver diferente de zero (o napster terminou
com erro), ele fica executando o napster:
? = 1; while [ "$?" -ne "0" ]; do ./nap; done;
O comando "? = 1" tenta atribuir 1 a varivel ?. Isso provoca um erro, pois a
varivel ? somente de leitura. Isso necessrio para que ? Contenha algo diferente
de 0, pois seno o While no executa a primeira interao.
For
O for semelhante ao while usado como um contador. necessrio fornecer uma
lista de nomes e ele executa os comandos para cada nome na lista. Parece meio
confuso, mas simples. Veja a sintaxe:
for <var> in <lista>;
do
comandos
done;
"seq 10" gera uma seqncia de 1 at 10. Assim, podemos us-lo no for:
for x in $(seq 10); do echo $x; done;
No local de <lista> nos colocamos "*.mp3". Isso diz ao bash para expandir
(transformar) ele na lista de arquivos terminados com ".mp3". Seno houver
nenhum arquivo com essa terminao, o bash no faz nada, ficando para o for a
string "*.mp3". Por isso precisamos do IF para testar se o arquivo existe.
Experimente no seu sistema.
echo *.mp3
Vai mostrar os arquivos no diretrio atual com terminao mp3, mas sem quebra de
linha entre eles, ou seja, um nome aps o outro. Se no houver nenhum arquivo
com terminao mp3, ele apenas vai mostrar "*.mp3".
Bom, voltando ao For, ele vai atribuir a "x" cada nome na lista de arquivos com
terminao ".mp3" e executar os comandos seguintes.
Primeiro ele testa para ver se o arquivo existe ( if [ -e "$x" ]; ), e se existir,
renomeia ele para o seu prprio nome acrescido de ".bak" ( ${x}.bak ).
Resumindo, o For faz isso: voc fornece uma lista de nomes para ele e ele vai
atribuindo esses nomes, em ordem e um por vez, varivel <var> e executa os
comandos entre o "do" e o "done;".
Case
O Case est mais para um comando condicional do que para comando de lao, visto
que ele no executa "loopings" como o While e o For.
Ele geralmente utilizado como substituio de vrios IFs.. Um exemplo clssico e
muito utilizado quando voc precisa testar um parmetro fornecido na linha de
comando. O Case utilizado desta forma em scripts de inicializao de servios do
sistema.
Vou mostrar a sintaxe em seguida um script que inicialize/ reinicialize ou pare algum
servio (como o sendmail, apache, bind, etc).
Sintaxe:
case <parmetro> in
<opo 1>)
<comandos 1>
;;
[opo 2] )
*)
<comandos 2>
;;
< comandos se no for nenhuma das
opes >
;;
esac
'restart' )
'stop' )
*)
O Case serve exatamente para isso, ou seja, evitar o teste de vrios Ifs. No caso
acima, teramos que utilizar 3 Ifs. Mesmo se o primeiro j fosse verdadeiro, o bash
iria testar o segundo e o terceiro, ou seja, ia perder tempo desnecessariamente. J
no case isso no acontece. Aps entrar em uma opo e executar seus comandos,
ele j pula fora do case sem testar as outras opes abaixo.
Select
O Select um comando de lao que nos permite mostrar um pequeno menuzinho de
opes para o usurio. Cada opo possui um nmero e para escolher, o usurio
digita o nmero correspondente a opo desejada. Vejamos a sintaxe a seguir:
select <var> in <lista de opes>;
do
<comandos>
done;
Como disse acima, o select vai mostrar as opes contidas em <lista de opes>,
uma por linha, com um nmero na frente e espera que o usurio digite a opo
Iniciando o
Reinicializando o
Parando o servio..."
Script encerrado."
Opo
1) Iniciar
2) Reiniciar
3) Parar
4) Sair
#? 5
1) Iniciar
2) Reiniciar
3) Parar
4) Sair
#? 4
Opo invlida!
Script encerrado.
neo@matrix:~/test$
Bom pessoal, acho que por hoje s. ;-) Espero que vocs tenham pego a idia de
como funciona comandos de laos. Pelos menos sabendo a utilidade, sintaxe e como
funcionam, quando surgir a necessidade, vocs j vo saber quais ferramentas usar.
Nesta aula teremos um breve tutorial sobre o Grep. Ele no somente um dos
comandos mais teis, mas o seu domnio abre portas para dominar outros poderosos
comandos, como o sed (que trataremos na prxima aula) , awk, perl, etc.
Eu fiz uma adaptao/ modificao de um tutorial que eu tenho, e por sinal
excelente, sobre o Grep e Expresses Regulares em ingls. Espero que tenha ficado
legal e vocs gostem.
Outro jeito de usar o grep atraves de pipe (lembram dos pipes?). Por exemplo:
ls | grep palavra
Lista todos os arquivos que contenham palavra em seu nome. Ou seja, a entrada do
grep uma lista de arquivos (gerada pelo ls) que ser filtrada, sendo impressas
somente as linhas que contenham palavra.
>grep b.g
big
bad bug
bigger
Note que boogy no casa, desde que "." significa "qualquer e apenas um caracter".
Para significar strings arbitrrias utilizamos "*", que funciona da seguinte maneira:
"A expresso consistindo de um caracter seguido por um * casa com qualquer
nmero (inclusive zero) de repeties desse caracter. Em particular, ".*" significa
qualquer string."
Para compreendermos vamos a mais exemplos:
>cat file
big
bad bug
bag
bigger
boogy>grep b.*g file
big
bad bug
bag
bigger
boogy>grep b.*g. File
bigger
boogy>grep ggg* file
bigger
Desde que "grep 'hello.gif' file" iria resultar linhas contendo: hello-gif , hello1gif ,
helloagif , etc.
Ou seja, a barra invertida remove o significado especial do ".", passando esse a
significar um simples ponto ao invs de um coringa.
Agora vamos passar para expresses agrupadas, a fim de encontrar um jeito de criar
uma expresso que case com Frederic ou Fred. Primeiro vamos comear com o
operador "?":
"Uma expresso consistindo de caracter seguido por uma interrogao escapada ( \?
) casa com zero ou uma instncia daquele caracter".
Exemplo:
"bugg\?y" casa com o seguinte: bugy , buggy mas no com
bugggy
neo@matrix:~$ echo bugy | grep "bugg\?y"
bugy
neo@matrix:~$ echo bugggy | grep "bugg\?y"
neo@matrix:~$
Note que temos que tomar cuidado quando nossas expresses contm espaos em
branco. Quando eles aparecem, precisamos colocar a expresso entre aspas, para
que o shell no interprete mal nosso comando. Para o exemplo acima:
grep "Fred\(eric\)\? Smith" file
Procura no meu inbox por mensagens de uma pessoa em particular (no caso, Alex).
Esse tipo de expresso regular extremamente til e filtros de e-mail, como o
procmail, utilizam isso para fazerem tudo.
Isso ou Aquilo: Procurando uma coisa OU outra:
"A expresso consistindo de duas expresses separadas pelo operador OU \| casa
linhas contendo uma das duas expresses"
Note que voc DEVE colocar a expresso dentro de aspas simples ou duplas:
grep "cat\|dog" file casa com linhas contendo a palavra "cat" ou a
palavra "dog"
grep "I am a \(cat\|dog\)" casa com linhas contendo a string "I am
a cat" ou a string "I am a dog".
Note que o sinal de $ perde seu sentido se tiver caracteres depois dele, do mesmo
jeito que o sinal ^ perde seu sentido se tiver caracteres antes dele. Os colchetes [ ]
comportam-se um pouco diferente. A baixo segue as regras para eles:
O colchete direito ( ] ) perde seu sentido especial se colocado no comeo de uma lista, por
exemplo: "[]12]" casa com ] , 1, or 2.
Um hfen perde seu significado especial se colocado por ltimo. Assim, [15-] casa com 1, 5 ou -
A maioria dos caracteres especiais perdem seu significado especial se forem colocados dentro de
colchetes.
Aspas:
Em primeiro lugar, aspas simples so mais seguras de usar porque elas protegem
suas expresses regulares de serem alteradas pelo bash (como foi visto nas aulas
anteriores). Por exemplo, grep "!" file vai produzir um erro, j que o shell pensa que
"!" est se referindo ao comando de histrico do shell, enquanto grep '!' file funciona
perfeitamente.
Quando voc deve usar aspas simples ? A resposta : se voc precisa usar variveis
do shell, use aspas duplas. Caso contrrio, use aspas simples. Por exemplo:
grep "$HOME" file
Procura em file pelo nome do seu diretrio pessoal, enquanto grep '$HOME' file
procura pela string $HOME.
Nesta aula continuaremos nosso tutorial, desta vez falando sobre o Sed. Vale
lembrar que este tutorial dar uma breve introduo ao Sed, ajudando os iniciantes
a entender como ele funciona. Portanto muitos comandos mais complexos sero
omitidos, j que seria necessrio um livro inteiro para ensinar tudo sobre o Sed. Mas
no se preocupem, ensinaremos o suficiente sobre ele para utilizao em shell script.
Resumo de RegExp
Vamos a um resumo sobre as expresses regulares, explicadas na aula anterior e agora aplicadas ao Sed:
^
casa com o comeo de linha
$
casa com o fim de linha
.
casa com qualquer caracter simples
(apenas um)
(caracter)*
casa com qualquer ocorrncia, em qualquer
quantidade, de (caracter)
(caracter)?
casa com zero ou uma ocorrncia de
(caracter)
[abcdef]
Casa com qualquer caracter dentro dos [ ]
(neste caso, a b c d e ou f), faixas de caracteres como [a-z]
so
permitidas.
[^abcdef]
Casa com qualquer caracter NO
includo em [] (neste caso, qualquer caracter que
no seja a b c d e ou f)
(caracter)\{m,n\}
casa com m-n repeties de
(caracter)
(caracter)\{m,\}
casa com m ou mais repeties de
(caracter)
(caracter)\{,n\}
casa com n ou menos (tambm zero)
repeties de (caracter)
(caracter)\{n\}
casa com exatamente n repeties
de (caracter)
\(expresso\)
operador de grupo.
\n
Backreference - casa com o
n-simo grupo
expresso1\|expresso2
Casa com expresso1 ou
expresso2. Funciona com o GNU sed, mas essa
caracterstica pode no funcionar com outros Seds.
Caracteres Especiais
Os caracteres especiais no Sed so os mesmo do Grep, com uma diferena: a barra
normal / um caracter especial no sed. A razo disso ficar clara mais para frente
quando estudarmos os comandos do sed.
Ns no vamos discutir todas as flags ainda. A nica que usamos abaixo a "g", que
OK, ento o que aconteceu? Primeiro o sed leu a linha do arquivo "file" e executou:
s/cachorros/gatos/g
que produziu o seguinte texto:
Eu tenho trs gatos e dois gatos
e ento o segundo comando foi executado na linha j
editada e resultou:
Eu tenho trs elefantes e dois elefantes
Ns atualmente damos um nome para o texto (geralmente uma linha) que o sed leu
e est processando (editando): ele chama-se "pattern space" (uma boa traduo
seria "rea de edio").
O sed l da entrada padro e joga na sua rea de edio, executando nela uma
seqncia de comandos de edio e ento ele escreve o resultado na sada padro.
Ento, o sed pode ler do arquivo ou da entrada padro, e os comandos podem ser
especificados em um arquivo de script ou na linha de comando. Esse arquivo,
chamado sedscript.sed um arquivo que contm todos os comandos do sed, ao
invs de serem especificados na linha de comando. Esses sed's scripts so teis
quando precisamos de um processamento de texto mais complexo e refinado.
Note o seguinte: se os comandos so lidos de um arquivo (sed script), espaos em
branco podem ser fatais. Eles podem fazer o script falhar sem explicao aparente.
Eu recomendo editar os arquivos de comandos do sed com um editor como o VIM
que pode mostrar o final da linha e voc pode ver se existem espaos em branco
entre os comandos e o fim da linha.
Comando de Substituio
O formato para o comando de substituio o seguinte:
[endereo1[,endereo2]]s/procura/substituto/[flags]
sucesso
w arquivo imprime a "rea de edio" para arquivo
se ocorrer uma substituio com sucesso
O comando de Deleo
A sintaxe desse comando muito simples. Ai vai:
[endereo1[,endereo2]]d
Isto deleta o contedo da "rea de edio" (se esta casar com os endereos
fornecidos). Todos os comandos seguintes sero pulados (j que no a nada a fazer
com uma rea de edio em branco) e uma nova linha ser lida e jogada na rea de
edio e todo o processo se repete.
Exemplos:
Exemplo 1:
>cat file
O gato preto foi caado por um cachorro marrom.
>sed -e 's/preto/branco/g' file
O gato branco foi caado por um cachorro marrom.
Exemplo 2:
>cat file
O gato preto foi caado por um cachorro marrom.
O gato preto no foi caado por um cachorro marrom.
>sed -e '/no/s/preto/branco/g' file
O gato preto foi caado por um cachorro marrom.
O gato branco no caado por um cachorro marrom.
Neste caso, a substituio aplicada somente a linhas que casam com a expresso
regular "/no/". Portanto, ela no aplicada a primeira linha, pois esta no contem a
palavra "no".
Exemplo 3:
>cat file
linha 1 (um)
linha 2 (dois)
linha 3 (trs)
Exemplo 3a:
>sed -e '1,2d' file
linha 3 (trs)
Exemplo 3b:
>sed -e '3d' file
linha 1 (um)
linha 2 (dois)
Exemplo 3c:
>sed -e '1,2s/linha/LINHA/' file
LINHA 1 (um)
LINHA 2 (dois)
linha 3 (trs)
Exemplo 3d:
>sed -e '/^linha.*um/s/linha/LINHA/' -e '/linha/d' file
LINHA 1 (um)
3a : Este foi bem simples: Ns apenas deletamos as linhas de 1
at 2
3b : Isto tambm foi simples: Ns deletamos a linha 3.
3c : Neste exemplo, ns fizemos uma substituio nas
linhas 1 at 2.
3d : Agora este mais interessante e merece algumas
explicaes.
Exemplo 4:
>cat file
ol
Este texto ser cortado
ol (tambm ser retirado)
ReTiRaDo Tambm!!!
tchau
(1) Este texto no foi apagado
(2) nem este ... ( tchau )
(3) nem este
ol
mas este ser
e este tambm
e a menos que ns encontremos outro tch*u
cada linha at o final do texto ser apagada
>sed -e '/ol/,/tchau/d' file
(1) Este texto no foi apagado
(2) nem este ... ( tchau )
(3) nem este
deleo para nenhuma linha at encontrar novamente a expresso "ol". Desde que
a expresso "tchau" no ocorre mais em nenhuma linha subseqente, o comando de
deleo aplicado at o final do texto.
Resumindo, simples: Quando ele encontra o primeiro endereo ("ol") ele passa a
executar os comandos at encontrar o segundo endereo ("tchau") ou o fim do
texto. E isso se repete at acabar o texto.
Exemplo 5:
>cat file
http://www.kernel.org/
>sed -e
's@http://www.kernel.org@http://www.metalab.unc.edu@' file
http://www.metalab.unc.edu/
s/.*\($X\)/\1/
q
}" $1
Uma nota importante: tentador pensar que:
s/\($X\).*/\1/
s/.*\($X\)/\1/
redundante e tentar encurta-la para:
s/.*\($X\).*/\1/
Mas isto no funciona. Por que? Suponha que temos a linha:
word1 word2 word3
Ns no temos como saber se $X vai casar com word1, word2 ou word3, ento
quando ns citamos ele (\1), ns no sabemos quais dos termos est sendo citado.
O que est sendo usado para certificar-se que no h problemas na correta
implementao, isto:
"O operador * guloso. Ou seja, quando h ambigidade sobre qual (expresso)*
pode casar, ele tentar casar o mximo possvel."
Ento neste exemplo, s/\($X\).*/\1/ , .* tenta engolir o mximo da linha possvel,
em particular, se a linha contm isso:
"word1 word2 word3"
Ento ns podemos ter certeza que .* casa com " word2 word3" e portanto $X seria
word1. No se preocupem se no entenderam muito bem este tpico. Ele
complicado mesmo e pouco usado. O importante entender como ele funciona, o
uso de regexp e do comando de substituio e deleo. Para maiores informaes
sobre o sed, d uma olhada na sua man page: "man sed"
Espero que vocs tenham gostado desse pequeno tutorial sobre sed. Como disse na
aula anterior sobre o Grip, praticando que se aprende a usar ele.
O fim...
Bom pessoal, acho que nosso curso termina por aqui. Claro que no deu pra cobrir
tudo sobre shell script, se no nosso curso no teria fim. Tentei abordar os topicos
mais importantes, de modo que vcs tenham uma boa noo de como funciona as
coisas no shell e possam dar os proprios passos. Desculpem se esqueci de falar
sobre alguma coisa que vocs estavam esperando. Como disse, estou a disposio
para resolver qualquer dvidas.
Abraos,
Alex Borro