Curso de Shell

download Curso de Shell

If you can't read please download the document

description

curso de shell basico

Transcript of Curso de Shell

Curso de Shell - Aula I

Curso de Shell - Aula I Por: Alex Borro ( 25/12/2000 )

Introduo O que so os shell scripts? Shell scripts so conjuntos de comandos armazenados em um arquivo texto que so executados seqencialmente. Nesta primeira parte, faremos uma introduo sobre o shell, o formato desses arquivos e variveis de ambiente.O que Shell Shell, ou interpretador de comandos, o programa disparado logo aps o login responsvel por "pegar" os comandos do usurio, interpret-los e executar uma determinada ao. Por exemplo, quando voc escreve no console "ls" e pressiona , o shell l essa string e verifica se existe algum comando interno (embutido no prprio shell) com esse nome. Se houver, ele executa esse comando interno. Caso contrrio, ele vai procurar no PATH por algum programa que tenha esse nome. Se encontrar, ele executa esse programa, caso contrrio, ele retorna uma mensagem de erro. Para cada terminal ou console aberto, existe um shell sendo executado. Quando voc entra no seu Linux, ele apresenta o login, para digitar o usurio e a senha. Ao digitar um par usurio/senha correto, o Linux abre automaticamente um shell, que vai ficar esperando seus comandos. Veja o exemplo abaixo: Welcome to Linux Slackware 7.1 kernel 2.2.16. matrix login: neo Password: Linux 2.2.16. Last login: Mon Sep 25 10:41:12 -0300 2000 on tty1. No mail. neo@matrix:~$ Essa ultima linha o shell. Se voc der o comando "ps", vai ver que um dos programas rodando o seu shell:neo@matrix:~$ ps PID TTY TIME CMD 164 tty2 00:00:00 bash 213 tty2 00:00:00 ps neo@matrix:~$ Ou seja, o shell utilizado nesse console o bash, que est rodando com PID 164.Existem diversos tipos de shell: bash, csh, ksh, ash, etc. O mais utilizado atualmente o bash (GNU Bourne-Again SHell). Por isso, tomaremos ele como referncia.Resumindo essa seo, importante saber que para cada terminal ou console aberto, tem-se um shell rodando. Assim, se voc tem 3 xterms abertos na interface grfica, vai ter um shell para cada xterm.Ao executar o shell script, o shell atual (no qual voc deu o comando) abre um novo shell para executar o script. Assim, os scripts so executados em um shell prprio (a menos que se especifique, ao chamar o script, para execut-lo no shell atual). Isso ser importante quando formos tratar de variveis de ambiente.

Variveis do ambiente Uma varivel onde o shell armazena determinados valores para utilizao posterior.Toda varivel possui um nome e um valor associado a ela, podendo ser este ltimo vazio. Para listar as variveis atualmente definidas no shell digite o comando set .Para se definir uma varivel, basta utilizar a sntaxe: nome_da_varivel=valor . Por exemplo, queremos definir uma varivel chamada "cor" com o valor de "azul":neo@matrix:~$ cor=azul Para utilizar o valor de uma varivel, s colocar um sinal de "$" seguido do nome da varivel - o shell automaticamente substitui pelo valor da varivel:neo@matrix:~$ echo cor cor neo@matrix:~$ echo $cor azul Em alguns casos, aconselhvel colocar o nome da varivel entre chaves ({}). Por exemplo, se eu quero imprimir "azul-escuro", como faria? Simplesmente echo $cor-escuro ?? No funcionaria, pois o bash vai procurar uma varivel de nome "cor-escuro". Portanto, temos que colocar o nome "cor" entre chaves para delimitar o nome da varivel:neo@matrix:~$ echo ${cor}-escuro azul-escuro Algumas variveis j so predefinidas no shell, como o PATH, que, como foi dito antes, armazena o caminho dos programas. Por exemplo, a minha varivel PATH contm:neo@matrix:~$ echo $PATH /usr/local/bin:/usr/bin: /bin: /usr/X11R6/bin: /usr/openwin/bin: /usr/games: /opt/kde/bin: /usr/share/texmf/bin: /etc/script Ou seja, quando digito um comando, como "ls", o shell vai comear a procur-lo em /usr/local/bin, se no encontr-lo, vai procurar em /usr/bin e assim por diante. Repare que os diretrios so separados por um sinal de dois pontos (:). importante destacar que o shell possui vrias variveis pr-definidas, ou seja, que possuem um significado especial para ele, entre elas: PATH, PWD, PS1, PS2, USER e UID.Assim, quando iniciamos um novo shell (ao executar o nosso script), essas variveis especiais so "herdadas" do shell pai (o que executou o shell filho). Outras variveis definidas pelo usurio, como a varivel "cor" no so passadas do shell pai para o filho.Quando o script terminar, o seu shell (shell filho) simplesmente desaparece e com ele tambm as suas variveis, liberando o espao ocupado na memria.

