<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>torradeira.net &#187; Shell Script</title>
	<atom:link href="http://torradeira.net/category/shell-script/feed/" rel="self" type="application/rss+xml" />
	<link>http://torradeira.net</link>
	<description>Milhares de dicas e tutoriais de informatica!</description>
	<lastBuildDate>Thu, 16 Sep 2010 23:42:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Faça exames e simulados aqui no Blog</title>
		<link>http://torradeira.net/faca-exames-e-simulados-aqui-no-blog/</link>
		<comments>http://torradeira.net/faca-exames-e-simulados-aqui-no-blog/#comments</comments>
		<pubDate>Tue, 31 Jul 2007 00:12:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Adm. Linux]]></category>
		<category><![CDATA[AdSense]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[Leis de Informática]]></category>
		<category><![CDATA[Licenças]]></category>
		<category><![CDATA[Modems]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Receitas de Bolo]]></category>
		<category><![CDATA[Samba]]></category>
		<category><![CDATA[Segurança]]></category>
		<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[warez]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://torradeira.net/faca-exames-e-simulados-aqui-no-blog/</guid>
		<description><![CDATA[Bem, inspirado por outros sites que contém simulados e exames decide fazer um nova área no blog destinada a exames e simulados, alguns úteis e outros nem tanto.. como este primeiro que fiz para testar a funcionalidade do plugin e aceitação da idéia no blog. Para acessar o primeiro exame clique aqui Na próxima semana [...]]]></description>
			<content:encoded><![CDATA[<p>Bem, inspirado por outros sites que contém simulados e exames decide fazer um nova área no blog destinada a exames e simulados, alguns úteis e outros nem tanto.. como este primeiro que fiz para testar a funcionalidade do plugin e aceitação da idéia no blog.</p>
<p>Para acessar o primeiro exame clique <a href="http://torradeira.net/exame-de-conhecimento-tecnico-sobre-o-wordpress/">aqui</a></p>
<p>Na próxima semana provavelmente segunda vou colocar já a disposição um simulado para quem deseja fazer a prova LPI 101, o exame será feito por um profissional da área que já fez a prova e passou se certificando na LPI 101.</p>
<p>Aos poucos e conforme pedidos vou colocando novos exames e simulados!</p>
<p>até</p>
<p>Daniel</p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/quer-fazer-um-simulado-para-as-provas-da-lpi/" rel="bookmark" class="crp_title">Quer fazer um Simulado para as provas da LPI</a></li><li><a href="http://torradeira.net/livro-para-estudar-para-certificacao-lpi-101-e-102/" rel="bookmark" class="crp_title">Livro para estudar para Certificação LPI 101 e 102</a></li><li><a href="http://torradeira.net/como-um-blogueiro-deve-saber-o-que-escrever/" rel="bookmark" class="crp_title">Como um blogueiro deve saber o que escrever</a></li><li><a href="http://torradeira.net/como-instalar-temas-e-plugins-no-seu-blog-wordpress/" rel="bookmark" class="crp_title">Como instalar temas e plugins no seu blog WordPress</a></li><li><a href="http://torradeira.net/6-plugins-para-aumentar-sua-produtividade/" rel="bookmark" class="crp_title">6 Plugins para aumentar sua produtividade</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/faca-exames-e-simulados-aqui-no-blog/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Curso de Shell &#8211; Aula 6</title>
		<link>http://torradeira.net/curso-de-shell-aula-6/</link>
		<comments>http://torradeira.net/curso-de-shell-aula-6/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 12:48:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://torradeira.net/curso-de-shell-aula-6/</guid>
		<description><![CDATA[por Alex Borro Nesta aula continuaremos nosso tutorial, desta vez falando sobre o Sed. Vale lembrar que este tutorial dará uma breve introdução ao Sed, ajudando os iniciantes a entender como ele funciona. Portanto muitos comandos mais complexos serão omitidos, já que seria necessário um livro inteiro para ensinar tudo sobre o Sed. Mas não [...]]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><em>por  Alex Borro</p>
<p>Nesta aula continuaremos nosso tutorial, desta vez  falando sobre o Sed. Vale lembrar que este tutorial dará uma breve introdução ao  Sed, ajudando os iniciantes a entender como ele funciona. Portanto muitos  comandos mais complexos serão omitidos, já que seria necessário um livro inteiro  para ensinar tudo sobre o Sed. Mas não se preocupem, ensinaremos o suficiente  sobre ele para utilização em shell script.<br />
</em>  <span id="more-103"></span><br />
<strong>Resumo de RegExp</strong></p>
<p>Vamos a um resumo sobre as expressões  regulares, explicadas na aula anterior e agora aplicadas ao Sed:</p>
<p>^                            casa com o começo de linha<br />
$                            casa com o fim de linha<br />
.                            casa com  qualquer caracter simples<br />
(apenas um)<br />
(caracter)*          casa com  qualquer ocorrência, em qualquer<br />
quantidade, de (caracter)<br />
(caracter)?            casa com zero ou uma ocorrência de<br />
(caracter)<br />
[abcdef]                 Casa com qualquer caracter dentro dos [ ]<br />
(neste caso, a b c d e  ou f), faixas de caracteres como [a-z]<br />
são<br />
permitidas.<br />
[^abcdef]             Casa com qualquer caracter NÃO<br />
incluído em [] (neste  caso, qualquer caracter que<br />
não seja a b c d e ou f)<br />
(caracter)\{m,n\}      casa com m-n repetições de<br />
(caracter)<br />
(caracter)\{m,\}        casa com m ou mais repetições de<br />
(caracter)<br />
(caracter)\{,n\}         casa com n ou menos (também  zero)<br />
repetições de (caracter)<br />
(caracter)\{n\}          casa  com exatamente n repetições<br />
de (caracter)<br />
\(expressão\)              operador de grupo.<br />
\n                                Backreference &#8211; casa com o<br />
n-ésimo grupo<br />
expressão1\|expressão2        Casa com expressão1 ou<br />
expressão2.  Funciona com o GNU sed, mas essa<br />
característica pode não  funcionar com outros Seds.</p>
<p><strong>Caracteres Especiais</strong></p>
<p>Os  caracteres especiais no Sed são os mesmo do Grep, com uma diferença: a barra  normal / é um caracter especial no sed. A razão disso ficará clara mais para  frente quando estudarmos os comandos do sed.</p>
<p><strong>Como funciona: Uma  breve introdução</strong></p>
<p>O Sed funciona assim: ele lê da entrada padrão,  uma linha de cada vez. Para cada linha, ele executa uma série de comandos de  edição e então a linha é escrita na saída padrão. Um exemplo que mostra como ele  funciona: Nós usamos o comando &#8220;s&#8221;, que significa  &#8220;substitute&#8221; (substituir) ou &#8220;search and replace&#8221; (procurar  e trocar). O formato é:</p>
<p>s/expressão-regular/texto-substituto/{flags}</p>
<p>Nós não vamos discutir todas as flags ainda. A única que usamos  abaixo é a &#8220;g&#8221;, que significa &#8220;substitua todas as  ocorrências&#8221;:</p>
<p>>cat file<br />
Eu tenho três  cachorros e dois gatos<br />
>sed -e &#8216;s/cachorros/gatos/g&#8217; -e  &#8216;s/gatos/elefantes/g&#8217; file<br />
Eu tenho três elefantes e dois  elefantes</p>
<p>OK, então o que aconteceu? Primeiro o sed leu a linha do  arquivo &#8220;file&#8221; e executou:</p>
<p>s/cachorros/gatos/g</p>
<p>que produziu o seguinte texto:</p>
<p>Eu tenho três gatos e dois gatos</p>
<p>e então o segundo comando foi executado na linha já<br />
editada e  resultou:</p>
<p>Eu tenho três elefantes e dois elefantes</p>
<p>Nós  atualmente damos um nome para o texto (geralmente uma linha) que o sed leu e  está processando (editando): ele chama-se &#8220;pattern space&#8221; (uma boa  tradução seria &#8220;área de edição&#8221;).</p>
<p>O sed lê da entrada  padrão e joga na sua área de edição, executando nela uma seqüência de comandos  de edição e então ele escreve o resultado na saída padrão.</p>
<p><strong>Comandos de Substituição e Deleção</strong></p>
<p>Primeiro, as maneiras mais  usuais do sed é a seguinte:</p>
<p>>sed -e &#8216;comando1&#8242; -e  &#8216;comando2&#8242; -e &#8216;comando3&#8242; arquivo<br />
>{comando shell}  | sed -e &#8216;comando1&#8242; -e &#8216;comando2&#8242;<br />
>sed -f  sedscript.sed arquivo<br />
>{comando shell} | sed -f sedscript.sed</p>
<p>Então, o sed pode ler do arquivo ou da entrada padrão, e os comandos  podem ser especificados em um arquivo de script ou na linha de comando. Esse  arquivo, chamado sedscript.sed é um arquivo que contém todos os comandos do sed,  ao invés de serem especificados na linha de comando. Esses sed&#8217;s scripts são  úteis quando precisamos de um processamento de texto mais complexo e refinado.</p>
<p>Note o seguinte: se os comandos são lidos de um arquivo (sed script),  espaços em branco podem ser fatais. Eles podem fazer o script falhar sem  explicação 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  espaços em branco entre os comandos e o fim da linha.</p>
<p><strong>Comando de  Substituição</strong></p>
<p>O formato para o comando de substituição é o  seguinte:</p>
<p>[endereço1[,endereço2]]s/procura/substituto/[flags]</p>
<p>As flags podem ser as seguinte:</p>
<p>n                troca a  n-ésima ocorrência (na linha) do<br />
texto &#8220;procura&#8221; por  &#8220;substituto&#8221;<br />
g                troca todas as ocorrências (na  linha) do<br />
texto &#8220;procura&#8221; por &#8220;substituto&#8221;<br />
p                 imprime a &#8220;área de edição&#8221; para a<br />
saída padrão se  ocorrer uma substituição com<br />
sucesso<br />
w arquivo   imprime a &#8220;área  de edição&#8221; para arquivo<br />
se ocorrer uma substituição com sucesso</p>
<p>Se nenhuma flag for especificada, somente a primeira ocorrências na linha é  substituída. Note que nós quase sempre usamos o comando &#8220;s&#8221; ou com a  flag &#8220;g&#8221; ou sem nenhuma flag.</p>
<p>Se um endereço é dado, então  a substituição é aplicada a linhas que contenham aquele endereço. Um endereço  pode ser ou uma expressão regular dentro de barras normais /regexp/ , ou um  número de linha. O símbolo $ pode ser usado no lugar do número da linha  para denotar a última linha.</p>
<p>Se dois endereços são fornecidos,  separados por uma vírgula, então a substituição é aplicada a todas as linhas  entre duas linhas que casam com os endereços fornecidos.</p>
<p>Isto requer  algum esclarecimento. Mais precisamente, a substituição ocorre em todas as  linhas desde a primeira ocorrência de &#8220;endereço1&#8243; até a primeira  ocorrência de &#8220;endereço2&#8243;.</p>
<p>Não se preocupe se isso tudo  parece meio confuso. Os exemplos vão esclarecer melhor.</p>
<p><strong>O comando  de Deleção</strong></p>
<p>A sintaxe desse comando é muito simples. Ai vai:</p>
<p>[endereço1[,endereço2]]d</p>
<p>Isto deleta o conteúdo da &#8220;área de  edição&#8221; (se esta casar com os endereços fornecidos). Todos os comandos  seguintes serão pulados (já que não a nada a fazer com uma área de edição em  branco) e uma nova linha será lida e jogada na área de edição e todo o processo  se repete.</p>
<p>Exemplos:</p>
<p>Exemplo 1:</p>
<p>>cat  file<br />
O gato preto foi caçado por um cachorro marrom.<br />
>sed -e &#8216;s/preto/branco/g&#8217; file<br />
O gato branco foi caçado  por um cachorro marrom.</p>
<p>Exemplo 2:</p>
<p>>cat file<br />
O gato preto foi caçado por um cachorro marrom.<br />
O gato preto não  foi caçado por um cachorro marrom.<br />
>sed -e  &#8216;/não/s/preto/branco/g&#8217; file<br />
O gato preto foi caçado por um  cachorro marrom.<br />
O gato branco não caçado por um cachorro marrom.</p>
<p>Neste caso, a substituição é aplicada somente a linhas que casam com  a expressão regular &#8220;/não/&#8221;. Portanto, ela não é aplicada a primeira  linha, pois esta não contem a palavra &#8220;não&#8221;.</p>
<p>Exemplo 3:</p>
<p>>cat file<br />
linha 1 (um)<br />
linha 2 (dois)<br />
linha 3 (três)</p>
<p>Exemplo 3a:</p>
<p>>sed -e  &#8217;1,2d&#8217; file<br />
linha 3 (três)</p>
<p>Exemplo 3b:</p>
<p>>sed -e &#8217;3d&#8217; file<br />
linha 1 (um)<br />
linha 2 (dois)</p>
<p>Exemplo 3c:</p>
<p>>sed -e &#8217;1,2s/linha/LINHA/&#8217;  file<br />
LINHA 1 (um)<br />
LINHA 2 (dois)<br />
linha 3 (três)</p>
<p>Exemplo 3d:</p>
<p>>sed -e  &#8216;/^linha.*um/s/linha/LINHA/&#8217; -e &#8216;/linha/d&#8217; file</p>
<p>LINHA 1 (um)</p>
<p>3a : Este foi bem simples: Nós apenas deletamos as  linhas de 1<br />
até 2<br />
3b : Isto também foi simples: Nós deletamos a linha  3.<br />
3c : Neste exemplo, nós fizemos uma substituição nas<br />
linhas 1 até  2.<br />
3d : Agora este é mais interessante e merece algumas<br />
explicações.</p>
<p>O primeiro comando vai procurar &#8220;^linha.*um&#8221; e substituir  &#8220;linha&#8221; por &#8220;LINHA&#8221;, ou seja, somente a primeira linha casa  com essa expressão regular. O segundo comando diz para o sed deletar linhas que  contenham a palavra &#8220;linha&#8221;. Assim, somente as duas últimas linhas  serão deletadas, já que a primeira teve palavra &#8220;linha&#8221; substituída  por &#8220;LINHA&#8221;.</p>
<p>Exemplo 4:</p>
<p>>cat file<br />
olá<br />
Este texto será cortado<br />
olá (também será retirado)<br />
ReTiRaDo Também!!!<br />
tchau<br />
(1) Este  texto não foi apagado<br />
(2) nem este &#8230; ( tchau )<br />
(3) nem  este<br />
olá<br />
mas este será<br />
e este também<br />
e a  menos que nós encontremos outro tch*u<br />
cada linha até o final do texto  será apagada</p>
<p>>sed -e &#8216;/olá/,/tchau/d&#8217; file</p>
<p>(1) Este texto não foi apagado<br />
(2) nem este &#8230; ( tchau )<br />
(3) nem este</p>
<p>Isto mostra como o endereçamento funciona quando dois  endereços são especificados. O sed encontra o primeiro casamento da expressão  &#8220;olá&#8221; e deleta todas as linhas lidas na área de edição até ele  encontrar a primeira linha que contém a expressão &#8220;tchau&#8221; (está também  será apagada). Ele não aplica mais o comando de deleção para nenhuma linha até  encontrar novamente a expressão &#8220;olá&#8221;. Desde que a expressão  &#8220;tchau&#8221; não ocorre mais em nenhuma linha subseqüente, o comando de  deleção é aplicado até o final do texto.</p>
<p>Resumindo, é simples: Quando  ele encontra o primeiro endereço (&#8220;olá&#8221;) ele passa a executar os  comandos até encontrar o segundo endereço (&#8220;tchau&#8221;) ou o fim do texto.  E isso se repete até acabar o texto.</p>
<p>Exemplo 5:</p>
<p>>cat file<br />
<a target="_blank" href="http://www.kernel.org/">http://www.kernel.org/</a><br />
>sed -e<br />
&#8216;s@http://www.kernel.org@http://www.metalab.unc.edu@&#8217; file<br />
<a target="_blank" href="http://www.metalab.unc.edu/">http://www.metalab.unc.edu/</a></p>
<p>Note que nós usamos um delimitador  diferente, @ para o comando de substituição. O Sed permite diversos  delimitadores para o comando de substituição, incluindo @ % , ; : Esses  delimitadores alternativos são bons para substituições que incluem string como  nome de arquivos e outras que contém barra normal /, o que torna o código do sed  muito mais legível.</p>
<p><strong>Mais alguns comandos</strong></p>
<p>Aqui  veremos mais alguns comandos sobre o sed, a maioria deles mais complexos.  Dependendo da aplicação em que vocês forem usar o sed, dificilmente usarão esses  recursos, a menos que precisem de um processamento de texto mais refinado e  complexo. Veja que eles são muito usado nos scripts do sed (não confunda com  shell-script).</p>
<p><strong>Backreference no Sed</strong></p>
<p>Uma das coisas  legais sobre backreference no sed é que você pode usar não apenas em procura de  textos mas também na substituição de textos.</p>
<p><strong>O comando Quit</strong></p>
<p>O comando quit ou &#8220;q&#8221; é muito simples. Ele simplesmente  termina o processamento. Nenhuma outra linha é lida para a área de edição ou  impressa na saída padrão.</p>
<p><strong>Sub-rotinas</strong></p>
<p>Nós agora  introduzimos o conceito de sub-rotinas no sed:</p>
<p>No sed, as chaves { }  são usadas para agrupar comandos. Elas são usadas dessa maneira:</p>
<p>endereço1[,endereço2]{<br />
comandos}</p>
<p>Exemplo: Encontrar uma palavra  de uma lista num arquivo</p>
<p>Este exemplo faz um bom uso dos conceitos  descritos acima.</p>
<p>Para isto, nos usamos um shell-script, desde que os  comandos são muito longos e precisaríamos escrever a longa string X várias  vezes. Note que usamos aspas duplas, já que a variável $X precisa ser  expandida pelo shell. A sintaxe para rodar esse script é: &#8220;script  arquivo&#8221;, onde &#8220;script&#8221; é o nome dado ao script e  &#8220;arquivo&#8221; é o nome do arquivo a procurar uma palavra da lista.<br />
X=&#8217;word1\|word2\|word3|\word4|\word<br />
#!/bin/sh<br />
5&#8242;<br />
sed -e &#8221;<br />
/$X/!d<br />
/$X/{<br />
s/\($X\).*/\1/<br />
s/.*\($X\)/\1/<br />
q<br />
}&#8221; $1</p>
<p>Uma nota importante: é tentador pensar que:</p>
<p>s/\($X\).*/\1/<br />
s/.*\($X\)/\1/</p>
<p>é redundante e tentar encurta-la para:</p>
<p>s/.*\($X\).*/\1/</p>
<p>Mas isto não funciona. Por que?  Suponha que temos a linha:</p>
<p>word1 word2 word3</p>
<p>Nós não  temos como saber se $X vai casar com word1, word2 ou word3, então quando  nós citamos ele (\1), nós não sabemos quais dos termos está sendo citado. O  que está sendo usado para certificar-se que não há problemas na correta  implementação, é isto:</p>
<p>&#8220;O operador * é guloso. Ou seja, quando  há ambigüidade sobre qual (expressão)* pode casar, ele tentar casar o máximo  possível.&#8221;</p>
<p>Então neste exemplo,  s/\($X\).*/\1/ , .* tenta engolir o máximo da linha  possível, em particular, se a linha contém isso:</p>
<p>&#8220;word1  word2 word3&#8243;</p>
<p>Então nós podemos ter certeza que .* casa com  &#8221; word2 word3&#8243; e portanto $X seria word1. Não se preocupem se não  entenderam muito bem este tópico. Ele é complicado mesmo e pouco usado. O  importante é entender como ele funciona, o uso de regexp e do comando de  substituição e deleção. Para maiores informações sobre o sed, dê uma olhada na  sua man page: &#8220;man sed&#8221;</p>
<p>Espero que vocês tenham gostado  desse pequeno tutorial sobre sed. Como disse na aula anterior sobre o Grip, é  praticando que se aprende a usar ele.</p>
<p>O fim&#8230;</p>
<p>Bom  pessoal, acho que nosso curso termina por aqui. Claro que não deu pra cobrir  tudo sobre shell script, se não nosso curso não teria fim. Tentei abordar os  topicos mais importantes, de modo que vcs tenham uma boa noção de como funciona  as coisas no shell e possam dar os proprios passos. Desculpem se esqueci de  falar sobre alguma coisa que vocês estavam esperando. Como disse, estou a  disposição para resolver qualquer dúvidas.</p>
<p>Abraços,<br />
Alex Borro  </font></p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/curso-de-shell-aula-5/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 5</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-1/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 1</a></li><li><a href="http://torradeira.net/programando-em-shell-script/" rel="bookmark" class="crp_title">Programando em Shell Script</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-4/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 4</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-3/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 3</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/curso-de-shell-aula-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso de Shell &#8211; Aula 5</title>
		<link>http://torradeira.net/curso-de-shell-aula-5/</link>
		<comments>http://torradeira.net/curso-de-shell-aula-5/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 12:47:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://torradeira.net/curso-de-shell-aula-5/</guid>
		<description><![CDATA[Por: Alex Borro Nesta aula teremos um breve tutorial sobre o Grep. Ele não é somente um dos comandos mais úteis, mas o seu domínio abre portas para dominar outros poderosos comandos, como o sed (que trataremos na próxima aula) , awk, perl, etc. Eu fiz uma adaptação/ modificação de um tutorial que eu tenho, [...]]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><em>Por: Alex Borro</p>
<p>Nesta aula teremos um breve tutorial sobre o Grep.  Ele não é somente um dos comandos mais úteis, mas o seu domínio abre portas para  dominar outros poderosos comandos, como o sed (que trataremos na próxima aula) ,  awk, perl, etc.<br />
</em><br />
Eu fiz uma adaptação/ modificação de um tutorial que eu tenho, e por sinal é  excelente, sobre o Grep e Expressões Regulares em inglês. Espero que tenha  ficado legal e vocês gostem.<br />
<span id="more-102"></span><br />
<strong>O que ele faz?</strong></p>
<p>O grep  basicamente faz buscas. Mais precisamente:</p>
<p>grep palavra file     retorna todas as linhas do arquivo file<br />
que contenham palavra</p>
<p>Outro jeito de usar o grep é atraves de pipe (lembram dos pipes?). Por exemplo:</p>
<p>ls | grep palavra</p>
<p>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.</p>
<p><strong>Usando caracteres coringas</strong></p>
<p>Suponho que todos saibam o que são caracteres coringas. Caso contrário, coringas  são caracteres especiais que substituem outros. Geralmente o caracter  &#8220;*&#8221; é um coringa que significa &#8220;qualquer caracter em qualquer  quantidade&#8221;. Por isso se a gente executar &#8220;ls *&#8221;, onde  &#8220;*&#8221; entra no lugar do &#8220;nome do arquivo&#8221;, significando  qualquer string de qualquer tamanho. Por isso ele lista todos os arquivos.</p>
<p>Mas agora voltemos ao grep. Será que ele aceita coringas ??? A resposta é  mais do que sim. O grep suporta algo que vai além de coringas, ele suporta  Expressões Regulares. Mas vamos começar apenas com coringas. Um dos mais usados  com o grep é o &#8220;.&#8221; Vamos a um exemplo:</p>
<p>>cat file                                           >grep b.g<br />
file<br />
big                                                  big<br />
bad bug                                           bad bug<br />
bigger                                            bigger<br />
boogy</p>
<p>Note que boogy não casa, desde que &#8220;.&#8221;  significa &#8220;qualquer e apenas um caracter&#8221;. Para significar strings  arbitrárias utilizamos &#8220;*&#8221;, que funciona da seguinte maneira:</p>
<p>&#8220;A expressão consistindo de um caracter seguido por um * casa com  qualquer número (inclusive zero) de repetições desse caracter. Em particular,  &#8220;.*&#8221; significa qualquer string.&#8221;</p>
<p><strong>Para  compreendermos vamos a mais exemplos:</strong></p>
<p>>cat file<br />
big<br />
bad bug<br />
bag<br />
bigger<br />
boogy>grep b.*g file<br />
big<br />
bad  bug<br />
bag<br />
bigger<br />
boogy>grep b.*g. File<br />
bigger<br />
boogy>grep ggg* file<br />
bigger</p>
<p><strong>Avançando para expressões  regulares</strong></p>
<p>Os coringas são o começo, mas a idéia vai mais longe.  Por exemplo, suponha que queremos uma expressão que case com Frederic Smith ou  Fred Smith, ou seja, a string &#8220;eric&#8221; é opcional.</p>
<p>Primeiro,  introduzimos o conceito de um &#8220;caracter escapado (escaped character)&#8221;.</p>
<p>&#8220;Um caracter escapado é um caracter precedido por uma barra  invertida ( \ ). Essa barra invertida faz o seguinte: (a) Remove qualquer  significado especial do caracter. (b) acrescenta um significado especial a um  caracter que não tenha um significado especial.&#8221;</p>
<p>Parece  complicado, mas veja nos exemplo que é um tanto quanto simples:</p>
<p>Para  procurar uma linha contento o texto &#8220;hello.gif&#8221;, o comando correto  seria:</p>
<p>grep &#8216;hello\.gif&#8217; file</p>
<p>Desde que  &#8220;grep &#8216;hello.gif&#8217; file&#8221; iria resultar linhas contendo:  hello-gif , hello1gif , helloagif , etc.</p>
<p>Ou seja, a barra invertida  remove o significado especial do &#8220;.&#8221;, passando esse a significar um  simples ponto ao invés de um coringa.</p>
<p>Agora vamos passar para  expressões agrupadas, a fim de encontrar um jeito de criar uma expressão que  case com Frederic ou Fred. Primeiro vamos começar com o operador &#8220;?&#8221;:</p>
<p>&#8220;Uma expressão consistindo de caracter seguido por uma  interrogação escapada ( \? ) casa com zero ou uma instância daquele  caracter&#8221;.</p>
<p>Exemplo:</p>
<p>&#8220;bugg\?y&#8221; casa com  o seguinte: bugy , buggy  mas não com<br />
bugggy</p>
<p>neo@matrix:~$  echo bugy | grep &#8220;bugg\?y&#8221;<br />
bugy<br />
neo@matrix:~$  echo bugggy | grep &#8220;bugg\?y&#8221;<br />
neo@matrix:~$</p>
<p>Agora vamos para expressões agrupadas. No nosso exemplo, queremos tornar  opcional a string &#8220;eric&#8221; após &#8220;Fred&#8221;, ou seja, não apenas um  caracter mas sim um conjunto de caracteres (string).</p>
<p>&#8220;Uma  expressão dentro de parênteses escapados é tratada como um único caracter&#8221;</p>
<p>Exemplos:</p>
<p>&#8220;Fred\(eric\)\?&#8221; Smith  casa com &#8220;Fred Smith&#8221; or &#8220;Frederic Smith&#8221;<br />
\(abc\)* casa com abc , abcabcabc, etc (isto é, qualquer<br />
número  de repetições da string &#8220;abc&#8221;, incluindo<br />
zero).</p>
<p>Note  que temos que tomar cuidado quando nossas expressões contém espaços em branco.  Quando eles aparecem, precisamos colocar a expressão entre aspas, para que o  shell não interprete mal nosso comando. Para o exemplo acima:</p>
<p>grep  &#8220;Fred\(eric\)\? Smith&#8221; file</p>
<p>Eu aconselho  fortemente a sempre usar aspas, mesmo que não usemos espaços em brancos. Já tive  muita dor de cabeça porque expressões e comandos não funcionavam simplesmente  por não estarem entre aspas. Um dos exemplo acima (o do bugg\?y) não  funciona no meu sistema se não estiver entre aspas. Veja:</p>
<p>neo@matrix:~$ echo bugy | grep &#8220;bugg\?y&#8221;<br />
bugy<br />
neo@matrix:~$ echo bugy | grep bugg\?y<br />
neo@matrix:~$</p>
<p><strong>Outros operadores úteis</strong></p>
<p>Para casar algum caracter  de uma lista, use [ ] Veja:</p>
<p>&#8220;[Hh]ello&#8221; casa com linhas  contendo &#8220;hello&#8221; ou &#8220;Hello&#8221;</p>
<p>Faixas de caracteres  também são permitidos:</p>
<p>[0-3] é o mesmo que [0123]<br />
[a-k] é o mesmo que [abcdefghijk]<br />
[A-C] é o mesmo que [ABC]<br />
[A-Ca-k] é o mesmo que [ABCabcdefghijk]</p>
<p>Existem também algumas formas  alternativas:</p>
<p>[[:alpha:]] é o mesmo que [a-zA-Z]<br />
[[:upper:]] é o mesmo que [A-Z]<br />
[[:lower:]] é o mesmo que [a-z]<br />
[[:digit:]] é o mesmo que [0-9]<br />
[[:alnum:]] é o mesmo que  [0-9a-zA-Z]<br />
[[:space:]] casa com qualquer quantidade de espaços,<br />
inclusive tabulações</p>
<p>Essas formas alternativas, como [[:digit:]] é  preferível ao método direto, [0-9].</p>
<p>Os [ ] podem ser usado para  indicar caracteres que NÃO devem estar na expressão. É só colocar o sinal ^ na  primeira posição da lista. Veja:</p>
<p>neo@matrix:~$ echo hello |  grep &#8220;[Hh]ello&#8221;<br />
hello<br />
neo@matrix:~$ echo hello |  grep &#8220;[^Hh]ello&#8221;<br />
neo@matrix</p>
<p>Outro exemplo, um pouco  mais complicado:</p>
<p>grep &#8220;([^()]*)a&#8221; file retorna qualquer  linha contendo um par de parentes seguido por &#8220;a&#8221; e que NÃO contenham  outros parênteses dentro. Assim, ele casa com essas linhas:</p>
<p>(hello)a<br />
(aksjdhaksj d ka)a</p>
<p>Mas não com: x=(y+2(x+1))a</p>
<p><strong>Casando com um número especifico de repetições</strong></p>
<p>Suponha que  você queira casar um número específico de repetições de uma expressão. Um bom  exemplo são números de telefones. Você pode procurar por um número de telefone  com sete dígitos, assim:</p>
<p>grep &#8220;[:digit:]\{3\}[  -]\?[:digit:]\{4\}&#8221; file</p>
<p>Ou seja, três dígitos,  opcionalmente um espaço ou um hífen e mais 4 dígitos.</p>
<p><strong>Procurando  por começo e fim de linha:</strong></p>
<p>Isso é muito interessante. Digamos que  você queira procurar por linhas que contendo espaços em brancos no começo da  linha, a palavra hello e então o fim da linha. Vamos começar com este exempo:</p>
<p>>cat file<br />
hello<br />
hello world<br />
hhello</p>
<p>>grep hello file<br />
hello<br />
hello world<br />
hhello</p>
<p>Isso não é o que nós  queremos. O que está errado ? O problema é que o grep procura por linhas  contendo a string hello e todas as linhas especificadas contem ela. Para  contornar isso, introduzimos os caracteres de começo e fim de linha:</p>
<p>&#8220;O caracter ^ significa começo de linha e o $ significa fim da  linha&#8221;</p>
<p>Retornando ao nosso exemplo:</p>
<p>grep  &#8220;^[[:space:]]*hello[[:space:]]*$&#8221; file</p>
<p>Ou seja, o  começo da linha, qualquer quantidade de espaço em branco (inclusive zero), a  palavra hello, qualquer quantidade de espaço em branco e o fim da linha. Essa  expressão faz o que a gente quer, retornando somente a linha que contém a  palavra hello. Outro exemplo:</p>
<p>grep &#8220;^From.*Alex&#8221;  /var/spool/mail/neo</p>
<p>Procura no meu inbox por mensagens de uma pessoa  em particular (no caso, Alex). Esse tipo de expressão regular é extremamente  útil e filtros de e-mail, como o procmail, utilizam isso para fazerem tudo.</p>
<p>Isso ou Aquilo: Procurando uma coisa OU outra:</p>
<p>&#8220;A  expressão consistindo de duas expressões separadas pelo operador OU \|  casa linhas contendo uma das duas expressões&#8221;</p>
<p>Note que você DEVE  colocar a expressão dentro de aspas simples ou duplas:</p>
<p>grep  &#8220;cat\|dog&#8221; file casa com linhas contendo a palavra  &#8220;cat&#8221; ou a<br />
palavra &#8220;dog&#8221;<br />
grep &#8220;I am a  \(cat\|dog\)&#8221; casa com linhas contendo a string &#8220;I  am<br />
a cat&#8221; ou a string &#8220;I am a dog&#8221;.</p>
<p><strong>Usando  backreference (referencia anterior)</strong></p>
<p>Digamos que você queira  procurar strings que contenham uma substring em mais de um lugar. Um exemplo é  as tags de cabeçalhos de HTML. Suponha que eu queira procurar por  &#8220;<br />
<h1>alguma string</h1>
<p>&#8220;. Isto é fácil de se fazer. Mas  suponha que eu queira fazer o mesmo, mas permita H2 H3 H4 H5 e H6 no lugar de  H1. A expressão <h[1-6]>.*</h[1-6]> não é boa, desde que casa com  &#8220;<br />
<h1>alguma string</h3>
<p>&#8221; e nos queremos que a tag de  abertura seja igual a de fechamento. Para fazermos isso, usamos backreference:</p>
<p>&#8220;A expressão \n onde n é um número, casa com o conteúdo do  n-ésimo conjunto de parênteses na expressão&#8221;.</p>
<p>Nossa&#8230; isso  realmente precisa de um exemplo!!!!</p>
<p><h\([1-6]\)>.*</h\1> faz o que nos queríamos fazer  acima&#8230;</p>
<p>&#8220;O Senhor \(dog\|cat\) e a senhora  \1 foram visitar o Senhor \(dog\|cat\) e a senhora  \2&#8243;</p>
<p>Esse é outro exemplo bobo. Os casais tem sempre que  serem iguais. Ou um casal de cachorro ou de gato.</p>
<p><strong>Alguns detalhes  cruciais: caracteres especiais e aspas</strong></p>
<p><strong>Caracteres  Especiais:</strong></p>
<p>Aqui nós descrevemos os caracteres especiais para  RegExp (expressões regulares) no grep. Note que no &#8220;egrep&#8221;, que usa  expressões regulares estendidas (atualmente não tem nenhuma funcionalidade a  mais que as expressões regulares normais do GNU grep), a lista de caracteres  especiais são os mesmos, diferindo somente que alguns não precisar estar  &#8220;escapados&#8221;.</p>
<p>Os seguintes caracteres são considerados  especiais, e precisam estar escapados:</p>
<p>?      \        .       [         ]        ^         $</p>
<p>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:</p>
<p>* O colchete  direito ( ] ) perde seu sentido especial se colocado no começo de uma lista, por  exemplo: &#8220;[]12]&#8221; casa com ] , 1, or 2.<br />
* Um hífen perde seu  significado especial se colocado por último. Assim, [15-] casa com 1, 5 ou -<br />
* O caracter ^ perde seu sentido se não for colocado em primeiro lugar.<br />
* A maioria dos caracteres especiais perdem seu significado especial se  forem colocados dentro de colchetes.</p>
<p><strong>Aspas:</strong></p>
<p>Em  primeiro lugar, aspas simples são mais seguras de usar porque elas protegem suas  expressões regulares de serem alteradas pelo bash (como foi visto nas aulas  anteriores). Por exemplo, grep &#8220;!&#8221; file vai produzir um erro, já  que o shell pensa que &#8220;!&#8221; está se referindo ao comando de  histórico do shell, enquanto grep &#8216;!&#8217; file funciona perfeitamente.</p>
<p>Quando você deve usar aspas simples ? A resposta é: se você precisa  usar variáveis do shell, use aspas duplas. Caso contrário, use aspas simples.  Por exemplo:</p>
<p>grep &#8220;$HOME&#8221; file</p>
<p>Procura  em file pelo nome do seu diretório pessoal, enquanto grep &#8216;$HOME&#8217;  file procura pela string $HOME.</p>
<p><strong>Sintaxe das expressões  regulares estendidas</strong></p>
<p>Agora vamos ver a sintaxe do egrep em  contraste com a sintaxe do grep. Ironicamente, apesar do nome  &#8220;estendido&#8221;, o egrep atualmente tem menos funcionalidade do que quando  foi criado, para manter a compatibilidade com o tradicional grep. A melhor  maneira de fazer um grep estendido é utilizar grep -E que usa a sintaxe de  expressões regulares estendidas sem perda de funcionalidade.</p>
<p>Bom,  espero que vocês tenham tido uma boa idéia de como funcionam as expressões  regulares. Elas são extremamente importante, principalmente para utilizar o grep  e o poderosíssimo sed, do qual trataremos na próxima aula. Não se preocupem se  estiverem confuso com as expressões, quando começarem a utilizá-las, as idéias  vão clareando. Até a próxima.</font></p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/curso-de-shell-aula-6/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 6</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-3/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 3</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-1/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 1</a></li><li><a href="http://torradeira.net/programando-em-shell-script/" rel="bookmark" class="crp_title">Programando em Shell Script</a></li><li><a href="http://torradeira.net/introducao-ao-perl/" rel="bookmark" class="crp_title">Introducao ao Perl</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/curso-de-shell-aula-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso de Shell &#8211; Aula 4</title>
		<link>http://torradeira.net/curso-de-shell-aula-4/</link>
		<comments>http://torradeira.net/curso-de-shell-aula-4/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 12:47:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://torradeira.net/curso-de-shell-aula-4/</guid>
		<description><![CDATA[Por: Alex Borro Nesta aula vamos aprender sobre comandos de laço como o while, for, case e select. Eles nos permitem executar alguns comandos diversas vezes, sob determinadas condições e até montar menuzinhos para interagir com o usuário. While Este é provavelmente o comando de laço mais utilizado em programação. Seu entendimento é simples. Ele [...]]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><em>Por: Alex Borro</p>
<p>Nesta aula vamos aprender sobre comandos de laço como  o while, for, case e select. Eles nos permitem executar alguns comandos diversas  vezes, sob determinadas condições e até montar menuzinhos para interagir com o  usuário.<br />
</em><br />
<strong>While</strong></p>
<p>Este é provavelmente o comando de laço mais utilizado em  programação. Seu entendimento é simples. Ele testa uma condição (como faz o IF)  e executa um conjunto de comandos se esta condição for verdadeira. Após a  execução desses comandos, ele torna a testar a condição e se esta for  verdadeira, ele reexecuta os comandos e assim por diante.<br />
<span id="more-101"></span><br />
Sua sintaxe  é a seguinte:</p>
<p>while [ condição ];<br />
do<br />
comando 1;<br />
comando 2;<br />
&#8230;<br />
done;</p>
<p>O parâmetro [ condição ] funciona  exatamente igual ao do IF. Não voltarei a abortar os parâmetros condicionais  pois eles já foram explicados na aula 3. Em caso de dúvida sobre isso, uma  rápida revisão na aula 3 é suficiente.</p>
<p>Bom, vamos ao exemplo mais  simples do While: um contador.</p>
<p>x = 0<br />
While [   "$x" -le 10 ];<br />
do<br />
echo &#8220;Execução número:   $x&#8221;?;<br />
x = $((x+1));<br />
done;</p>
<p><strong>Analisando:</strong></p>
<p>Na primeira linha temos a condição: enquanto o  valor da variável x ( $x ) for menor-igual ( -le ) a 10, faça: mostre  &#8220;Execução número: &#8221; e o valor de x ($x). Faça x = x + 1. Isso no  bash é feito pelo comando $(( )). Ele realiza operações algébricas com  variáveis. No caso acima, estamos somando x + 1 e colocando o resultado no  próprio x.</p>
<p>Preste atenção, que as linhas do While precisam de um  &#8220;;&#8221; para terminar, exceto a que contém o &#8220;do&#8221;, pois ele  representa o começo do bloco de comandos.</p>
<p>Quando executamos o script  acima, temos uma contagem de 1 até 10:</p>
<p>neo@matrix:~$ x=0; while  [ "$x" -lt 10 ]; do x=$((x+1)); echo<br />
&#8220;Execução  número: $x&#8221;; done;<br />
Execução número: 1<br />
Execução número: 2<br />
&#8230;<br />
Execução número: 10<br />
neo@matrix:~$</p>
<p>O While  tem muita utilidade em programação, mas fica difícil dar exemplos usando somente  ele, pois geralmente ele está associado a execução de outros programas e rotinas  mais complexas.</p>
<p>Eu costumo usar ele, por exemplo, quando quero que o  napster fique tentando conectar, pois quando ele vai tentar conectar o servidor  e não consegue, ele simplesmente termina. Ai eu coloco o while testando a código  de retorno dele (lembram da variável $? ) e enquanto estiver diferente de  zero (o napster terminou com erro), ele fica executando o napster:</p>
<p>?  = 1; while [ "$?" -ne "0" ]; do ./nap; done;</p>
<p>O comando &#8220;? = 1&#8243; tenta atribuir 1 a variável ?. Isso provoca um erro,  pois a variável ? É somente de leitura. Isso é necessário para que ? Contenha  algo diferente de 0, pois senão o While não executa a primeira interação.</p>
<p><strong>For</strong></p>
<p>O for é semelhante ao while usado como um contador. É  necessário fornecer uma lista de nomes e ele executa os comandos para cada nome  na lista. Parece meio confuso, mas é simples. Veja a sintaxe:</p>
<p>for  <var> in</p>
<lista>;<br />
do<br />
comandos<br />
done;</p>
<p>O For  associa o primeiro item da lista de nomes à variável <var> e executa os  comandos. Em seguida, associa novamente o segundo item da lista à <var> e  executa novamente os comandos&#8230; e assim por diante, até acabar a lista.</p>
<p><strong>Veja o exemplo:</strong></p>
<p>neo@matrix:~$ for x in Compra Venda  Aluguel; do echo $x; done;<br />
Compra<br />
Venda<br />
Aluguel</p>
<p>Ou seja, primeiro ele coloca &#8220;Compra&#8221; na variável x e executa os  comandos, no caso, &#8220;echo $x&#8221;, e assim por diante.</p>
<p>Podemos facilmente implementar um contador, usando em conjunto com o for, o  programinha &#8220;seq&#8221;. Ele simplesmente gera uma seqüência de números. Por  exemplo, &#8220;seq 10&#8243; gera uma seqüência de 1 até 10. Assim, podemos  usá-lo no for:</p>
<p>for x in $(seq 10); do echo $x; done;</p>
<p>Esse comando é semelhante ao contador implementado com o While. Primeiro o  x vale 1 e o for executa os comandos. Depois x vale 2 e ele reexecuta os  comandos&#8230;</p>
<p>Vamos usar o For para renomear os arquivo de um  diretório, mudando todos os arquivo terminados em &#8220;.mp3&#8243; para  &#8220;.mp3.bak&#8221;.</p>
<p>for x in *; do<br />
mv &#8220;$x&#8221;  &#8220;${x}.bak&#8221;;<br />
done;</p>
<p>for x in *.mp3; do<br />
if  [ -e "$x" ];<br />
then mv &#8220;$x&#8221;  &#8220;${x}.bak&#8221;;<br />
fi;<br />
done;</p>
<p>No local de</p>
<lista>nos colocamos &#8220;*.mp3&#8243;. Isso diz ao bash para expandir  (transformar) ele na lista de arquivos terminados com &#8220;.mp3&#8243;. Senão  houver nenhum arquivo com essa terminação, o bash não faz nada, ficando para o  for a string &#8220;*.mp3&#8243;. Por isso precisamos do IF para testar se o  arquivo existe.
<p><strong>Experimente no seu sistema.</strong></p>
<p>echo  *.mp3</p>
<p>Vai mostrar os arquivos no diretório atual com terminação mp3,  mas sem quebra de linha entre eles, ou seja, um nome após o outro. Se não houver  nenhum arquivo com terminação mp3, ele apenas vai mostrar &#8220;*.mp3&#8243;.</p>
<p>Bom, voltando ao For, ele vai atribuir a &#8220;x&#8221; cada nome na  lista de arquivos com terminação &#8220;.mp3&#8243; e executar os comandos  seguintes.</p>
<p>Primeiro ele testa para ver se o arquivo existe ( if [ -e  "$x" ]; ), e se existir, renomeia ele para o seu próprio nome  acrescido de &#8220;.bak&#8221; ( ${x}.bak ).</p>
<p>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, à variável <var> e executa os comandos entre o  &#8220;do&#8221; e o &#8220;done;&#8221;.</p>
<p><strong>Case</strong></p>
<p>O Case  está mais para um comando condicional do que para comando de laço, visto que ele  não executa &#8220;loopings&#8221; como o While e o For.</p>
<p>Ele geralmente  é utilizado como substituição de vários IFs.. Um exemplo clássico e muito  utilizado é quando você precisa testar um parâmetro fornecido na linha de  comando. O Case é utilizado desta forma em scripts de inicialização de serviços  do sistema.</p>
<p>Vou mostrar a sintaxe em em seguida um script que  inicialize/ reinicialize ou pare algum serviço (como o sendmail, apache, bind,  etc).</p>
<p><strong>Sintaxe:</strong></p>
<p>case</p>
<parâmetro>in</p>
<p><opção 1>)<br />
<comandos 1><br />
;;</p>
<p>[opção 2] )<br />
<comandos 2><br />
;;<br />
* )<br />
< comandos se não for nenhuma das<br />
opções ><br />
;;<br />
esac</p>
<p>Vamos as explicações. O Case pega a  string fornecida em</p>
<parâmetro>e compara com <opção 1>. Se forem  iguais, ele executa <comandos 1> e sai fora. Caso contrario, ele compara</p>
<parâmetro>com <opção 2> e assim por diante.</p>
<p>Caso</p>
<parâmetro>não seja igual a nenhuma das opções, ele executa os comandos  da opção &#8220;*&#8221;, se este existir.</p>
<p>Prestem atenção a alguns  detalhes na sintaxe. Deve existir um &#8220;)&#8221; após cada opção e também um  &#8220;;;&#8221; após todos os comandos de cada opção. Vejam o exemplo abaixo:</p>
<p>case &#8220;$1&#8243; in</p>
<p>&#8216;start&#8217; )<br />
echo &#8220;Iniciando o serviço&#8230;&#8221;<br />
<comandos para iniciar o serviço><br />
;;<br />
&#8216;restart&#8217; )<br />
echo &#8220;Reinicializando o  serviço&#8230;&#8221;<br />
<comandos para reinicializar o  serviço><br />
;;<br />
&#8216;stop&#8217; )<br />
echo &#8220;Parando o serviço&#8230;&#8221;<br />
<comandos para  parar o serviço><br />
;;<br />
*)<br />
echo  &#8220;Opção invalida!&#8221;<br />
echo &#8220;As opções  válidas são:<br />
start,   stop   e   restart&#8221;<br />
;;<br />
esac</p>
<p>O Case serve exatamente para isso, ou seja, evitar o teste  de vários Ifs. No caso acima, teríamos 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 não acontece. Após entrar em  uma opção e executar seus comandos, ele já pula fora do case sem testar as  outras opções abaixo.</p>
<p><strong>Select</strong></p>
<p>O Select é um comando  de laço que nos permite mostrar um pequeno menuzinho de opções para o usuário.  Cada opção possui um número e para escolher, o usuário digita o número  correspondente a opção desejada. Vejamos a sintaxe a seguir:</p>
<p>select  <var> in</p>
<lista de opções>;<br />
do<br />
<comandos><br />
done;</p>
<p>Como disse acima, o select vai mostrar as opções contidas em</p>
<lista de opções>, uma por linha, com um número na frente e espera que o  usuário digite a opção desejada. Ao digitar a opção, o select atribui o nome da  opção a variável <var> e executa os comandos. Para sair do select, é  necessário executar o comando &#8220;break&#8221;. Vamos a um exemplo:
<p>select x in Iniciar Reiniciar Parar Sair; do<br />
echo &#8220;Opção Escolhida:   $x&#8221;<br />
if [ "$x" == "Sair" ]; then  break; fi;<br />
done;</p>
<p>Ou seja, se o usuário escolher alguma opção  diferente de &#8220;Sair&#8221;, o script apenas escreve a opção. Se for escolhida  Sair, ele mostra a opção, entra no IF e executa o break, saindo do select.</p>
<p>É interessante combinar o Select com o Case. Vamos mostrar como ficaria  aquele exemplo do case, de iniciar um serviço, utilizando o Select, para tornar  o script interativo:</p>
<p>select x in Iniciar Reiniciar Parar Sair; do</p>
<p>case &#8220;$x&#8221; in<br />
&#8216;Iniciar&#8217; )<br />
echo &#8221;                   Iniciando o<br />
serviço&#8230;&#8221;<br />
;;<br />
&#8216;Reiniciar&#8217; )<br />
echo  &#8221;                   Reinicializando o<br />
serviço&#8230;&#8221;<br />
;;<br />
&#8216;Parar&#8217; )<br />
echo &#8221;                    Parando o serviço&#8230;&#8221;<br />
;;<br />
&#8216;Sair&#8217;   )<br />
echo &#8221;                   Script encerrado.&#8221;<br />
break<br />
;;<br />
*)<br />
echo &#8221;                   Opção<br />
inválida!&#8221;<br />
;;<br />
esac<br />
done;</p>
<p>Primeiramente o Select mostra um  menuzinho:</p>
<p>1) Iniciar<br />
2) Reiniciar<br />
3) Parar<br />
4) Sair<br />
#?</p>
<p>Quando o usuário digitar um número de opção, o select  executa o case e este compara a variável x com suas opções. Se achar alguma,  executa seus comandos, no caso um echo. Se o usuário escolher Sair, além do  echo, ele executa o &#8220;break&#8221;, que interrompe o select:</p>
<p>neo@matrix:~/test$ ./t<br />
1) Iniciar<br />
2) Reiniciar<br />
3) Parar<br />
4) Sair<br />
#? 1<br />
Iniciando o serviço&#8230;<br />
1) Iniciar<br />
2) Reiniciar<br />
3) Parar<br />
4) Sair<br />
#? 5<br />
Opção inválida!<br />
1) Iniciar<br />
2) Reiniciar<br />
3) Parar<br />
4) Sair<br />
#? 4<br />
Script encerrado.<br />
neo@matrix:~/test$</p>
<p>Bom pessoal, acho que por hoje é só. <img src='http://torradeira.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Espero que vocês tenham pego  a idéia de como funciona comandos de laços. Pelos menos sabendo a utilidade,  sintaxe e como funcionam, quando surgir a necessidade, vocês já vão saber quais  ferramentas usar.</p>
<p>Qualquer dúvida, sugestão, etc, podem me enviar um  e-mail. Terei o maior prazer em responder. Até a próxima aula! </font></p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/curso-de-shell-aula-3/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 3</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-1/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 1</a></li><li><a href="http://torradeira.net/programando-em-shell-script/" rel="bookmark" class="crp_title">Programando em Shell Script</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-2/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 2</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-5/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 5</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/curso-de-shell-aula-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso de Shell &#8211; Aula 3</title>
		<link>http://torradeira.net/curso-de-shell-aula-3/</link>
		<comments>http://torradeira.net/curso-de-shell-aula-3/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 12:46:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://torradeira.net/curso-de-shell-aula-3/</guid>
		<description><![CDATA[Por: Alex Borro Introdução Nesta terceira parte do nosso curso de shell script, vamos tratar de &#8220;condicionais&#8221;.Condicionais são comandos que avaliam uma expressão. Se ela for verdadeira, uma determinada rotina é executada. Caso contrário, outra rotina pode ser executada. O famoso &#8220;if&#8221; O bash nos oferece, entre outros, o comando IF (ele é um comando [...]]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><em>Por: Alex Borro</p>
<p><strong>Introdução</strong></p>
<p>Nesta terceira parte do  nosso curso de shell script, vamos tratar de  &#8220;condicionais&#8221;.Condicionais são comandos que avaliam uma expressão. Se  ela for verdadeira, uma determinada rotina é executada. Caso contrário, outra  rotina pode ser executada.<br />
</em><br />
<strong>O famoso &#8220;if&#8221;</strong></p>
<p>O bash nos oferece, entre outros, o  comando IF (ele é um comando embutido no bash e não um programa como o  &#8220;ls&#8221;, o &#8220;cp&#8221; etc.). A forma mais simples de representar uma  condicional utilizando o IF, é da seguinte forma básica:</p>
<p><strong>if  [condição];<br />
then comandos1;<br />
else comandos2;<br />
fi;</strong></p>
<p>Se  [condição] for verdadeira, os comandos1 são executados. Se for falsa, os  comandos2 são executados.Mas para o IF, o que é uma condição verdadeira ou uma  falsa?</p>
<p>Como foi explicado na aula anterior, TODO comando em Unix tem  um código de retorno. Geralmente o código &#8220;0&#8243; (zero) significa que o  comando foi executado perfeitamente e terminou bem. Códigos maiores que zero  significam que alguma coisa de errado ocorreu.</p>
<p>É assim que o IF  verifica uma condição. Se o seu código de retorno for zero, então ela é  considerada verdadeira. Caso contrario, ela é falsa.Mas então a [condição] tem  que ser um comando, certo? Exatamente. Vamos exemplificar:</p>
<p>neo@matrix:~$ if ls /boot; then echo &#8220;O diretório existe.&#8221;; else  echo &#8220;Diretório inválido.&#8221;; fi;<br />
System.map boot.0300 boot.b  boot_message.txt chain.b config map os2_d.b<br />
O diretório existe.</p>
<p>O que fizemos?</p>
<p>Logo após o if, nós colocamos um comando: &#8220;ls  /boot&#8221;. O que o IF faz? Ele executa esse comando (por isso que temos a  segunda linha começada por &#8220;System.map&#8221;, que é o conteúdo do meu  diretório /boot) e avalia o seu código de saída. Como o &#8220;ls&#8221; foi  executado corretamente, ele retorna zero, significando verdadeiro para o IF, que  executa o comando logo após o &#8220;then&#8221;, ou seja, o echo &#8220;O  diretório existe.&#8221;, mostrando essa mensagem no console.</p>
<p>Agora  vamos colocar um diretório que não existe:</p>
<p>neo@matrix:~$ if ls  /dir_invalido; then echo &#8220;O diretório existe.&#8221;; else echo  &#8220;Diretório inválido.&#8221;; fi;<br />
/bin/ls: /dir_invalido: Arquivo ou  diretório não encontrado<br />
Diretório inválido.</p>
<p>A lógica é a mesma.  Executa o &#8220;ls /dir_invalido&#8221;, que retorna um código maior que zero. O  IF avalia como falso e executa o comando após o else: echo &#8220;Diretório  inválido&#8221;.</p>
<p>Nós poderíamos omitir a segunda linha dos dois  exemplo (a que mostra o conteúdo de /boot no primeiro exemplo e a mensagem de  erro emitida pelo ls dizendo que /dir_invalido não existe no segundo), apenas  redirecionando as saídas para /dev/null, ou seja:</p>
<p>neo@matrix:~$  ls /boot 1> /dev/null 2> /dev/null</p>
<p>Nota: Tem um macete que  possui o mesmo efeito. Em vez de colocar: &#8220;1> /dev/null 2>  /dev/null&#8221; podemos colocar &#8220;2&#038;>1&#8243;, que é menor e mais simples.</p>
<p><strong>O comando &#8220;test&#8221;</strong></p>
<p>Bom, aprendemos que o IF  avalia a código de retorno de um comando. Mas muitas vezes, para não dizer a  maioria, nós queremos avaliar &#8220;expressões&#8221;, ou seja, verificar se uma  variável é igual a outra, se ela esta vazia etc.</p>
<p>Para isso, nós temos  outro comando chamado &#8220;test&#8221; (intuitivo o nome, não?). Ele funciona da  seguinte maneira: test [expressão].</p>
<p>O test pode testar operações de  três tipos: strings, arquivos e aritméticas.</p>
<p><strong>Expressões usando  strings:</strong></p>
<p>O test pode apenas comparar strings, ou seja, verificar  se uma é igual a outra, e verificar se uma string é vazia ou não. Vamos aos  exemplos para facilitar o entendimento:</p>
<p>neo@matrix:~$ test  &#8220;a&#8221; = &#8220;a&#8221;<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test &#8220;a&#8221; = &#8220;b&#8221;<br />
neo@matrix:~$  echo $?<br />
1<br />
neo@matrix:~$ test &#8220;a&#8221; !=  &#8220;b&#8221;<br />
neo@matrix:~$ echo $?<br />
0</p>
<p>Aqui  comparamos a string &#8220;a&#8221; com &#8220;b&#8221;. Como era de se esperar, o  primeiro retornou verdadeiro (zero), pois a = a e o segundo retornou falso. No  terceiro, o símbolo &#8220;!=&#8221; significa &#8220;diferente&#8221;.</p>
<p>neo@matrix:~$ test -z &#8220;neo&#8221;<br />
neo@matrix:~$ echo  $?<br />
1<br />
neo@matrix:~$ test -z &#8220;&#8221;<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test -n  &#8220;neo&#8221;<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test -n &#8220;&#8221;<br />
neo@matrix:~$ echo $?<br />
1</p>
<p>Acima temos os testes de vazio. A opção &#8220;-z&#8221;  verifica se é vazio, e &#8220;-n&#8221; se não é vazio. No primeiro caso, ele  testa se &#8220;neo&#8221; é uma string vazia, retornando falso. Já no segundo  caso, como &#8220;&#8221; é vazia, retorna verdadeiro. O terceiro e quarto são  semelhantes aos primeiros, mas com &#8220;-n&#8221;.</p>
<p><strong>Expressões com  arquivos:</strong></p>
<p>Os testes que podem ser feitos com arquivos são para  verificar determinadas caracteristicas, como se ele existe, se é executavel, se  é um link simbólico, se é um diretório etc.</p>
<p>Alguns exemplos:</p>
<p>A opção &#8220;-e&#8221; verifica apenas se um arquivo existe e a opção  &#8220;-d&#8221; verifica se o arquivo é um diretório.</p>
<p>A opção  &#8220;-nt&#8221; verifica se o primeiro arquivo é mais novo que o segundo (nt =  newer than) e &#8220;-ot&#8221; verifica se o primeiro é mais velho que o segundo  (od = older than):</p>
<p>neo@matrix:~$ test -e /vmlinuz<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test -d /vmlinuz<br />
neo@matrix:~$ echo $?<br />
1<br />
neo@matrix:~$ test -e /usr<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test -d /usr<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test /usr  -nt /vmlinuz<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$  test /usr -ot /vmlinuz<br />
neo@matrix:~$ echo $?<br />
1</p>
<p><strong>O comando &#8220;test&#8221; (continuação)</strong></p>
<p>A seguir, temos uma  lista de várias opções disponíveis:</p>
<p>* -b arquivo &#8211; Verdadeiro se  arquivo é um arquivo de bloco, como /dev/hda.<br />
* -c arquivo &#8211; Verdadeiro  se arquivo é um arquivo de caracter, como /dev/tty1.<br />
* -d arquivo &#8211;  Verdadeiro se arquivo é um diretório.<br />
* -e arquivo &#8211; Verdadeiro se  arquivo existe.<br />
* -f arquivo &#8211; Verdadeiro se arquivo existe e é um  arquivo comum.<br />
* -s arquivo &#8211; Verdadeiro se arquivo existe e não é  vazio.<br />
* -h arquivo &#8211; Verdadeiro se arquivo é um link simbólico.<br />
* -p arquivo &#8211; Verdadeiro se arquivo é um &#8220;named pipe&#8221; (fifo, lifo,  etc).<br />
* -S arquivo &#8211; Verdadeiro se arquivo é um &#8220;socket&#8221;.<br />
* -k arquivo &#8211; Verdadeiro se arquivo tem seu &#8220;sticky bit&#8221;  ligado.<br />
* -r arquivo &#8211; Verdadeiro se arquivo pode ser lido pelo usuário  atual.<br />
* -w arquivo &#8211; Verdadeiro se arquivo pode ser escrito pelo  usuário atual.<br />
* -x arquivo &#8211; Verdadeiro se arquivo pode ser executado  pelo usuário atual.<br />
* -O arquivo &#8211; Verdadeiro se arquivo pertence ao  usuário atual.<br />
* -G arquivo &#8211; Verdadeiro se arquivo pertence ao grupo  do usuário atual.<br />
* -N arquivo &#8211; Verdadeiro se arquivo foi modificado  desde a ultima vez que foi lido.</p>
<p><strong>Expressões Aritméticas</strong></p>
<p>Expressões aritméticas consistem com comparar dois números, verificando se  são iguais, ou se o primeiro é maior que o segundo etc.</p>
<p>Infelizmente  não podemos apenas utilizar os símbolos conhecidos para igual (=), maior que  (>), menor que (<) etc. Temos que usar operadores reconhecidos pelo  "test". Assim, não podemos fazer: "test 1 = 1", devemos  utilizar o operador "-eq" (equal): "test 1 -eq 1". A seguir,  temos uma lista dos operadores:</p>
<p>* -eq (equal): Igual;<br />
*  -ne (not-equal): Não Igual (diferente);<br />
* -lt (less than): Menor que  (<);<br />
* -le (less than or equal): Menor ou igual ( <= );<br />
* -gt (greater than): Maior que (>);<br />
* -ge (greater than or equal):  Maior ou igual (>=);</p>
<p><strong>Alguns exemplos:</strong></p>
<p>neo@matrix:~$ test 1 -lt 2<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test 1 -gt 2<br />
neo@matrix:~$ echo $?<br />
1<br />
neo@matrix:~$ test 2 -gt 1<br />
neo@matrix:~$ echo $?<br />
0<br />
neo@matrix:~$ test 2 -ge 2<br />
neo@matrix:~$ echo $?<br />
0</p>
<p>Para finalizar, vamos fazer duas considerações. A primeira é de que o  comando &#8220;test&#8221; pode ser substituido por um par de colchetes [ ].  Assim, o comando test &#8220;a&#8221; = &#8220;b&#8221;  pode ser escrito como [  "a" = "b" ]  .</p>
<p>Essa segunda nomenclatura fica  mais fácil e simples, principalmente quando estamos utilizando IF:</p>
<p>if  [ -e /vmlinuz ]; é mais intuitivo e simples que if test -e /vmlinuz; .</p>
<p>A segunda consideração é que, obviamente, podemos utilizar variáveis no  lugar dos argumentos (caso contrário, ficaria difícil utilizar comandos de  condicionais em shell script). Assim, se tivermos duas variaveis, valor1=5 e  valor2=8:</p>
<p>[ "$valor1" = "$valor2" ] , [  "$valor1" -lt "$valor2" ] etc.</p>
<p>É  importante colocarmos os valores entre aspas duplas (&#8220;), pois assim o bash  pode substituir o que se encontra dentro dessas aspas. Se colocarmos entre aspas  simples (&#8216;), impedimos o bash de alterar o que se encontra dentro delas. Se  não utilizarmos as aspas duplas, vamos ter problemas, principalmente ao  trabalharmos com string.</p>
<p>Por exemplo, queremos comparar dois nomes,  que se encontram em duas variaveis:nome1=&#8221;fulano de tal&#8221; e  nome2=&#8221;ciclano&#8221;.Montando nossa expressão condicional: [  "$nome1" = "$nome2" ].O bash irá expandir isso  para: [ "fulano de tal" = "ciclano" ], ficando claramente  definidos o primeiro e o segundo argumento.</p>
<p>Agora, se não usarmos  aspas: [ $nome1 = $nome2 ]. O bash irá expandir isso para: [ fulano de  tal = ciclano ]. Perceba que os argumentos se misturam e o bash não vai saber o  que comparar.Por isso é importante colocarmos os argumentos entre aspas duplas.</p>
<p><strong>Conclusão</strong></p>
<p>Resumindo, aprendemos na aula de hoje  como utilizar comandos condicionais. Isso será fundamental nas proximas aulas,  onde iremos tratar os comandos de laço, como o while. Não perca!</font></p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/curso-de-shell-aula-4/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 4</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-2/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 2</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-1/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 1</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-5/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 5</a></li><li><a href="http://torradeira.net/programando-em-shell-script/" rel="bookmark" class="crp_title">Programando em Shell Script</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/curso-de-shell-aula-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso de Shell &#8211; Aula 2</title>
		<link>http://torradeira.net/curso-de-shell-aula-2/</link>
		<comments>http://torradeira.net/curso-de-shell-aula-2/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 12:46:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://torradeira.net/curso-de-shell-aula-2/</guid>
		<description><![CDATA[Por: Alex Borro Introdução Na aula de hoje vamos falar sobre execução de programas em primeiro plano (fg &#8211; foreground) e em segundo plano (bg &#8211; background), redirecionamento de saídas e também sobre os códigos de escape dos programas. Execução em foreground e background Quando executamos um programa, o shell fica esperando o mesmo terminar [...]]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><em>Por: Alex Borro</p>
<p>Introdução</p>
<p>Na aula de hoje vamos falar  sobre execução de programas em primeiro plano (fg &#8211; foreground) e em segundo  plano (bg &#8211; background), redirecionamento de saídas e também sobre os códigos de  escape dos programas.<br />
</em><br />
<strong>Execução em foreground e background</strong></p>
<p>Quando executamos um  programa, o shell fica esperando o mesmo terminar para depois nos devolver a  linha de comando. Por exemplo, quando executamos o comando cp arquivo1  arquivo2,o shell executa esse comando, fica esperando ele terminar, para depois  nos retornar a linha de comando. Isso chama-se execução em primeiro plano, ou  foreground, em inglês.Agora digamos que o arquivo a ser copiado seja muito  grande, digamos, 50Mb. Enquanto o comando cp é executado, vamos ficar com o  shell preso a ele todo esse tempo, ou seja, cerca de 1 ou 2 minutos. Somente  após isso vamos ter a linha de comando de volta para podermos continuar  trabalhando.</p>
<p>E se pudéssemos dizer ao shell para executar um programa  e nos retornar a linha de comando sem ficar esperando o tal programa terminar?  Seria muito melhor, não? Em alguns casos seria. E podemos fazer isso.</p>
<p>Uma maneira fácil é colocar o sinal de &#038; depois de um comando. No exemplo acima  ficaria:</p>
<p>neo@matrix:~$ cp arquivo1 arquivo2 &#038;<br />
[1] 206<br />
neo@matrix:~$</p>
<p>Pronto, assim que teclarmos [enter], teremos a  nossa linha de comando de volta e mais duas informações: &#8220;[1] 206&#8243;.</p>
<p>A primeira informação ([1]) chama-se job. Ela identifica os programas  que estão sendo executados em bg (background). Por exemplo, se executarmos mais  um programa em bg enquanto este &#8220;cp&#8221; está sendo executado, o novo  programa recebe o job de número 2 ([2]) e assim por diante.</p>
<p>A segunda  informação (206) é o pid do programa, ou seja, o número de processo que o kernel  dá a esse programa.</p>
<p>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 música. Como fazemos? Usamos o  comando fg [job] (intuitivo, não ?) do bash. No exemplo acima, digamos que eu  execute o &#8220;cp&#8221; em bg, mas depois queira trazê-lo para fg para  cancelá-lo. Seria simples:</p>
<p>neo@matrix:~$ cp arquivo1 arquivo2 &#038;<br />
[1] 206<br />
neo@matrix:~$ fg 1<br />
cp arquivo1 arquivo2</p>
<p>Assim trazemos o &#8220;cp&#8221; para primeiro plano e a linha de comando só  retorna quando ele terminar.</p>
<p>Opcional</p>
<p>Uma outra maneira de  colocar um programa para rodar em bg é utilizando um truque do bash (não sei se  esta opção está disponível em outros shells).Digamos que você execute o comando  &#8220;cp&#8221; e esqueça de colocar o sinal &#8220;&#038;&#8221;. E aí? Tem que ficar  esperando acabar ou cancelar o comando? Não, podemos teclar: Ctrl + Z.</p>
<p>Ao fazer isso, paramos a execução do programa. Então é só dar o comando bg  [job] (intuitivo também, né?):</p>
<p>neo@matrix:~$ cp arquivo1  arquivo2</p>
<p>* aqui teclamos Ctrl + Z *<br />
[1]+ Stopped cp -i arquivo1  arquivo2<br />
neo@matrix:~$ bg 1<br />
[1]+ cp -i arquivo1 arquivo2 &#038;<br />
neo@matrix:~$</p>
<p>Quando teclamos o Ctrl + Z, o bash nos diz que o  job 1 foi parado ([1]+ Stopped) e quando executamos &#8220;bg 1&#8243; ele nos diz  que o comando voltou a ser executado, mas em bg (repare o sinal de &#8220;&#038;&#8221;  no final da linha): [1]+ cp -i arquivo1 arquivo2 &#038;.</p>
<p><strong>Redirecionamento de saídas</strong></p>
<p>Muitos programas que executamos  geram saídas no console, ou sejam, emitem mensagens para os usuários. Por  exemplo, queremos achar quantos arquivos no nosso sistema tem  &#8220;netscape&#8221; no nome:</p>
<p>neo@matrix:~$ find / -name  netscape<br />
/usr/lib/netscape<br />
/usr/lib/netscape/netscape<br />
/usr/lib/netscape/nethelp/netscape<br />
/usr/local/bin/netscape</p>
<p>Agora  se quisermos procurar quantos arquivos compactados com o gzip (extensão .gz) tem  no nosso sistema para depois analisá-los e possivelmente apagar os repetidos ou  inúteis, teremos uma lista muito grande. Aqui no meu sistema deu mais de 1000  arquivos. Então, seria útil podermos enviar as mensagens que vão para o console,  para um arquivo. Assim, poderíamos analisá-lo depois de executar o comando. Isso  é extremamente útil ao trabalharmos com shell script &#8211; enviar as saídas dos  comandos para arquivos para depois analisá-las. Exemplificando:</p>
<p>neo@matrix:~$ find / -name &#8220;*.gz&#8221; > lista.txt<br />
find:  /home/vera: Permissão negada<br />
find: /home/pri: Permissão negada<br />
find:  /root: Permissão negada<br />
neo@matrix:~$</p>
<p>Notamos que nem tudo  foi para o arquivo lista.txt. As mensagens de erro foram para o console.</p>
<p>Isso porque existem dois tipos de saída: a saída padrão e a saída de erro.A  saída padrão é a saída normal dos programas, que no caso acima, seria os  arquivos encontrados. E a saída de erro, como o próprio nome diz, são os erro  encontrados pelo programa durante sua execução, que devem ser informados ao  usuário, como os erros de &#8220;permissão negada&#8221;.</p>
<p>E aí, como  selecionar uma ou outra? É simples, apenas devemos indicar o &#8220;file  descriptor&#8221; (fd) delas. Não vamos entrar em detalhes sobre o que é  &#8220;descritor de arquivos&#8221; por fugir do nosso escopo e ser um pouco  complicado, apenas temos que saber que o fd 1 corresponde a saída padrão e o fd  2 a saída de erro. Assim, no exemplo acima, para enviar os erro para o arquivo  erros.txt e a saída padrão para o arquivo lista.txt, usaríamos:</p>
<p>neo@matrix:~$ find / -name &#8220;*.gz&#8221; 1> lista.txt 2> erros.txt</p>
<p>Ou seja, é só por o número da saída desejada antes do sinal de  &#8220;>&#8221;.</p>
<p>Agora digamos que queremos ver o conteúdo do  arquivo lista.txt. Podemos abrí-lo com um editor de textos ou usar o  &#8220;cat&#8221;. Optando pela última opção:</p>
<p>neo@matrix:~$ cat  lista.txt<br />
/home/neo/gkrellm-0.10.5.tar.gz<br />
/home/neo/linuxcall-interface-beta.tar.gz<br />
&#8230;<br />
<<< mais de  1000 linhas<br />
neo@matrix:~$</p>
<p>Temos um problema. O arquivo tem  mais de 1000 linhas e não conseguimos vê-lo inteiro. Podemos redirecionar a  saída do comando "cat" para o comando "more", que dá pausa  entre as telas:</p>
<p>neo@matrix:~$ cat lista.txt | more<br />
.........</p>
<p>Veja que utilizamos o caractere "|", chamado  "pipe". Não poderíamos ter utilizado o sinal de ">&#8220;? Não,  o sinal de &#8220;>&#8221; é somente para enviar a saída para um ARQUIVO. Para  enviar a saída de um comando para a entrada de outro, usamos o pipe.</p>
<p>As vezes queremos que além da saída ir para um arquivo, ela também vá para a  tela. Temos um programinha que faz isso. Ele chama-se &#8220;tee&#8221;. Veja o  exemplo a seguir:</p>
<p>neo@matrix:~$ find / -name &#8220;*.gz&#8221;  2> erros.txt | tee lista.txt</p>
<p>O que fizemos???Primeiro pegamos  a saída de erro e enviamos para o arquivo erros.txt. O restante, ou seja, a  saída padrão, estamos enviando para a entrada do comando tee (usando o pipe). O  tee simplesmente pega o que ele recebe (através do pipe) e joga no arquivo  lista.txt e na tela. Assim, além de gravarmos a saída num arquivo, podemos  mostrar ao usuário o que está acontecendo. Isso é muito útil quando escrevemos  alguns scripts.</p>
<p>Resumindo: aprendemos que podemos redirecionar a  saída padrão ou de erro de programa para um arquivo usando respectivamente  &#8220;1>&#8221; ou &#8220;2>&#8221; ou também enviar a saída para a entrada  de outro programa usando o pipe &#8220;|&#8221;.</p>
<p>Códigos de Escape</p>
<p>Toda vez que executamos um programa em Unix, ele retorna um código de  escape ao finalizar. Esse código reflete a condição 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 código diferente de 0, geralmente  variando com o problema ocorrido.</p>
<p>Esse código de retorno é  extremamente importante em shell script, pois é assim que testamos se uma certa  ação ocorreu bem ou teve problemas.Esse código é armazenado pelo bash numa  variável chamada &#8220;?&#8221; (isso mesmo, somente o sinal de interrogação  <img src='http://torradeira.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ).</p>
<p>Por exemplo, vamos executar um &#8220;ls&#8221; em um diretório  que existe e ver o código de retorno:</p>
<p>neo@matrix:~$ ls /boot<br />
System.map boot.0300 boot.b boot_message.txt chain.b config map os2_d.b<br />
neo@matrix:~$ echo $? 0<br />
neo@matrix:~$</p>
<p>Ou  seja, o &#8220;ls&#8221; foi executado normalmente, retornando 0. Agora vamos  executá-lo num diretório que não existe:</p>
<p>neo@matrix:~$ ls  /diretorio_invalido<br />
/bin/ls: /diretorio_invalido: Arquivo ou diretório não  encontrado<br />
neo@matrix:~$ echo $?<br />
1<br />
neo@matrix:~$</p>
<p>Como esperado, obtemos o retorno de erro 1.</p>
<p>Alguns  programas tem muitos códigos de retorno. Por exemplo, os códigos de retorno do  &#8220;pppd&#8221; vão até o 19. Assim é possível saber porque ele foi finalizado.  Se você colocar uma senha errada no pppd e tentar conectar, ele vai terminar com  o código 19.</p>
<p>man pppd<br />
&#8230;<br />
17 The PPP negotiation failed  because serial loopback was detected.<br />
18 The init script failed (returned a  non-zero exit status).<br />
19 We failed to authenticate ourselves to the peer.<br />
&#8230;</p>
<p>Um detalhe importante: quando executamos um programa em  background, ele sempre retorna um código 0 para o shell, mesmo que durante sua  execução ocorra algum problema. Assim, quando executamos um programa em bg,  perdemos essa facilidade de testar como foi seu término.</p>
<p>neo@matrix:~$ ls /diretorio_invalido &#038;<br />
[1] 230<br />
neo@matrix:~$  /bin/ls: /diretorio_invalido: Arquivo ou diretório não encontrado</p>
<p>[1]+ Exit 1 /bin/ls $LS_OPTIONS /diretorio_invalido<br />
neo@matrix:~$  echo $?<br />
0</p>
<p>Como vemos, ao terminar, ele emite uma mensagem  dizendo que finalizou com código 1 ([1]+ Exit 1) mas quando testamos a variável  &#8220;?&#8221;, o bash nos diz &#8220;0&#8243;.</p>
<p>Conclusão</p>
<p>Como todos os programas tem que terminar com um código de retorno que tenha  algum significado, nossos shell scripts também terão que finalizar indicando o  que aconteceu, se ocorreu tudo bem ou se ouve erro. Mas isso discutiremos melhor  mais pra frente.</p>
<p>O importante aqui é saber que todos os programas  terminam com um código de retorno, os quais usaremos nos nossos scripts para  testar o término dos programas.</font></p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/curso-de-shell-aula-1/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 1</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-3/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 3</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-4/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 4</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-5/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 5</a></li><li><a href="http://torradeira.net/programando-em-shell-script/" rel="bookmark" class="crp_title">Programando em Shell Script</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/curso-de-shell-aula-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curso de Shell &#8211; Aula 1</title>
		<link>http://torradeira.net/curso-de-shell-aula-1/</link>
		<comments>http://torradeira.net/curso-de-shell-aula-1/#comments</comments>
		<pubDate>Tue, 23 Jan 2007 12:45:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://torradeira.net/curso-de-shell-aula-1/</guid>
		<description><![CDATA[Por: Alex Borro Introdução O que são os shell scripts? Shell scripts são conjuntos de comandos armazenados em um arquivo texto que são executados seqüencialmente. Nesta primeira parte, faremos uma introdução sobre o shell, o formato desses arquivos e variáveis de ambiente. O que é Shell Shell, ou interpretador de comandos, é o programa disparado [...]]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><em>Por: Alex Borro</p>
<p><strong>Introdução</strong></p>
<p>O que são os shell  scripts? Shell scripts são conjuntos de comandos armazenados em um arquivo texto  que são executados seqüencialmente. Nesta primeira parte, faremos uma introdução  sobre o shell, o formato desses arquivos e variáveis de ambiente.<br />
</em><br />
<strong>O que é Shell</strong></p>
<p>Shell, ou interpretador de comandos, é o  programa disparado logo após o login responsável por &#8220;pegar&#8221; os  comandos do usuário, interpretá-los e executar uma determinada ação.</p>
<p>Por exemplo, quando você escreve no console &#8220;ls&#8221; e pressiona  <enter>, o shell lê essa string e verifica se existe algum comando interno  (embutido no próprio shell) com esse nome. Se houver, ele executa esse comando  interno. Caso contrário, ele vai procurar no PATH por algum programa que tenha  esse nome. Se encontrar, ele executa esse programa, caso contrário, 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 usuário e a senha. Ao digitar um par usuário/senha correto, o Linux  abre automaticamente um shell, que vai ficar esperando seus comandos. Veja o  exemplo abaixo:</p>
<p>Welcome to Linux Slackware 10.1 kernel 2.4.16.</p>
<p>matrix login: neo<br />
Password:</p>
<p>Linux 2.2.16.<br />
Last login:  Mon Sep 25 10:41:12 -0300 2000 on tty1.<br />
No mail.</p>
<p>neo@matrix:~$</p>
<p>Essa ultima linha é o shell. Se você der o comando  &#8220;ps&#8221;, vai ver que um dos programas rodando é o seu shell:</p>
<p>neo@matrix:~$ ps<br />
PID TTY TIME CMD<br />
164 tty2 00:00:00 bash<br />
213  tty2 00:00:00 ps<br />
neo@matrix:~$</p>
<p>Ou seja, o shell utilizado  nesse console é o bash, que está rodando com PID 164.</p>
<p>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 referência.</p>
<p>Resumindo essa seção, é importante saber que para cada terminal ou console  aberto, tem-se um shell rodando. Assim, se você tem 3 xterms abertos na  interface gráfica, vai ter um shell para cada xterm.</p>
<p>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 são executados em um shell próprio (a menos  que se especifique, ao chamar o script, para executá-lo no shell atual). Isso  será importante quando formos tratar de variáveis de ambiente.</p>
<p><strong>Variáveis do ambiente</strong></p>
<p>Uma variável é onde o shell armazena  determinados valores para utilização posterior.</p>
<p>Toda variável possui  um nome e um valor associado a ela, podendo ser este último vazio. Para listar  as variáveis atualmente definidas no shell digite o comando set .</p>
<p>Para se definir uma variável, basta utilizar a síntaxe: nome_da_variável=valor .  Por exemplo, queremos definir uma variável chamada &#8220;cor&#8221; com o valor  de &#8220;azul&#8221;:</p>
<p>neo@matrix:~$ cor=azul</p>
<p>Para  utilizar o valor de uma variável, é só colocar um sinal de &#8220;$&#8221;  seguido do nome da variável &#8211; o shell automaticamente substitui pelo valor da  variável:</p>
<p>neo@matrix:~$ echo cor<br />
cor<br />
neo@matrix:~$ echo $cor<br />
azul</p>
<p>Em alguns casos, é  aconselhável colocar o nome da variável entre chaves ({}). Por exemplo, se eu  quero imprimir &#8220;azul-escuro&#8221;, como faria? Simplesmente echo  $cor-escuro ?? Não funcionaria, pois o bash vai procurar uma variável de  nome &#8220;cor-escuro&#8221;. Portanto, temos que colocar o nome &#8220;cor&#8221;  entre chaves para delimitar o nome da variável:</p>
<p>neo@matrix:~$  echo ${cor}-escuro<br />
azul-escuro</p>
<p>Algumas variáveis já são  predefinidas no shell, como o PATH, que, como foi dito antes, armazena o caminho  dos programas. Por exemplo, a minha variável PATH contém:</p>
<p>neo@matrix:~$ echo $PATH<br />
/usr/local/bin:/usr/bin: /bin:  /usr/X11R6/bin: /usr/openwin/bin: /usr/games: /opt/kde/bin:  /usr/share/texmf/bin: /etc/script</p>
<p>Ou seja, quando digito um comando,  como &#8220;ls&#8221;, o shell vai começar a procurá-lo em /usr/local/bin, se não  encontrá-lo, vai procurar em /usr/bin e assim por diante. Repare que os  diretórios são separados por um sinal de dois pontos (:).</p>
<p>É  importante destacar que o shell possui várias variáveis pré-definidas, ou seja,  que possuem um significado especial para ele, entre elas: PATH, PWD, PS1, PS2,  USER e UID.</p>
<p>Assim, quando iniciamos um novo shell (ao executar o  nosso script), essas variáveis especiais são &#8220;herdadas&#8221; do shell pai  (o que executou o shell filho). Outras variáveis definidas pelo usuário, como a  variável &#8220;cor&#8221; não são passadas do shell pai para o filho.</p>
<p>Quando o script terminar, o seu shell (shell filho) simplesmente desaparece e  com ele também as suas variáveis, liberando o espaço ocupado na memória.</p>
<p><strong>Formato dos arquivos de Shell Script</strong></p>
<p>A primeira linha de  todo shell script deve começar com algo do tipo: #!/bin/bash , a qual indica  com qual shell deverá ser executado o script.Nesse exemplo, estamos falando para  o shell atual executar o script com o shell /bin/bash.Se quisermos que o nosso  script seja executado com o shell csh, devemos colocar nessa primeira linha:  #!/bin/csh .</p>
<p>Como usaremos o bash como nosso shell de referência,  todas as linhas dos nossos scripts começarão com #!/bin/bash</p>
<p>Digamos que você executa freqüentemente o comando: find / -name file -print ,  que procura na raiz (/) por um arquivo de nome &#8220;file&#8221;. Só que é chato  ficar digitando esse comando toda vez que se quer procurar um arquivo.</p>
<p>Então vamos criar um shell script que contenha esse comando. Vamos chamar  esse shell script de &#8220;procura&#8221;. Seu conteúdo fica assim:</p>
<p>#!/bin/bash<br />
find / -name file -print</p>
<p>Pronto. Tornemos agora  o arquivo executável: chmod 755 ./procura . Porém, ao tentar executar o nosso  script, teremos um problema.</p>
<p>./procura</p>
<p>Este script irá  procurar por um arquivo chamado &#8220;file&#8221;.Como especificar qual arquivo  queremos procurar? Seria ideal executarmos o nosso script seguido do nome do  arquivo que queremos procurar.</p>
<p>Por exemplo, queremos saber onde está  o arquivo &#8220;netscape&#8221;: ./procura netscape . É ai que entram as  &#8220;variáveis de parâmetro&#8221;. Vamos substituir no nosso script a linha  find / -name file -print por find / -name $1 -print .</p>
<p>Quando o  bash lê a variável &#8220;$1&#8243;, ele a substitui pelo primeiro parâmetro  passado na linha de comando para o nosso script. Então, se executamos ./procura  netscape , a variável &#8220;$1&#8243; será substituída por  &#8220;netscape&#8221;, como a gente queria. Repare que a variável  &#8220;$2&#8243; conteria o segundo parâmetro passado para o script e assim  por diante.</p>
<p>Sendo assim, qualquer comando colocado abaixo de find  seria executado após ele. Esse é o essencial do shell script: poder automatizar  a execução de programas e comandos como se estivessem sendo digitados  diretamente no console ou terminal.</p>
<p><strong>Conclusão</strong></p>
<p>Na  próxima 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 seqüencialmente. Entre eles, podemos  destacar os comandos de laço, como &#8220;if&#8221;, &#8220;for&#8221;,  &#8220;while&#8221;, &#8220;case&#8221; etc.</p>
<p>Até a próxima semana!</font></p>
<div id="crp_related"><h3>Artigos relacionados:</h3><ul><li><a href="http://torradeira.net/curso-de-shell-aula-2/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 2</a></li><li><a href="http://torradeira.net/programando-em-shell-script/" rel="bookmark" class="crp_title">Programando em Shell Script</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-3/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 3</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-4/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 4</a></li><li><a href="http://torradeira.net/curso-de-shell-aula-6/" rel="bookmark" class="crp_title">Curso de Shell &#8211; Aula 6</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://torradeira.net/curso-de-shell-aula-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

