Escolar Documentos
Profissional Documentos
Cultura Documentos
LM01 Shellscript
LM01 Shellscript
Papo de Botequim
Papo de Botequim
Voc no agenta mais aquele seu amigo usurio de Linux enchendo o seu saco com aquela histria de que o sistema fantstico e o Shell uma ferramenta maravilhosa? A partir desta edio vai ficar mais fcil entender o porqu deste entusiasmo...
POR JULIO CEZAR NEVES
porque, em ingls, Shell significa concha, carapaa, isto , fica entre o usurio e o sistema operacional, de forma que tudo que interage com o sistema operacional, tem que passar pelo seu crivo.
O ambiente Shell
Bom j que para chegar ao ncleo do Linux, no seu kernel que o que interessa a todo aplicativo, necessria a filtragem do Shell, vamos entender como ele funciona de forma a tirar o mximo proveito das inmeras facilidades que ele nos oferece. O Linux, por definio, um sistema multiusurio no podemos nunca nos esquecer disto e para permitir o acesso de determinados usurios e barrar a entrada de outros, existe um arquivo chamado /etc/passwd, que alm de fornecer dados para esta funo de leo-de-chcara do Linux, tambm prov informaes para o incio de uma sesso (ou login, para os ntimos) daqueles que passaram por esta primeira barreira. O ltimo campo de seus registros informa ao sistema qual o Shell que a pessoa vai receber ao iniciar sua sesso. Lembra que eu te falei de Shell, famlia, irmo? Pois , vamos comear a entender isto: o Shell a conceituao de concha envolvendo o sistema operacional propriamente dito, o nome genrico para tratar os filhos desta idia que, ao longo dos muitos anos de exis-
ilogo entreouvido em uma mesa de um botequim, entre um usurio de Linux e um empurrador de mouse: Quem o Bash? o filho caula da famlia Shell. P cara! Ests a fim de me deixar maluco? Eu tinha uma dvida e voc me deixa com duas! No, maluco voc j h muito tempo: desde que decidiu usar aquele sistema operacional que voc precisa reiniciar dez vezes por dia e ainda por cima no tem domnio nenhum sobre o que esta acontecendo no seu computador. Mas deixa isso pr l, pois vou te explicar o que Shell e os componentes de sua famlia e ao final da nossa conversa voc dir: Meu Deus do Shell! Porque eu no optei pelo Linux antes?.
O ambiente Linux
Para voc entender o que e como funciona o Shell, primeiro vou te mostrar como funciona o ambiente em camadas do Linux. D uma olhada no grfico mostrado na Figura 1. Neste grfico podemos ver que a camada de hardware a mais profunda e formada pelos componentes fsicos do seu computador. Em torno dela, vem a camada do kernel que o cerne do Linux, seu ncleo, e quem pe o hardware para funcionar, fazendo seu gerenciamento e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas para que foram desenvolvidos. Fechando tudo isso vem o Shell, que leva este nome
82
Agosto 2004
www.linuxmagazine.com.br
Papo de Botequim
LINUX USER
tncia do sistema operacional Unix, foram aparecendo. Atualmente existem diversos sabores de Shell (veja Quadro 1 na pgina anterior).
redirecionamento, que pode ser de entrada (stdin), de sada (stdout) ou dos erros (stderr), conforme vou explicar a seguir. Mas antes precisamos falar de...
Substituio de Variveis
Neste ponto, o Shell verifica se as eventuais variveis (parmetros comeados por $), encontradas no escopo do comando, esto definidas e as substitui por seus valores atuais.
volvidos (inclusive o prprio programa), e retorna um erro caso o usurio que chamou o programa no esteja autorizado a executar esta tarefa.
$ ls linux linux
Substituio de MetaCaracteres
Se algum meta-caracter (ou coringa, como *, ? ou []) for encontrado na linha de comando, ele ser substitudo por seus possveis valores. Supondo que o nico item no seu diretrio corrente cujo nome comea com a letra n seja um diretrio chamado nomegrandeprachuchu, se voc fizer:
$ cd n*
Neste exemplo o Shell identificou o ls como um programa e o linux como um parmetro passado para o programa ls.
Atribuio
Se o Shell encontra dois campos separados por um sinal de igual (=) sem espaos em branco entre eles, ele identifica esta seqncia como uma atribuio.
$ valor=1000
como at aqui quem est manipulando a linha de comando ainda o Shell e o programa cd ainda no foi executado, o Shell expande o n* para nomegrandeprachuchu (a nica possibilidade vlida) e executa o comando cd com sucesso.
Neste caso, por no haver espaos em branco (que um dos caracteres reservados), o Shell identificou uma atribuio e colocou 1000 na varivel valor.
Resoluo de Redirecionamentos
Aps identificar os componentes da linha que voc digitou, o Shell parte para a resoluo de redirecionamentos. O Shell tem incorporado ao seu elenco de habilidades o que chamamos de
Comando
Quando um comando digitado no prompt (ou linha de comando) do Linux, ele dividido em partes, separadas por espaos em branco: a primeira parte o nome do programa, cuja existncia ser verificada; em seguida, nesta ordem, vm as opes/parmetros, redirecionamentos e variveis. Quando o programa identificado existe, o Shell verifica as permisses dos arquivos en-
Cuidado na Atribuio
Jamais faa:
www.linuxmagazine.com.br
Agosto 2004
83
LINUX USER
Papo de Botequim
$ echo \* $ echo *
Viu a diferena? Aspas (): exatamente iguais ao apstrofo, exceto que, se a cadeia entre aspas contiver um cifro ($), uma crase (`), ou uma barra invertida (\), estes caracteres sero interpretados pelo Shell. No precisa se estressar, eu no te dei exemplos do uso das aspas por que voc ainda no conhece o cifro ($) nem a crase (`). Daqui para frente veremos com muita constncia o uso destes caracteres especiais; o mais importante entender seu significado.
esperando pelo teclado (Entrada Padro) e como tambm no citei a sada, o que eu teclar ir para a tela (Sada Padro), criando desta forma como eu havia proposto um programa gago. Experimente!
Caracteres de redirecionamento
A maioria dos comandos tem uma entrada, uma sada e pode gerar erros. Esta entrada chamada Entrada Padro ou stdin e seu dispositivo padro o teclado do terminal. Analogamente, a sada do comando chamada Sada Padro ou stdout e seu dispositivo padro a tela do terminal. Para a tela tambm so enviadas normalmente as mensagens de erro oriundas dos comandos, chamada neste caso de Sada de Erro Padro ou stderr. Veremos agora como alterar este estado de coisas. Vamos fazer um programa gago. Para isto digite (tecle Enter ao final de cada linha comandos do usurio so ilustrados em negrito):
$ cat E-e-eu sou gago. Vai encarar? E-e-eu sou gago. Vai encarar?
O cat continua sem ter a entrada especificada, portanto est aguardando que os dados sejam teclados, porm a sua sada est sendo desviada para o arquivo Arq. Assim sendo, tudo que esta sendo teclado esta indo para dentro de Arq, de forma que fizemos o editor de textos mais curto e ruim do planeta. Se eu fizer novamente:
$ cat > Arq
No primeiro caso o Shell expandiu o asterisco e descobriu o arquivo linuxmagazine para listar. No segundo, os apstrofos inibiram a interpretao do Shell e veio a resposta que no existe o arquivo linuxm*. Contrabarra ou Barra Invertida (\): idntico aos apstrofos exceto que a barra invertida inibe a interpretao somente do caractere que a segue. Suponha que voc, acidentalmente, tenha criado um arquivo chamado * (asterisco) o que alguns sabores de Unix permitem e deseja remov-lo. Se voc fizesse:
$ rm *
Os dados contidos em Arq sero perdidos, j que antes do redirecionamento o Shell criar um Arq vazio. Para colocar mais informaes no final do arquivo eu deveria ter feito:
$ cat >> Arq
Voc estaria na maior encrenca, pois o rm removeria todos os arquivos do diretrio corrente. A melhor forma de fazer o servio :
$ rm \*
O cat um comando que lista o contedo do arquivo especificado para a Sada Padro (stdout). Caso a entrada no seja definida, ele espera os dados da stdin (a entrada padro). Ora como eu no especifiquei a entrada, ele a est
Redirecionamento Perigoso
Desta forma, o Shell no interpreta o asterisco, evitando a sua expanso. Faa a seguinte experincia cientfica:
$ cd /etc $ echo '*'
Como j havia dito, o Shell resolve a linha e depois manda o comando para a execuo. Assim, se voc redirecionar a sada de um arquivo para ele prprio, primeiramente o Shell esvaziaeste arquivo e depois manda o comando para execuo! Desta forma, para sua alegria, voc acabou de perder o contedo de seu querido arquivo.
84
Agosto 2004
www.linuxmagazine.com.br
Papo de Botequim
LINUX USER
Dados ou Erros?
Preste ateno! No confunda >> com 2>. O primeiro anexa dados ao final de um arquivo, e o segundo redireciona a Sada de Erro Padro (stderr) para um arquivo que est sendo designado. Isto importante!
Caso o arquivo no existisse seria enviado para a tela uma mensagem de erro. Para que isso no acontea faa:
rm /tmp/seraqueexiste$$ 2> U /dev/null
caprichamos, n? Ento ao invs de sair redigindo o mail direto no prompt, de forma a tornar impossvel a correo de uma frase anterior onde, sem querer, voc escreveu um ns vai, voc edita um arquivo com o contedo da mensagem e aps umas quinze verificaes sem constatar nenhum erro, decide envi-lo e para tal faz:
$ mail chefe@chefia.com.br < U arquivocommailparaochefe
Etiquetas Erradas
Um erro comum no uso de labels (como o fimftp do exemplo anterior) causado pela presena de espaos em branco antes ou aps o mesmo. Fique muito atento quanto a isso, por que este tipo de erro costuma dar uma boa surra no programador, at que seja detectado. Lembre-se: um label que se preze tem que ter uma linha inteira s para ele.
Para que voc teste a Sada de Erro Padro direto no prompt do seu Shell, vou dar mais um exemplo. Faa:
$ ls naoexiste bash: naoexiste no such file U or directory $ ls naoexiste 2> arquivodeerros $ $ cat arquivodeerros bash: naoexiste no such file U or directory
e o chefe receber uma mensagem com o contedo do arquivocommailparaochefe. Outro tipo de redirecionamento muito louco que o Shell permite o chamado here document. Ele representado por << e serve para indicar ao Shell que o escopo de um comando comea na linha seguinte e termina quando encontra uma linha cujo contedo seja unicamente o label que segue o sinal <<. Veja o fragmento de script a seguir, com uma rotina de ftp:
ftp -ivn hostremoto << fimftp user $Usuario $Senha binary get arquivoremoto fimftp
Neste exemplo, vimos que quando fizemos um ls em naoexiste, ganhamos uma mensagem de erro. Aps redirecionar a Sada de Erro Padro para arquivodeerros e executar o mesmo comando, recebemos somente o prompt na tela. Quando listamos o contedo do arquivo para o qual foi redirecionada a Sada de Erro Padro, vimos que a mensagem de erro tinha sido armazenada nele. interessante notar que estes caracteres de redirecionamento so cumulativos, isto , se no exemplo anterior fizssemos o seguinte:
$ ls naoexiste 2>> U arquivodeerros
neste pedacinho de programa temos um monte de detalhes interessantes: As opes usadas para o ftp (-ivn) servem para ele listar tudo que est acontecendo (opo -v de verbose), para no ficar perguntando se voc tem certeza que deseja transmitir cada arquivo (opo -i de interactive) e finalmente a opo -n serve para dizer ao ftp para ele no solicitar o usurio e sua senha, pois estes sero informados pela instruo especfica (user); Quando eu usei o << fimftp, estava dizendo o seguinte para o interpretador: Olha aqui Shell, no se meta em
nada a partir deste ponto at encontrar o label fimftp. Voc no entenderia droga nenhuma, j que so instrues especficas do ftp. Se fosse s isso seria simples, mas pelo prprio exemplo d para ver que existem duas variveis ($Usuario e $Senha), que o Shell vai resolver antes do redirecionamento. Mas a grande vantagem deste tipo de construo que ela permite que comandos tambm sejam interpretados dentro do escopo do here document, o que, alis, contraria o que acabei de dizer. Logo a seguir te explico como esse negcio funciona. Agora ainda no d, esto faltando ferramentas. O comando user do repertrio de instrues do ftp e serve para passar o usurio e a senha que haviam sido lidos em uma rotina anterior a este fragmento de cdigo e colocados respectivamente nas duas variveis: $Usuario e $Senha. O binary outra instruo do ftp, que serve para indicar que a transferncia de arquivoremoto ser feita em modo binrio, isto o contedo do arquivo no ser inteerpretado para saber se est em ASCII, EBCDIC, O comando get arquivoremoto diz ao cliente ftp para pegar este arquivo no servidor hostremoto e traz-lo para a nossa mquina local. Se quisssemos enviar um arquivo, bastaria usar, por exemplo, o comando put arquivolocal.
Direito de Posse
O $$ contm o PID,isto ,o nmero do seu processo. Como o Linux multiusurio, bom anexar sempre o $$ ao nome dos seus arquivos para no haver problema de propriedade,isto ,caso voc batizasse o seu arquivo simplesmente como seraqueexiste,a primeira pessoa que o usasse (criando-o ento) seria o seu dono e a segunda ganharia um erro quando tentasse gravar algo nele.
Redirecionamento de comandos
Os redirecionamentos de que falamos at agora sempre se referiam a arquivos, isto , mandavam para arquivo, recebiam de arquivo, simulavam arquivo local, O que veremos a partir de agora, redireciona a sada de um comando para a entrada de outro. utilssimo e, apesar de no ser macaco gordo, sempre quebra os
www.linuxmagazine.com.br
Agosto 2004
85
LINUX USER
Papo de Botequim
maiores galhos. Seu nome pipe (que em ingls significa tubo, j que ele canaliza a sada de um comando para a entrada de outro) e sua representao a | (barra vertical).
$ ls | wc -l 21
O comando ls passou a lista de arquivos para o comando wc, que quando est com a opo -l conta a quantidade de linhas que recebeu. Desta forma, podemos afirmar categoricamente que no meu diretrio existiam 21 arquivos.
$ cat /etc/passwd | sort | lp
Hi! Olha s, no funcionou! mesmo, no funcionou e no foi por causa das aspas que eu coloquei, mas sim por que eu teria que ter executado o who | wc -l antes do echo. Para resolver este problema, tenho que priorizar a segunda parte do comando com o uso de crases:
$ echo "Existem `who | wc -l` U usuarios conectados" Existem 8 usuarios U conectados
A linha de comandos acima manda a listagem do arquivo /etc/passwd para a entrada do comando sort. Este a classifica e envia para o lp que o gerenciador da fila de impresso.
Para eliminar esse monte de brancos antes do 8 que o wc -l produziu, basta retirar as aspas. Assim:
$ echo Existem `who | wc -l` U usuarios conectados Existem 8 usuarios conectados
Caracteres de ambiente
Quando queremos priorizar uma expresso, ns a colocamos entre parnteses, no ? Pois , por causa da aritmtica normal pensarmos deste jeito. Mas em Shell o que prioriza mesmo so as crases (`) e no os parnteses. Vou dar exemplos para voc entender melhor. Eu quero saber quantos usurios esto logados no computador que eu administro. Eu posso fazer:
$ who | wc -l 8
Quequeiiisso minha gente? Eu estava no /home/meudir, mudei para o /etc, constatei que estava neste diretrio com o pwd seguinte e quando o agrupamento de comandos terminou, eu vi que continuava no /etc/meudir! Hi! Ser que tem coisa do mgico Mandrake por a? Nada disso. O interessante do uso de parnteses que eles invocam um novo Shell para executar os comandos que esto em seu interior. Desta forma, fomos realmente para o diretrio /etc, porm aps a execuo de todos os comandos, o novo Shell que estava no diretrio /etc morreu e retornamos ao Shell anterior que estava em /home/meudir. Que tal usar nossos novos conceitos?
$ mail suporte@linux.br << FIM Ola suporte, hoje as `date U +%hh:mm` ocorreu novamente U aquele problema que eu havia U reportado por telefone. De U acordo com seu pedido segue a U listagem do diretorio: `ls -l` Abracos a todos. FIM
As aspas protegem da interpretao do Shell tudo que est dentro dos seus limites. Como para o Shell basta um espao em branco como separador, o monte de espaos ser trocado por um nico aps a retirada das aspas. Outra coisa interessante o uso do ponto-e-vrgula. Quando estiver no Shell, voc deve sempre dar um comando em cada linha. Para agrupar comandos em uma mesma linha, temos que separ-los por ponto-e-vrgula. Ento:
$ pwd ; cd /etc; pwd ;cd -;pwd /home/meudir /etc /home/meudir
O comando who passa a lista de usurios conectados ao sistema para o comando wc -l, que conta quantas linhas recebeu e mostra a resposta na tela. Muito bem, mas ao invs de ter um nmero oito solto na tela, o que eu quero mesmo que ele esteja no meio de uma frase. Ora, para mandar frases para a tela eu s preciso usar o comando echo; ento vamos ver como que fica:
Buraco Negro
Em Unix existe um arquivo fantasma. Chama-se /dev/null.Tudo que enviado para este arquivo some. Assemelha-se a um Buraco Negro. No caso do exemplo, como no me interessava guardar a possvel mensagem de erro oriunda do comando rm, redirecionei-a para este arquivo.
Neste exemplo, listei o nome do diretrio corrente com o comando pwd, mudei para o diretrio /etc, novamente listei o nome do diretrio e finalmente voltei para o diretrio onde estava anteriormente (cd -), listando seu nome. Repare que coloquei o ponto-e-vrgula de todas as formas possveis, para mostrar que no importa se existem espaos em branco antes ou aps este caracter. Finalmente, vamos ver o caso dos parnteses. No exemplo a seguir, colocamos diversos comandos separados por ponto-e-vrgula entre parnteses:
Finalmente agora podemos demonstrar o que conversamos anteriormente sobre here document. Os comandos entre crases tem prioridade, portanto o Shell os executar antes do redirecionamento do here document. Quando o suporte receber a mensagem, ver que os comandos date e ls foram executados antes do comando mail, recebendo ento um instantneo do ambiente no momento de envio do email. - Garom, passa a rgua! s
Julio Cezar Neves Analista de Suporte de Sistemas desde 1969 e trabalha com Unix desde 1980, quando fez parte da equipe que desenvolveu o SOX, sistema operacional, similar ao Unix, da Cobra Computadores. professor do curso de Mestrado em Software Livre das Faculdades Estcio de S, no Rio de Janeiro.
86
Agosto 2004
www.linuxmagazine.com.br
SOBRE O AUTOR