Formato dos arquivos de Shell Script A primeira linha de todo shell script deve comear 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 .Como usaremos o bash como nosso shell de referncia, todas as linhas dos nossos scripts comearo com #!/bin/bash Digamos que voc executa freqentemente o comando: find / -name file -print , que procura na raiz (/) por um arquivo de nome "file". S que chato ficar digitando esse comando toda vez que se quer procurar um arquivo.Ento vamos criar um shell script que contenha esse comando. Vamos chamar esse shell script de "procura". Seu contedo fica assim:#!/bin/bash find / -name file -print Pronto. Tornemos agora o arquivo executvel: chmod 755 ./procura . Porm, ao tentar executar o nosso script, teremos um problema../procura Este script ir procurar por um arquivo chamado "file".Como especificar qual arquivo queremos procurar? Seria ideal executarmos o nosso script seguido do nome do arquivo que queremos procurar.Por exemplo, queremos saber onde est o arquivo "netscape": ./procura netscape . ai que entram as "variveis de parmetro". Vamos substituir no nosso script a linha find / -name file -print por find / -name $1 -print .Quando o bash l a varivel "$1", ele a substitui pelo primeiro parmetro passado na linha de comando para o nosso script. Ento, se executamos ./procura netscape , a varivel "$1" ser substituda por "netscape", como a gente queria. Repare que a varivel "$2" conteria o segundo parmetro passado para o script e assim por diante.Sendo assim, qualquer comando colocado abaixo de find seria executado aps ele. Esse o essencial do shell script: poder automatizar a execuo de programas e comandos como se estivessem sendo digitados diretamente no console ou terminal.Concluso Na prxima aula do nosso curso de shell script iremos aprender alguns comandos especiais para tornar nossos script mais poderosos, fazendo coisas mais elaboradas do que apenas executar programas seqencialmente. Entre eles, podemos destacar os comandos de lao, como "if", "for", "while", "case" etc. Curso de Shell - Aula II Por: Alex Borro ( 26/12/2000 )

Introduo Na aula de hoje vamos falar sobre execuo de programas em primeiro plano (fg - foreground) e em segundo plano (bg - background), redirecionamento de sadas e tambm sobre os cdigos de escape dos programas.Execuo em foreground e background 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 execuo em primeiro plano, ou foreground, em ingls.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 aps isso vamos ter a linha de comando de volta para podermos continuar trabalhando.E se pudssemos dizer ao shell para executar um programa e nos retornar a linha de comando sem ficar esperando o tal programa terminar? Seria muito melhor, no? Em alguns casos seria. E podemos fazer isso.Uma maneira fcil colocar o sinal de & depois de um comando. No exemplo acima ficaria:neo@matrix:~$ cp arquivo1 arquivo2 & [1] 206 neo@matrix:~$Pronto, assim que teclarmos [enter], teremos a nossa linha de comando de volta e mais duas informaes: "[1] 206".A primeira informao ([1]) chama-se job. Ela identifica os programas que esto sendo executados em bg (background). Por exemplo, se executarmos mais um programa em bg enquanto este "cp" est sendo executado, o novo programa recebe o job de nmero 2 ([2]) e assim por diante.A segunda informao (206) o pid do programa, ou seja, o nmero de processo que o kernel d a esse programa.Mas a temos um pequeno problema. Digamos que voc queira trazer o programa para fg, por exemplo, se o programa executado em bg for um tocador de mp3 e voc quiser mudar a msica. Como fazemos? Usamos o comando fg [job] (intuitivo, no ?) do bash. No exemplo acima, digamos que eu execute o "cp" em bg, mas depois queira traz-lo para fg para cancel-lo. Seria simples:neo@matrix:~$ cp arquivo1 arquivo2 & [1] 206 neo@matrix:~$ fg 1 cp arquivo1 arquivo2Assim trazemos o "cp" para primeiro plano e a linha de comando s retorna quando ele terminar.OpcionalUma outra maneira de colocar um programa para rodar em bg utilizando um truque do bash (no sei se esta opo est disponvel em outros shells).Digamos que voc execute o comando "cp" e esquea de colocar o sinal "&". E a? Tem que ficar esperando acabar ou cancelar o comando? No, podemos teclar: Ctrl + Z.Ao fazer isso, paramos a execuo do programa. Ento s dar o comando bg [job] (intuitivo tambm, n?):neo@matrix:~$ cp arquivo1 arquivo2* aqui teclamos Ctrl + Z * [1]+ Stopped cp -i arquivo1 arquivo2 neo@matrix:~$ bg 1 [1]+ cp -i arquivo1 arquivo2 & neo@matrix:~$Quando teclamos o Ctrl + Z, o bash nos diz que o job 1 foi parado ([1]+ Stopped) e quando executamos "bg 1" ele nos diz que o comando voltou a ser executado, mas em bg (repare o sinal de "&" no final da linha): [1]+ cp -i arquivo1 arquivo2 &.

Redirecionamento de sadas Muitos programas que executamos geram sadas no console, ou sejam, emitem mensagens para os usurios. Por exemplo, queremos achar quantos arquivos no nosso sistema tem "netscape" no nome:neo@matrix:~$ find / -name netscape /usr/lib/netscape /usr/lib/netscape/netscape /usr/lib/netscape/nethelp/netscape /usr/local/bin/netscapeAgora se quisermos procurar quantos arquivos compactados com o gzip (extenso .gz) tem no nosso sistema para depois analis-los e possivelmente apagar os repetidos ou inteis, teremos uma lista muito grande. Aqui no meu sistema deu mais de 1000 arquivos. Ento, seria til podermos enviar as mensagens que vo para o console, para um arquivo. Assim, poderamos analis-lo depois de executar o comando. Isso extremamente til ao trabalharmos com shell script - enviar as sadas dos comandos para arquivos para depois analis-las. Exemplificando:neo@matrix:~$ find / -name "*.gz" > lista.txt find: /home/vera: Permisso negada find: /home/pri: Permisso negada find: /root: Permisso negada neo@matrix:~$Notamos que nem tudo foi para o arquivo lista.txt. As mensagens de erro foram para o console.Isso porque existem dois tipos de sada: a sada padro e a sada de erro.A sada padro a sada normal dos programas, que no caso acima, seria os arquivos encontrados. E a sada de erro, como o prprio nome diz, so os erro encontrados pelo programa durante sua execuo, que devem ser informados ao usurio, como os erros de "permisso negada".E a, como selecionar uma ou outra? simples, apenas devemos indicar o "file descriptor" (fd) delas. No vamos entrar em detalhes sobre o que "descritor de arquivos" por fugir do nosso escopo e ser um pouco complicado, apenas temos que saber que o fd 1 corresponde a sada padro e o fd 2 a sada de erro. Assim, no exemplo acima, para enviar os erro para o arquivo erros.txt e a sada padro para o arquivo lista.txt, usaramos:neo@matrix:~$ find / -name "*.gz" 1> lista.txt 2> erros.txtOu seja, s por o nmero da sada desejada antes do sinal de ">".Agora digamos que queremos ver o contedo do arquivo lista.txt. Podemos abr-lo com um editor de textos ou usar o "cat". Optando pela ltima opo:neo@matrix:~$ cat lista.txt /home/neo/gkrellm-0.10.5.tar.gz /home/neo/linuxcall-interface-beta.tar.gz ... erros.txt | tee lista.txtO que fizemos???Primeiro pegamos a sada de erro e enviamos para o arquivo erros.txt. O restante, ou seja, a sada padro, estamos enviando para a entrada do comando tee (usando o pipe). O tee simplesmente pega o que ele recebe (atravs do pipe) e joga no arquivo lista.txt e na tela. Assim, alm de gravarmos a sada num arquivo, podemos mostrar ao usurio o que est acontecendo. Isso muito til quando escrevemos alguns scripts.Resumindo: aprendemos que podemos redirecionar a sada padro ou de erro de programa para um arquivo usando respectivamente "1>" ou "2>" ou tambm enviar a sada para a entrada de outro programa usando o pipe "|".

Cdigos de Escape Toda vez que executamos um programa em Unix, ele retorna um cdigo de escape ao finalizar. Esse cdigo reflete a condio em que o programa finalizou. Se ocorreu tudo certo e o programa terminou normalmente, ele retorna 0. Se ocorreu algum problema, o programa retorna um cdigo diferente de 0, geralmente variando com o problema ocorrido.Esse cdigo de retorno extremamente importante em shell script, pois assim que testamos se uma certa ao ocorreu bem ou teve problemas.Esse cdigo armazenado pelo bash numa varivel chamada "?" (isso mesmo, somente o sinal de interrogao ;-)).Por exemplo, vamos executar um "ls" em um diretrio que existe e ver o cdigo de retorno:neo@matrix:~$ ls /boot System.map boot.0300 boot.b boot_message.txt chain.b config map os2_d.b neo@matrix:~$ echo $? 0 neo@matrix:~$Ou seja, o "ls" foi executado normalmente, retornando 0. Agora vamos execut-lo num diretrio que no existe:neo@matrix:~$ ls /diretorio_invalido /bin/ls: /diretorio_invalido: Arquivo ou diretrio no encontrado neo@matrix:~$ echo $? 1 neo@matrix:~$Como esperado, obtemos o retorno de erro 1.Alguns programas tem muitos cdigos de retorno. Por exemplo, os cdigos de retorno do "pppd" vo at o 19. Assim possvel saber porque ele foi finalizado. Se voc colocar uma senha errada no pppd e tentar conectar, ele vai terminar com o cdigo 19.man pppd ... 17 The PPP negotiation failed because serial loopback was detected. 18 The init script failed (returned a non-zero exit status). 19 We failed to authenticate ourselves to the peer. ...Um detalhe importante: quando executamos um programa em background, ele sempre retorna um cdigo 0 para o shell, mesmo que durante sua execuo ocorra algum problema. Assim, quando executamos um programa em bg, perdemos essa facilidade de testar como foi seu trmino.neo@matrix:~$ ls /diretorio_invalido & [1] 230 neo@matrix:~$ /bin/ls: /diretorio_invalido: Arquivo ou diretrio no encontrado[1]+ Exit 1 /bin/ls $LS_OPTIONS /diretorio_invalido neo@matrix:~$ echo $? 0Como vemos, ao terminar, ele emite uma mensagem dizendo que finalizou com cdigo 1 ([1]+ Exit 1) mas quando testamos a varivel "?", o bash nos diz "0".Concluso Como todos os programas tem que terminar com um cdigo de retorno que tenha algum significado, nossos shell scripts tambm tero que finalizar indicando o que aconteceu, se ocorreu tudo bem ou se ouve erro. Mas isso discutiremos melhor mais pra frente.O importante aqui saber que todos os programas terminam com um cdigo de retorno, os quais usaremos nos nossos scripts para testar o trmino dos programas.

Curso de Shell - Aula III Por: Alex Borro ( 27/03/2001 )

Introduo Nesta terceira parte do nosso curso de shell script, vamos tratar de "condicionais".Condicionais so comandos que avaliam uma expresso. Se ela for verdadeira, uma determinada rotina executada. Caso contrrio, outra rotina pode ser executada.O famoso "if" O bash nos oferece, entre outros, o comando IF (ele um comando embutido no bash e no um programa como o "ls", o "cp" etc.). A forma mais simples de representar uma condicional utilizando o IF, da seguinte forma bsica:if [condio]; then comandos1; else comandos2; fi; Se [condio] for verdadeira, os comandos1 so executados. Se for falsa, os comandos2 so executados.Mas para o IF, o que uma condio verdadeira ou uma falsa?Como foi explicado na aula anterior, TODO comando em Unix tem um cdigo de retorno. Geralmente o cdigo "0" (zero) significa que o comando foi executado perfeitamente e terminou bem. Cdigos maiores que zero significam que alguma coisa de errado ocorreu. assim que o IF verifica uma condio. Se o seu cdigo de retorno for zero, ento ela considerada verdadeira. Caso contrario, ela falsa.Mas ento a [condio] tem que ser um comando, certo? Exatamente. Vamos exemplificar:neo@matrix:~$ if ls /boot; then echo "O diretrio existe."; else echo "Diretrio invlido."; fi; System.map boot.0300 boot.b boot_message.txt chain.b config map os2_d.b O diretrio existe. O que fizemos?Logo aps o if, ns colocamos um comando: "ls /boot". O que o IF faz? Ele executa esse comando (por isso que temos a segunda linha comeada por "System.map", que o contedo do meu diretrio /boot) e avalia o seu cdigo de sada. Como o "ls" foi executado corretamente, ele retorna zero, significando verdadeiro para o IF, que executa o comando logo aps o "then", ou seja, o echo "O diretrio existe.", mostrando essa mensagem no console.Agora vamos colocar um diretrio que no existe:neo@matrix:~$ if ls /dir_invalido; then echo "O diretrio existe."; else echo "Diretrio invlido."; fi; /bin/ls: /dir_invalido: Arquivo ou diretrio no encontrado Diretrio invlido. A lgica a mesma. Executa o "ls /dir_invalido", que retorna um cdigo maior que zero. O IF avalia como falso e executa o comando aps o else: echo "Diretrio invlido".Ns poderamos omitir a segunda linha dos dois exemplo (a que mostra o contedo de /boot no primeiro exemplo e a mensagem de erro emitida pelo ls dizendo que /dir_invalido no existe no segundo), apenas redirecionando as sadas para /dev/null, ou seja:neo@matrix:~$ ls /boot 1> /dev/null 2> /dev/null Nota: Tem um macete que possui o mesmo efeito. Em vez de colocar: "1> /dev/null 2> /dev/null" podemos colocar "2&>1", que menor e mais simples.

O comando "test" Bom, aprendemos que o IF avalia a cdigo de retorno de um comando. Mas muitas vezes, para no dizer a maioria, ns queremos avaliar "expresses", ou seja, verificar se uma varivel igual a outra, se ela esta vazia etc.Para isso, ns temos outro comando chamado "test" (intuitivo o nome, no?). Ele funciona da seguinte maneira: test [expresso].O test pode testar operaes de trs tipos: strings, arquivos e aritmticas.Expresses usando strings: O test pode apenas comparar strings, ou seja, verificar se uma igual a outra, e verificar se uma string vazia ou no. Vamos aos exemplos para facilitar o entendimento:neo@matrix:~$ test "a" = "a" neo@matrix:~$ echo $? 0 neo@matrix:~$ test "a" = "b" neo@matrix:~$ echo $? 1 neo@matrix:~$ test "a" != "b" neo@matrix:~$ echo $? 0 Aqui comparamos a string "a" com "b". Como era de se esperar, o primeiro retornou verdadeiro (zero), pois a = a e o segundo retornou falso. No terceiro, o smbolo "!=" significa "diferente".neo@matrix:~$ test -z "neo" neo@matrix:~$ echo $? 1 neo@matrix:~$ test -z "" neo@matrix:~$ echo $? 0 neo@matrix:~$ test -n "neo" neo@matrix:~$ echo $? 0 neo@matrix:~$ test -n "" neo@matrix:~$ echo $? 1 Acima temos os testes de vazio. A opo "-z" verifica se vazio, e "-n" se no vazio. No primeiro caso, ele testa se "neo" uma string vazia, retornando falso. J no segundo caso, como "" vazia, retorna verdadeiro. O terceiro e quarto so semelhantes aos primeiros, mas com "-n".Expresses com arquivos: Os testes que podem ser feitos com arquivos so para verificar determinadas caracteristicas, como se ele existe, se executavel, se um link simblico, se um diretrio etc.Alguns exemplos:A opo "-e" verifica apenas se um arquivo existe e a opo "-d" verifica se o arquivo um diretrio.A opo "-nt" verifica se o primeiro arquivo mais novo que o segundo (nt = newer than) e "-ot" verifica se o primeiro mais velho que o segundo (od = older than):neo@matrix:~$ test -e /vmlinuz neo@matrix:~$ echo $? 0 neo@matrix:~$ test -d /vmlinuz neo@matrix:~$ echo $? 1 neo@matrix:~$ test -e /usr neo@matrix:~$ echo $? 0 neo@matrix:~$ test -d /usr neo@matrix:~$ echo $? 0 neo@matrix:~$ test /usr -nt /vmlinuz neo@matrix:~$ echo $? 0 neo@matrix:~$ test /usr -ot /vmlinuz neo@matrix:~$ echo $? 1

O comando "test" (continuao) A seguir, temos uma lista de vrias opes disponveis:-b arquivo - Verdadeiro se arquivo um arquivo de bloco, como /dev/hda. -c arquivo - Verdadeiro se arquivo um arquivo de caracter, como /dev/tty1. -d arquivo - Verdadeiro se arquivo um diretrio. -e arquivo - Verdadeiro se arquivo existe. -f arquivo - Verdadeiro se arquivo existe e um arquivo comum. -s arquivo - Verdadeiro se arquivo existe e no vazio. -h arquivo - Verdadeiro se arquivo um link simblico. -p arquivo - Verdadeiro se arquivo um "named pipe" (fifo, lifo, etc). -S arquivo - Verdadeiro se arquivo um "socket". -k arquivo - Verdadeiro se arquivo tem seu "sticky bit" ligado. -r arquivo - Verdadeiro se arquivo pode ser lido pelo usurio atual. -w arquivo - Verdadeiro se arquivo pode ser escrito pelo usurio atual. -x arquivo - Verdadeiro se arquivo pode ser executado pelo usurio atual. -O arquivo - Verdadeiro se arquivo pertence ao usurio atual. -G arquivo - Verdadeiro se arquivo pertence ao grupo do usurio atual. -N arquivo - Verdadeiro se arquivo foi modificado desde a ultima vez que foi lido.

Expresses Aritmticas Expresses aritmticas consistem com comparar dois nmeros, verificando se so iguais, ou se o primeiro maior que o segundo etc.Infelizmente no podemos apenas utilizar os smbolos conhecidos para igual (=), maior que (>), menor que (