SlideShare uma empresa Scribd logo
1 de 55
Baixar para ler offline
LINUX USER                Papo de Botequim




Curso de Shell Script


Papo de Botequim
Você não agüenta mais aquele seu                                                                    porque, em inglês, Shell significa con-
                                                                                                       cha, carapaça, isto é, fica entre o u-
amigo usuário de Linux enchendo o                                                                        suário e o sistema operacional, de
                                                                                                           forma que tudo que interage com
seu saco com aquela história de que o                                                                       o sistema operacional, tem que
                                                                                                             passar pelo seu crivo.
sistema é fantástico e o Shell é uma

ferramenta maravilhosa? A partir
                                                                                                                O ambiente Shell
                                                                                                                 Bom já que para chegar ao
desta edição vai ficar mais fácil en-                                                                            núcleo do Linux, no seu ker-
                                                                                                                nel que é o que interessa a
tender o porquê deste entusiasmo...                                                                            todo aplicativo, é necessária a
                                                                                                             filtragem do Shell, vamos enten-
POR JULIO CEZAR NEVES                                                                                       der como ele funciona de forma a
                                                                                                         tirar o máximo proveito das inú-
                                                                                                      meras facilidades que ele nos oferece.


D
        iálogo entreouvido em uma mesa                                                                 O Linux, por definição, é um sistema
        de um botequim, entre um                                                                    multiusuário – não podemos nunca nos
        usuário de Linux e um empur-                                                                esquecer disto – e para permitir o acesso
rador de mouse:                                     O ambiente Linux                                de determinados usuários e barrar a en-
• Quem é o Bash?                                    Para você entender o que é e como fun-          trada de outros, existe um arquivo cha-
• É o filho caçula da família Shell.                ciona o Shell, primeiro vou te mostrar          mado /etc/passwd, que além de fornecer
• Pô cara! Estás a fim de me deixar                 como funciona o ambiente em camadas             dados para esta função de “leão-de-chá-
  maluco? Eu tinha uma dúvida e você                do Linux. Dê uma olhada no gráfico              cara” do Linux, também provê informa-
  me deixa com duas!                                mostrado na Figura 1.                           ções para o início de uma sessão (ou
• Não, maluco você já é há muito tem-                  Neste gráfico podemos ver que a ca-          “login”, para os íntimos) daqueles que
  po: desde que decidiu usar aquele sis-            mada de hardware é a mais profunda e é          passaram por esta primeira barreira. O
  tema operacional que você precisa                 formada pelos componentes físicos do            último campo de seus registros informa
  reiniciar dez vezes por dia e ainda por           seu computador. Em torno dela, vem a            ao sistema qual é o Shell que a pessoa
  cima não tem domínio nenhum sobre                 camada do kernel que é o cerne do               vai receber ao iniciar sua sessão.
  o que esta acontecendo no seu com-                Linux, seu núcleo, e é quem põe o hard-            Lembra que eu te falei de Shell, fa-
  putador. Mas deixa isso prá lá, pois              ware para funcionar, fazendo seu geren-         mília, irmão? Pois é, vamos começar a
  vou te explicar o que é Shell e os com-           ciamento e controle. Os programas e             entender isto: o Shell é a conceituação
  ponentes de sua família e ao final da             comandos que envolvem o kernel, dele            de concha envolvendo o sistema opera-
  nossa conversa você dirá: “Meu Deus               se utilizam para realizar as tarefas para       cional propriamente dito, é o nome
  do Shell! Porque eu não optei pelo                que foram desenvolvidos. Fechando tudo          genérico para tratar os filhos desta idéia
  Linux antes?”.                                    isso vem o Shell, que leva este nome            que, ao longo dos muitos anos de exis-

                            Quadro 1: Uma rapidinha nos principais sabores de Shell
 Bourne Shell (sh): Desenvolvido por Stephen         do sh e a elas agregou muitas outras. A com-    C Shell (csh): Desenvolvido por Bill Joy, da
 Bourne do Bell Labs (da AT&T, onde também           patibilidade total com o sh vem trazendo        Universidade de Berkley, é o Shell mais uti-
 foi desenvolvido o Unix), foi durante muitos        muitos usuários e programadores de Shell        lizado em ambientes BSD. Foi ele quem intro-
 anos o Shell padrão do sistema operacional          para este ambiente.                             duziu o histórico de comandos. A
 Unix. É também chamado de Standard Shell            Boune Again Shell (bash): Desenvolvido ini-     estruturação de seus comandos é bem simi-
 por ter sido durante vários anos o único, e é       cialmente por Brian Fox e Chet Ramey, este é    lar à da linguagem C. Seu grande pecado foi
 até hoje o mais utilizado. Foi portado para         o Shell do projeto GNU. O número de seus        ignorar a compatibilidade com o sh, partindo
 praticamente todos os ambientes Unix e dis-         adeptos é o que mais cresce em todo o           por um caminho próprio.
 tribuições Linux.                                   mundo, seja por que ele é o Shell padrão do     Além destes Shells existem outros, mas irei
 Korn Shell (ksh): Desenvolvido por David            Linux, seja por sua grande diversidade de       falar somente sobre os três primeiros, tratan-
 Korn, também do Bell Labs, é um supercon-           comandos, que incorpora inclusive diversos      do-os genericamente por Shell e assinalando
 junto do sh, isto é, possui todas as facilidades    comandos característicos do C Shell.            as especificidades de cada um.




82         Agosto 2004            www.linuxmagazine.com.br
Papo de Botequim               LINUX USER




tência do sistema operacional Unix,                                                                  redirecionamento, que pode ser de
foram aparecendo. Atualmente existem
                                                  Com que Shell eu vou?                              entrada (stdin), de saída (stdout) ou dos
                                                Quando digo que o último campo do arqui-
diversos sabores de Shell (veja Quadro 1                                                             erros (stderr), conforme vou explicar a
                                                vo /etc/passwd informa ao sistema qual é o
na página anterior).                                                                                 seguir. Mas antes precisamos falar de...
                                                Shell que o usuário vai usar ao se “logar”, isto
                                                deve ser interpretado ao pé-da-letra. Se este
Como funciona o Shell                           campo do seu registro contém o termo prog,           Substituição de Variáveis
O Shell é o primeiro programa que você          ao acessar o sistema o usuário executará o           Neste ponto, o Shell verifica se as even-
ganha ao iniciar sua sessão (se quiser-         programa prog. Ao término da execução, a             tuais variáveis (parâmetros começados
mos assassinar a língua portuguesa              sessão do usuário se encerra automatica-             por $), encontradas no escopo do
                                                mente. Imagine quanto se pode incremen-
podemos também dizer “ao se logar”) no                                                               comando, estão definidas e as substitui
                                                tar a segurança com este simples artifício.
Linux. É ele quem vai resolver um monte                                                              por seus valores atuais.
de coisas de forma a não onerar o kernel
com tarefas repetitivas, poupando-o para      volvidos (inclusive o próprio programa),               Substituição de Meta-
tratar assuntos mais nobres. Como cada        e retorna um erro caso o usuário que                   Caracteres
usuário possui o seu próprio Shell inter-     chamou o programa não esteja autor-                    Se algum meta-caracter (ou “coringa”,
pondo-se entre ele e o Linux, é o Shell       izado a executar esta tarefa.                          como *, ? ou []) for encontrado na linha
quem interpreta os comandos digitados e                                                              de comando, ele será substituído por
examina as suas sintaxes, passando-os          $ ls linux                                            seus possíveis valores.
esmiuçados para execução.                      linux                                                   Supondo que o único item no seu
• Êpa! Esse negócio de interpretar co-                                                               diretório corrente cujo nome começa
   mando não tem nada a ver com inter-        Neste exemplo o Shell identificou o ls co-             com a letra n seja um diretório chamado
   pretador não, né?                          mo um programa e o linux como um pa-                   nomegrandeprachuchu, se você fizer:
• Tem sim: na verdade o Shell é um in-        râmetro passado para o programa ls.
   terpretador que traz consigo uma po-                                                               $ cd n*
   derosa linguagem com comandos de           Atribuição
   alto nível, que permite construção de      Se o Shell encontra dois campos separa-                como até aqui quem está manipulando a
   loops, de tomadas de decisão e de ar-      dos por um sinal de igual (=) sem espa-                linha de comando ainda é o Shell e o
   mazenamento de valores em variáveis,       ços em branco entre eles, ele identifica               programa cd ainda não foi executado, o
   como vou te mostrar.                       esta seqüência como uma atribuição.                    Shell expande o n* para nomegrandepra-
• Vou explicar as principais tarefas que o                                                           chuchu (a única possibilidade válida) e
   Shell cumpre, na sua ordem de exe-          $ valor=1000                                          executa o comando cd com sucesso.
   cução. Preste atenção, porque esta
   ordem é fundamental para o entendi-        Neste caso, por não haver espaços em                   Entrega da linha de comando
   mento do resto do nosso bate papo.         branco (que é um dos caracteres reserva-               para o kernel
                                              dos), o Shell identificou uma atribuição e             Completadas todas as tarefas anteriores,
Análise da linha de comando                   colocou 1000 na variável valor.                        o Shell monta a linha de comando, já
Neste exame o Shell identifica os carac-                                                             com todas as substituições feitas e
teres especiais (reservados) que têm sig-     Resolução de                                           chama o kernel para executá-la em um
nificado para a interpretação da linha e      Redirecionamentos                                      novo Shell (Shell filho), que ganha um
logo em seguida verifica se a linha pas-      Após identificar os componentes da li-                 número de processo (PID ou Process
sada é um comando ou uma atribuição           nha que você digitou, o Shell parte para               IDentification) e fica inativo, tirando
de valores, que são os ítens que vou          a resolução de redirecionamentos.                      uma soneca durante a execução do pro-
descrever a seguir.                              O Shell tem incorporado ao seu elenco               grama. Uma vez encerrado este processo
                                              de habilidades o que chamamos de                       (e o Shell filho), o “Shell pai” recebe
Comando                                                                                              novamente o controle e exibe um
Quando um comando é digi-                                                                            “prompt”, mostrando que está pronto
tado no “prompt” (ou linha de                         Shell                                          para executar outros comandos.
comando) do Linux, ele é divi-
dido em partes, separadas por
                                              Programas e Comandos                                       Cuidado na Atribuição
espaços em branco: a primeira                    Núcleo ou Kernel                                      Jamais faça:
parte é o nome do programa,
cuja existência será verificada;                    Hardware                                           $ valor = 1000
                                                                                                       bash: valor: not found
em seguida, nesta ordem, vêm
                                                                                                       Neste caso, o Bash achou a palavra valor iso-
as opções/parâmetros, redire-
                                                                                                       lada por espaços e julgou que você estivesse
cionamentos e variáveis.
                                                                                                       mandando executar um programa chama-
  Quando o programa identifi-
                                                                                                       do valor, para o qual estaria passando dois
cado existe, o Shell verifica as                                                                       parâmetros: = e 1000.
permissões dos arquivos en-        Figura 1: Ambiente em camadas de um sistema Linux




                                                                                           www.linuxmagazine.com.br        Agosto 2004             83
LINUX USER            Papo de Botequim




Decifrando a Pedra de Roseta                    $ echo *                                       esperando pelo teclado (Entrada Padrão)
Para tirar aquela sensação que você tem         $ echo *                                        e como também não citei a saída, o que
quando vê um script Shell, que mais                                                             eu teclar irá para a tela (Saída Padrão),
parece uma sopa de letrinhas ou um con-         Viu a diferença?                                criando desta forma – como eu havia
junto de hieróglifos, vou lhe mostrar os      • Aspas (“): exatamente iguais ao após-           proposto – um programa gago. Experi-
principais caracteres especiais para que        trofo, exceto que, se a cadeia entre            mente!
você saia por aí como Champollion deci-         aspas contiver um cifrão ($), uma
frando a Pedra de Roseta.                       crase (`), ou uma barra invertida (),          Redirecionamentop da Saída
                                                estes caracteres serão interpretados            Padrão
Caracteres para remoção do                      pelo Shell.                                     Para especificarmos a saída de um pro-
significado.                                    Não precisa se estressar, eu não te dei         grama usamos o símbolo “>” ou o
É isso mesmo, quando não desejamos              exemplos do uso das aspas por que               “>>”, seguido do nome do arquivo pa-
que o Shell interprete um caractere             você ainda não conhece o cifrão ($)             ra o qual se deseja mandar a saída.
específico, devemos “escondê-lo” dele.          nem a crase (`). Daqui para frente -               Vamos transformar o programa ante-
Isso pode ser feito de três maneiras difer-     veremos com muita constância o uso              rior em um “editor de textos”:
entes, cada uma com sua peculiaridade:          destes caracteres especiais; o mais
• Apóstrofo (´): quando o Shell vê uma          importante é entender seu significado.           $ cat > Arq
  cadeia de caracteres entre apóstrofos,
  ele retira os apóstrofos da cadeia e não    Caracteres de                                     O cat continua sem ter a entrada especi-
  interpreta seu conteúdo.                    redirecionamento                                  ficada, portanto está aguardando que os
                                              A maioria dos comandos tem uma entra-             dados sejam teclados, porém a sua saída
 $ ls linuxm*                                 da, uma saída e pode gerar erros. Esta            está sendo desviada para o arquivo Arq.
 linuxmagazine                                entrada é chamada Entrada Padrão ou               Assim sendo, tudo que esta sendo tecla-
 $ ls 'linuxm*'                               stdin e seu dispositivo padrão é o teclado        do esta indo para dentro de Arq, de for-
 bash: linuxm* no such file U                 do terminal. Analogamente, a saída do             ma que fizemos o editor de textos mais
 or directory                                 comando é chamada Saída Padrão ou                 curto e ruim do planeta.
                                              stdout e seu dispositivo padrão é a tela             Se eu fizer novamente:
  No primeiro caso o Shell “expandiu” o       do terminal. Para a tela também são
  asterisco e descobriu o arquivo linux-      enviadas normalmente as mensagens de               $ cat > Arq
  magazine para listar. No segundo, os        erro oriundas dos comandos, chamada
  apóstrofos inibiram a interpretação do      neste caso de Saída de Erro Padrão ou             Os dados contidos em Arq serão perdi-
  Shell e veio a resposta que não existe o    stderr. Veremos agora como alterar este           dos, já que antes do redirecionamento o
  arquivo linuxm*.                            estado de coisas.                                 Shell criará um Arq vazio. Para colocar
• Contrabarra ou Barra Invertida (): i-         Vamos fazer um programa gago. Para             mais informações no final do arquivo eu
  dêntico aos apóstrofos exceto que a         isto digite (tecle “Enter” ao final de cada       deveria ter feito:
  barra invertida inibe a interpretação       linha – comandos do usuário são ilus-
  somente do caractere que a segue.           trados em negrito):                                $ cat >> Arq
  Suponha que você, acidentalmente,
  tenha criado um arquivo chamado *             $ cat                                           Redirecionamento da Saída
  (asterisco) – o que alguns sabores de         E-e-eu sou gago. Vai encarar?                   de Erro Padrão
  Unix permitem – e deseja removê-lo.           E-e-eu sou gago. Vai encarar?                   Assim como por padrão o Shell recebe os
  Se você fizesse:                                                                              dados do teclado e envia a saída para a
                                              O cat é um comando que lista o con-               tela, os erros também vão para a tela se
 $ rm *                                       teúdo do arquivo especificado para a              você não especificar para onde eles de-
                                              Saída Padrão (stdout). Caso a entrada             vem ser enviados. Para redirecionar os
  Você estaria na maior encrenca, pois o      não seja definida, ele espera os dados da         erros, use 2> SaidaDeErro. Note que en-
  rm removeria todos os arquivos do           stdin (a entrada padrão). Ora como eu             tre o número 2 e o sinal de maior (>)
  diretório corrente. A melhor forma de       não especifiquei a entrada, ele a está            não existe espaço em branco.
  fazer o serviço é:                                                                               Vamos supor que durante a execução
                                               Redirecionamento Perigoso                        de um script você pode, ou não (depen-
 $ rm *                                        Como já havia dito, o Shell resolve a linha e   dendo do rumo tomado pela execução
                                                depois manda o comando para a execução.         do programa), ter criado um arquivo
  Desta forma, o Shell não interpreta o         Assim, se você redirecionar a saída de um       chamado /tmp/seraqueexiste$$. Como
  asterisco, evitando a sua expansão.           arquivo para ele próprio, primeiramente o       não quer ficar com sujeira no disco
  Faça a seguinte experiência científica:       Shell “esvazia”este arquivo e depois manda      rígido, ao final do script você coloca a
                                                o comando para execução! Desta forma,           linha a seguir:
                                                para sua alegria, você acabou de perder o
 $ cd /etc
                                                conteúdo de seu querido arquivo.
 $ echo '*'                                                                                      rm /tmp/seraqueexiste$$




84         Agosto 2004       www.linuxmagazine.com.br
Papo de Botequim              LINUX USER




                                               caprichamos, né? Então ao invés de sair
         Dados ou Erros?                       redigindo o mail direto no “prompt”, de
                                                                                                         Etiquetas Erradas
 Preste atenção! Não confunda >> com 2>. O     forma a tornar impossível a correção de             Um erro comum no uso de labels (como o
 primeiro anexa dados ao final de um arqui-                                                        fimftp do exemplo anterior) é causado pela
                                               uma frase anterior onde, sem querer,
 vo, e o segundo redireciona a Saída de Erro                                                       presença de espaços em branco antes ou
                                               você escreveu um “nós vai”, você edita
 Padrão (stderr) para um arquivo que está                                                          após o mesmo. Fique muito atento quanto a
                                               um arquivo com o conteúdo da mensa-
 sendo designado. Isto é importante!                                                               isso, por que este tipo de erro costuma dar
                                               gem e após umas quinze verificações
                                                                                                   uma boa surra no programador, até que seja
                                               sem constatar nenhum erro, decide
                                                                                                   detectado. Lembre-se: um label que se preze
Caso o arquivo não existisse seria envi-       enviá-lo e para tal faz:
                                                                                                   tem que ter uma linha inteira só para ele.
ado para a tela uma mensagem de erro.
Para que isso não aconteça faça:                $ mail chefe@chefia.com.br < U
                                                arquivocommailparaochefe                           nada a partir deste ponto até encontrar
 rm /tmp/seraqueexiste$$ 2> U                                                                      o ‘label’ fimftp. Você não entenderia
 /dev/null                                     e o chefe receberá uma mensagem com o               droga nenhuma, já que são instruções
                                               conteúdo do arquivocommailparaochefe.               específicas do ftp”.
Para que você teste a Saída de Erro Pa-           Outro tipo de redirecionamento “muito               Se fosse só isso seria simples, mas
drão direto no prompt do seu Shell, vou        louco” que o Shell permite é o chamado              pelo próprio exemplo dá para ver que
dar mais um exemplo. Faça:                     “here document”. Ele é representado por             existem duas variáveis ($Usuario e
                                               << e serve para indicar ao Shell que o              $Senha), que o Shell vai resolver antes
 $ ls naoexiste                                escopo de um comando começa na linha                do redirecionamento. Mas a grande
 bash: naoexiste no such file U                seguinte e termina quando encontra uma              vantagem deste tipo de construção é
 or directory                                  linha cujo conteúdo seja unicamente o               que ela permite que comandos tam-
 $ ls naoexiste 2> arquivodeerros              “label” que segue o sinal <<.                       bém sejam interpretados dentro do
 $                                                Veja o fragmento de script a seguir,             escopo do “here document”, o que,
 $ cat arquivodeerros                          com uma rotina de ftp:                              aliás, contraria o que acabei de dizer.
 bash: naoexiste no such file U                                                                    Logo a seguir te explico como esse
 or directory                                   ftp -ivn hostremoto << fimftp                      negócio funciona. Agora ainda não dá,
                                                user $Usuario $Senha                               estão faltando ferramentas.
Neste exemplo, vimos que quando fize-           binary                                           • O comando user é do repertório de
mos um ls em naoexiste, ganhamos uma            get arquivoremoto                                  instruções do ftp e serve para passar o
mensagem de erro. Após redirecionar a           fimftp                                             usuário e a senha que haviam sido
Saída de Erro Padrão para arquivodeerros                                                           lidos em uma rotina anterior a este
e executar o mesmo comando, recebe-            neste pedacinho de programa temos um                fragmento de código e colocados res-
mos somente o “prompt” na tela. Quan-          monte de detalhes interessantes:                    pectivamente nas duas variáveis:
do listamos o conteúdo do arquivo para         • As opções usadas para o ftp (-ivn)                $Usuario e $Senha.
o qual foi redirecionada a Saída de Erro         servem para ele listar tudo que está            • O binary é outra instrução do ftp, que
Padrão, vimos que a mensagem de erro             acontecendo (opção -v de “verbose”),              serve para indicar que a transferência
tinha sido armazenada nele.                      para não ficar perguntando se você                de arquivoremoto será feita em modo
   É interessante notar que estes carac-         tem certeza que deseja transmitir cada            binário, isto é o conteúdo do arquivo
teres de redirecionamento são cumula-            arquivo (opção -i de “interactive”) e             não será inteerpretado para saber se
tivos, isto é, se no exemplo anterior            finalmente a opção -n serve para dizer            está em ASCII, EBCDIC, …
fizéssemos o seguinte:                           ao ftp para ele não solicitar o usuário e       • O comando get arquivoremoto diz ao
                                                 sua senha, pois estes serão informados            cliente ftp para pegar este arquivo no
 $ ls naoexiste 2>> U                            pela instrução específica (user);                 servidor hostremoto e trazê-lo para a
 arquivodeerros                                • Quando eu usei o << fimftp, estava                nossa máquina local. Se quiséssemos
                                                 dizendo o seguinte para o interpreta-             enviar um arquivo, bastaria usar, por
a mensagem de erro oriunda do ls seria           dor: “Olha aqui Shell, não se meta em             exemplo, o comando put arquivolocal.
anexada ao final de arquivodeerros.
                                                       Direito de Posse                          Redirecionamento de
Redirecionamento da                             O $$ contém o PID,isto é,o número do seu         comandos
Entrada Padrão                                  processo. Como o Linux é multiusuário,é          Os redirecionamentos de que falamos até
Para fazermos o redirecionamento da En-         bom anexar sempre o $$ ao nome dos seus          agora sempre se referiam a arquivos, isto
trada Padrão usamos o < (menor que).            arquivos para não haver problema de propri-      é, mandavam para arquivo, recebiam de
“E pra que serve isso?”, você vai me per-       edade,isto é,caso você batizasse o seu ar-       arquivo, simulavam arquivo local, … O
guntar. Deixa eu dar um exemplo, que            quivo simplesmente como seraqueexiste,a          que veremos a partir de agora, redirecio-
você vai entender rapidinho.                    primeira pessoa que o usasse (criando-o          na a saída de um comando para a entra-
                                                então) seria o seu dono e a segunda ganharia
   Suponha que você queira mandar um                                                             da de outro. É utilíssimo e, apesar de não
                                                um erro quando tentasse gravar algo nele.
mail para o seu chefe. Para o chefe nós                                                          ser macaco gordo, sempre quebra os




                                                                                       www.linuxmagazine.com.br       Agosto 2004            85
LINUX USER             Papo de Botequim




maiores galhos. Seu nome é “pipe” (que           $ echo "Existem who | wc -l U              $ (pwd ; cd /etc ; pwd)
em inglês significa tubo, já que ele cana-       usuarios conectados"                       /home/meudir
liza a saída de um comando para a                Existem who | wc -l usuarios U             /etc
entrada de outro) e sua representação é a        conectados                                 $ pwd
| (barra vertical).                                                                         /home/meudir
                                               Hi! Olha só, não funcionou! É mesmo,
 $ ls | wc -l                                  não funcionou e não foi por causa das       “Quequeiiisso” minha gente? Eu estava
 21                                            aspas que eu coloquei, mas sim por que      no /home/meudir, mudei para o /etc,
                                               eu teria que ter executado o who | wc -l    constatei que estava neste diretório com
O comando ls passou a lista de arquivos        antes do echo. Para resolver este proble-   o pwd seguinte e quando o agrupamento
para o comando wc, que quando está             ma, tenho que priorizar a segunda parte     de comandos terminou, eu vi que conti-
com a opção -l conta a quantidade de li-       do comando com o uso de crases:             nuava no /etc/meudir!
nhas que recebeu. Desta forma, pode-                                                         Hi! Será que tem coisa do mágico
mos afirmar categoricamente que no               $ echo "Existem `who | wc -l` U           Mandrake por aí? Nada disso. O interes-
meu diretório existiam 21 arquivos.              usuarios conectados"                      sante do uso de parênteses é que eles
                                                 Existem     8 usuarios U                  invocam um novo Shell para executar os
 $ cat /etc/passwd | sort | lp                   conectados                                comandos que estão em seu interior.
                                                                                           Desta forma, fomos realmente para o
A linha de comandos acima manda a              Para eliminar esse monte de brancos         diretório /etc, porém após a execução de
listagem do arquivo /etc/passwd para a         antes do 8 que o wc -l produziu, basta      todos os comandos, o novo Shell que
entrada do comando sort. Este a classi-        retirar as aspas. Assim:                    estava no diretório /etc morreu e retor-
fica e envia para o lp que é o gerenciador                                                 namos ao Shell anterior que estava em
da fila de impressão.                            $ echo Existem `who | wc -l` U            /home/meudir.
                                                 usuarios conectados                         Que tal usar nossos novos conceitos?
Caracteres de ambiente                           Existem 8 usuarios conectados
Quando queremos priorizar uma expres-                                                       $ mail suporte@linux.br << FIM
são, nós a colocamos entre parênteses,         As aspas protegem da interpretação do        Ola suporte, hoje as `date U
não é? Pois é, por causa da aritmética é       Shell tudo que está dentro dos seus lim-     “+%hh:mm”` ocorreu novamente U
normal pensarmos deste jeito. Mas em           ites. Como para o Shell basta um espaço      aquele problema que eu havia U
Shell o que prioriza mesmo são as crases       em branco como separador, o monte de         reportado por telefone. De U
(`) e não os parênteses. Vou dar exemp-        espaços será trocado por um único após       acordo com seu pedido segue a U
los para você entender melhor.                 a retirada das aspas.                        listagem do diretorio:
  Eu quero saber quantos usuários estão           Outra coisa interessante é o uso do       `ls -l`
“logados” no computador que eu admi-           ponto-e-vírgula. Quando estiver no Shell,    Abracos a todos.
nistro. Eu posso fazer:                        você deve sempre dar um comando em           FIM
                                               cada linha. Para agrupar comandos em
 $ who | wc -l                                 uma mesma linha, temos que separá-los       Finalmente agora podemos demonstrar o
 8                                             por ponto-e-vírgula. Então:                 que conversamos anteriormente sobre
                                                                                           “here document”. Os comandos entre
O comando who passa a lista de usuários          $ pwd ; cd /etc; pwd ;cd -;pwd            crases tem prioridade, portanto o Shell
conectados ao sistema para o comando             /home/meudir                              os executará antes do redirecionamento
wc -l, que conta quantas linhas recebeu e        /etc                                      do “here document”. Quando o suporte
mostra a resposta na tela. Muito bem,            /home/meudir                              receber a mensagem, verá que os
mas ao invés de ter um número oito                                                         comandos date e ls foram executados
solto na tela, o que eu quero mesmo é          Neste exemplo, listei o nome do diretório   antes do comando mail, recebendo então
que ele esteja no meio de uma frase. Ora,      corrente com o comando pwd, mudei           um instantâneo do ambiente no
para mandar frases para a tela eu só pre-      para o diretório /etc, novamente listei o   momento de envio do email.
ciso usar o comando echo; então vamos          nome do diretório e finalmente voltei pa-   - Garçom, passa a régua!             s
ver como é que fica:                           ra o diretório onde estava anteriormente
                                               (cd -), listando seu nome. Repare que                        Julio Cezar Neves é Analista de Su-
                                                                                            SOBRE O AUTOR




          Buraco Negro                         coloquei o ponto-e-vírgula de todas as                       porte de Sistemas desde 1969 e tra-
 Em Unix existe um arquivo fantasma.           formas possíveis, para mostrar que não                       balha com Unix desde 1980, quando
 Chama-se /dev/null.Tudo que é enviado         importa se existem espaços em branco                         fez parte da equipe que desenvolveu
 para este arquivo some. Assemelha-se a um     antes ou após este caracter.                                 o SOX, sistema operacional, similar
 Buraco Negro. No caso do exemplo, como                                                                     ao Unix, da Cobra Computadores. É
                                                 Finalmente, vamos ver o caso dos
 não me interessava guardar a possível men-                                                                 professor do curso de Mestrado em
                                               parênteses. No exemplo a seguir, colo-
 sagem de erro oriunda do comando rm, redi-                                                                 Software Livre das Faculdades Estácio
                                               camos diversos comandos separados por
 recionei-a para este arquivo.                                                                              de Sá, no Rio de Janeiro.
                                               ponto-e-vírgula entre parênteses:




86        Agosto 2004         www.linuxmagazine.com.br
Papo de Botequim              LINUX USER




Curso de Shell Script


Papo de Botequim - Parte II
Nossos personagens voltam à mesa do bar para discutir expressões regulares e             linhas que usavam a palavra grep, em
                                                                                         todos os arquivos terminados em .sh.
colocar a “mão na massa” pela primeira vez, construindo um aplicativo simples            Como uso essa extensão para definir
                                                                                         meus arquivos com programas em Shell,
para catalogar uma coleção de CDs. POR JÚLIO CÉSAR NEVES                                 malandramente, o que fiz foi listar as lin-
                                                                                         has dos programas que poderia usar
                                                                                         como exemplo do comando grep.



G
        arçom! Traz um “chops” e dois                                                       Olha que legal! O grep aceita como
        “pastel”. O meu amigo hoje não                                                   entrada a saída de outro comando, redi-
        vai beber porque está finalmente                                                  recionado por um pipe (isso é muito
sendo apresentado a um verdadeiro sis-                                                       comum em Shell e é um tremendo
tema operacional, e ainda tem muita                                                           acelerador da execução de coman-
coisa a aprender!                                                                              dos). Dessa forma, no 3° exemplo,
– E então, amigo, tá entendendo                                                                 o comando who listou as pessoas
  tudo que te expliquei até agora?                                                               “logadas” na mesma máquina que
– Entendendo eu tô, mas não vi                                                                   você (não se esqueça jamais: o
  nada prático nisso…                                                                            Linux é multiusuário) e o grep foi
– Calma rapaz, o que te falei até                                                                usado para verificar se o Carvalho
  agora serve como base ao que há                                                               estava trabalhando ou “coçando”.
  de vir daqui pra frente. Vamos usar                                                          O grep é um comando muito con-
  essas ferramentas que vimos para                                                            hecido, pois é usado com muita fre-
  montar programas estruturados. Você                                                      qüência. O que muitas pessoas não
  verá porque até na TV já teve pro-                                                     sabem é que existem três comandos na
  grama chamado “O Shell é o Limite”.                                                    família grep: grep, egrep e fgrep. A princi-
  Para começar vamos falar dos coman-                                                    pais diferenças entre os 3 são:
  dos da família grep                                                                    • grep - Pode ou não usar expressões
– Grep? Não conheço nenhum termo em          $ grep franklin /etc/passwd                    regulares simples, porém no caso de
  inglês com este nome…                                                                     não usá-las, o fgrep é melhor, por ser
– É claro, grep é um acrônimo (sigla)       Pesquisando em vários arquivos:                 mais rápido.
  para Global Regular Expression Print,                                                  • egrep (“e” de extended, estendido) - É
  que usa expressões regulares para          $ grep grep *.sh                               muito poderoso no uso de expressões
  pesquisar a ocorrência de cadeias de                                                      regulares. Por ser o mais poderoso dos
  caracteres na entrada definida.           Pesquisando na saída de um comando:             três, só deve ser usado quando for
  Por falar em expressões regulares (ou                                                     necessária a elaboração de uma
regexp), o Aurélio Marinho Jargas es-        $ who | grep carvalho                          expressão regular não aceita pelo grep.
creveu dois artigos [1 e 2] imperdíveis                                                  • fgrep (“f” de fast, rápido) - Como o
para a Revista do Linux sobre esse          No 1º exemplo, procurei a palavra               nome diz, é o ligeirinho da família,
assunto e também publicou um livro [3]      franklin em qualquer lugar do arquivo           executando o serviço de forma muito
pela Editora Novatec. Acho bom você ler     /etc/passwd. Se quisesse procurar um            veloz (por vezes é cerca de 30% mais
esses artigos, eles vão te ajudar no que    nome de usuário, isto é, somente no iní-        rápido que o grep e 50% mais que o
está para vir.                              cio dos registros desse arquivo, poderia        egrep), porém não permite o uso de
                                            digitar $ grep ‘^franklin’ /etc/passwd.         expressões regulares na pesquisa.
Eu fico com grep,você com gripe                “E para que servem o circunflexo e os     –Agora que você já conhece as difer-
Esse negócio de gripe é brincadeira, só     apóstrofos?”, você vai me perguntar. Se      enças entre os membros da família, me
um pretexto para pedir umas caipirinhas.    tivesse lido os artigos que mencionei,       diga: o que você acha dos três exemplos
Eu te falei que o grep procura cadeias de   saberia que o circunflexo serve para limi-   que eu dei antes das explicações?
caracteres dentro de uma entrada defi-      tar a pesquisa ao início de cada linha e     – Achei que o fgrep resolveria o teu prob-
nida, mas o que vem a ser uma “entrada      os apóstrofos servem para o Shell não           lema mais rapidamente que o grep.
definida”? Bem, existem várias formas       interpretar esse circunflexo, deixando-o     – Perfeito! Tô vendo que você está
de definir a entrada do comando grep.       passar incólume para o comando grep.            atento, entendendo tudo que estou te
Veja só. Para pesquisar em um arquivo:         No 2º exemplo mandei listar todas as         explicando! Vamos ver mais exemplos




                                                                                www.linuxmagazine.com.br   Setembro 2004         87
LINUX USER                  Papo de Botequim




                   Quadro 1 - Listando subdiretórios                                              ser explorado).
                                                                                                  – Péra aí! De onde eu vou receber os
 $ ls -l | grep    ‘^d’                                                                             dados dos CDs?
 drwxr-xr-x        3                root     root      4096    Dec   18 2000 doc                  – Vou mostrar como o programa pode
 drwxr-xr-x        11               root     root      4096    Jul   13 18:58 freeciv               receber parâmetros de quem o estiver
 drwxr-xr-x        3                root     root      4096    Oct   17 2000 gimp                   executando e, em breve, ensinarei a ler
 drwxr-xr-x        3                root     root      4096    Aug    8 2000 gnome                  os dados da tela ou de um arquivo.
 drwxr-xr-x        2                root     root      4096    Aug    8 2000 idl
 drwxrwxr-x        14               root     root      4096    Jul   13 18:58 locale              Passando parâmetros
 drwxrwxr-x        12               root     root      4096    Jan   14 2000 lyx                  Veja abaixo a estrutura do arquivo con-
 drwxrwxr-x        3                root     root      4096    Jan   17 2000 pixmaps              tendo a lista das músicas:
 drwxr-xr-x        3                root     root      4096    Jul    2 20:30 scribus
 drwxrwxr-x        3                root     root      4096    Jan   17 2000 sounds                nomedoálbum^intérprete1~nomeU
 drwxr-xr-x        3                root     root      4096    Dec   18 2000 xine                  damúsica1:...:intérpreten~nomeU
 drwxr-xr-x        3                root     root      4096    Jun   19 2000 xplns                 damúsican

  para clarear de vez as diferenças de               -l). Os apóstrofos foram usados para o       Isto é, o nome do álbum será separado
  uso entre os membros da família.                   Shell não “ver” o circunflexo. Vamos ver     por um circunflexo do resto do registro,
  Eu sei que em um arquivo qualquer                  mais um. Veja na Tabela 1 as quatro          formado por diversos grupos compostos
existe um texto falando sobre Linux, só              primeiras posições possíveis da saída de     pelo intérprete de cada música do CD e a
não tenho certeza se está escrito com L              um ls -l em um arquivo comum (não é          música interpretada. Estes grupos são
maiúsculo ou minúsculo. Posso fazer                  diretório, nem link, nem …).                 separados entre si por dois pontos (:) e,
uma busca de duas formas:                               Para descobrir todos os arquivos exe-     internamente, o intérprete será separado
                                                     cutáveis em um determinado diretório         por um til (~) do nome da música.
 egrep (Linux | linux) arquivo.txt                   eu poderia fazer:                               Quero escrever um programa chamado
                                                                                                  musinc, que incluirá registros no meu
ou então:                                              $ ls -la | egrep ‘^-..(x|s)’               arquivo músicas. Passarei cada álbum
                                                                                                  como parâmetro para o programa:
 grep [Ll]inux arquivo.txt                           novamente usamos o circunflexo para
                                                     limitar a pesquisa ao início de cada          $ musinc “álbum^interprete~U
No primeiro caso, a expressão regular                linha, ou seja, listamos as linhas que        musica:interprete~musica:...”
complexa (Linux | linux) usa os parênte-             começam por um traço (-), seguido de
ses para agrupar as opções e a barra ver-            qualquer coisa (o ponto), novamente          Desta forma, musinc estará recebendo os
tical (|) é usada como um “ou” (or, em               seguido de qualquer coisa, e por fim um      dados de cada álbum como se fosse uma
inglês) lógico, isto é, estou procurando             x ou um s. Obteríamos o mesmo resul-         variável. A única diferença entre um
Linux ou linux.                                      tado se usássemos o comando:                 parâmetro recebido e uma variável é que
   No segundo, a expressão regular                                                                os primeiros recebem nomes numéricos
[Ll]inux significa: começado por L ou l                $ ls -la | grep ‘^-..[xs]’                 (o que quis dizer é que seus nomes são
seguido de inux. Como esta é uma                                                                  formados somente por um algarismo,
expressão simples, o grep consegue                   e além disso, agilizaríamos a pesquisa.      isto é, $1, $2, $3, …, $9). Vamos, fazer
resolvê-la, por isso é melhor usar a                                                              mais alguns testes:
segunda forma, já que o egrep tornaria a             A “CDteca”
pesquisa mais lenta.                                 Vamos começar a desenvolver progra-           $ cat teste
   Outro exemplo. Para listar todos os               mas! Creio que a montagem de um               #!/bin/bash
subdiretórios do diretório corrente, basta           banco de dados de músicas é bacana            #Teste de passagem    de parametros
usar o comando $ ls -l | grep ‘^d’. Veja o           para efeito didático (e útil nestes tempos    echo “1o. parm ->     $1”
resultado no Quadro 1.                               de downloads de arquivos MP3 e                echo “2o. parm ->     $2”
   No exemplo, o circunflexo (^) serviu              queimadores de CDs). Não se esqueça           echo “3o. parm ->     $3”
para limitar a pesquisa à primeira                   que, da mesma forma que vamos desen-
posição da saída do ls longo (parâmetro              volver um monte de programas para            Agora vamos rodar esse programinha:
                                                     organizar os seus CDs de música, com
               Tabela 1                              pequenas adaptações você pode fazer o         $ teste passando parametros para U
                                                     mesmo para organizar os CDs de soft-          testar
 Posição           Valores possíveis
 1ª                -
                                                     ware que vêm com a Linux Magazine e           bash: teste: cannot execute
 2ª                r ou -
                                                     outros que você compra ou queima, e
 3ª                w ou -                            disponibilizar esse banco de software        Ops! Esqueci-me de tornar o script exe-
 4ª                x,s(suid) ou -                    para todos os que trabalham com você         cutável. Vou fazer isso e testar nova-
                                                     (o Linux é multiusuário, e como tal deve     mente o programa:




88          Setembro 2004           www.linuxmagazine.com.br
Papo de Botequim                  LINUX USER




 $ chmod 755 teste                          Execute o programa:                          inclusão de CDs no meu banco chamado
 $ teste passando parametros para U                                                      musicas. O programa é muito simples
 testar                                      $ teste passando parametros para testar     (como tudo em Shell). Veja a Listagem 1.
 1o. parm -> passando                        O programa teste recebeu 4 U                   O script é simples e funcional; limito-
 2o. parm -> parametros                      parametros                                  me a anexar ao fim do arquivo musicas o
 3o. parm -> para                            1o. parm -> passando                        parâmetro recebido. Vamos cadastrar 3
                                             2o. parm -> parametros                      álbuns para ver se funciona (para não
Repare que a palavra testar, que seria o     3o. parm -> para                            ficar “enchendo lingüiça,” suponho que
quarto parâmetro, não foi listada. Isso      Para listar todos de uma U                  em cada CD só existem duas músicas):
ocorreu porque o programa teste só lista     “tacada” eu faco passando U
os três primeiros parâmetros recebidos.      parametros para testar                        $ musinc “album3^Artista5U
Vamos executá-lo de outra forma:                                                           ~Musica5:Artista6~Musica5”
                                            Repare que antes das aspas usei uma            $ musinc “album1^Artista1U
 $ teste “passando parametros” U            barra invertida, para escondê-las da           ~Musica1:Artista2~Musica2”
 para testar                                interpretação do Shell (se não usasse as       $ musinc “album 2^Artista3U
 1o. parm -> passando parametros            contrabarras as aspas não apareceriam).        ~Musica3:Artista4~Musica4”
 2o. parm -> para                             Como disse, os parâmetros recebem
 3o. parm -> testar                         números de 1 a 9, mas isso não significa     Listando o conteúdo do arquivo musicas:
                                            que não posso usar mais de nove
As aspas não deixaram o Shell ver o         parâmetros. Significa que só posso             $ cat musicas
espaço em branco entre as duas              endereçar nove. Vamos testar isso:             album3^Artista5~Musica5:Artista6U
primeiras palavras, e elas foram consid-                                                   ~Musica6
eradas como um único parâmetro. E            $ cat teste                                   album1^Artista1~Musica1:Artista2U
falando em passagem de parâmetros,           #!/bin/bash                                   ~Musica2
uma dica: veja na Tabela 2 algumas var-      # Programa para testar passagem U             album2^Artista3~Musica3:Artista4U
iáveis especiais. Vamos alterar o pro-       de parametros (3a. Versao)                    ~Musica4
grama teste para usar as novas variáveis:    echo O programa $0 recebeu $# U
                                             parametros                                  Podia ter ficado melhor. Os álbuns estão
 $ cat teste                                 echo “11o. parm -> $11”                     fora de ordem, dificultando a pesquisa.
 #!/bin/bash                                 shift                                       Vamos alterar nosso script e depois testá-
 # Programa para testar passagem U           echo “2o. parm -> $1”                       lo novamente. Veja a listagem 2. Sim-
 de parametros (2a. Versao)                  shift 2                                     plesmente inseri uma linha que classifica
 echo O programa $0 recebeu $# U             echo “4o. parm -> $1”                       o arquivo musicas, redirecionando a
 parametros                                                                              saída para ele mesmo (para isso serve a
 echo “1o. parm -> $1”                      Execute o programa:                          opção -o), após cada álbum ser anexado.
 echo “2o. parm -> $2”
 echo “3o. parm -> $3”                       $ teste passando parametros para U            $ cat musicas
 echo Para listar todos de uma U             testar                                        album1^Artista1~Musica1:Artista2U
 ”tacada” eu faco $*                       O programa teste recebeu 4 U                  ~Musica2
                                             parametros que são:                           albu2^Artista3~Musica3:Artista4U
 Listagem 1: Incluindo CDs                   11o. parm -> passando1                        ~Musica4
       na “CDTeca”                           2o. parm -> parametros                        album3^Artista5~Musica5:Artista6U
                                             4o. parm -> testar                            ~Musica6
 $ cat musinc
 #!/bin/bash                                Duas coisas muito interessantes aconte-         Oba! Agora o programa está legal e
 # Cadastra CDs (versao 1)                  ceram neste script. Para mostrar que os      quase funcional. Ficará muito melhor em
 #                                          nomes dos parâmetros variam de $1 a $9       uma nova versão, que desenvolveremos
 echo $1 >> musicas                         digitei echo $11 e o que aconteceu? O        após aprender a adquirir os dados da tela
                                            Shell interpretou como sendo $1 seguido      e formatar a entrada.
                                            do algarismo 1 e listou passando1;
            Listagem 2                        O comando shift, cuja sintaxe é shift n,     Tabela 2: Variáveis especiais
                                            podendo o n assumir qualquer valor
 $ cat musinc                                                                              Variável        Significado
                                            numérico, despreza os n primeiros
 #!/bin/bash                                                                               $0              Contém o nome do programa
                                            parâmetros, tornando o parâmetro de
 # Cadastra CDs (versao 2)                                                                 $#              Contém a quantidade de
                                            ordem n+1.                                                     parâmetros passados
 #
                                              Bem, agora que você já sabe sobre            $*              Contém o conjunto de todos os
 echo $1 >> musicas
                                            passagem de parâmetros, vamos voltar à                         parâmetros (muito parecido com $@)
 sort -o musicas musicas
                                            nossa “cdteca” para fazer o script de




                                                                                www.linuxmagazine.com.br    Setembro 2004                   89
LINUX USER           Papo de Botequim




  Ficar listando arquivos com o                grep <cadeia de caracteres> U                                Listagem 5 - musexc
comando cat não está com nada, vamos           [arq1, arq2, ..., arqn]
fazer um programa chamado muslist                                                             $ cat musexc
para listar um álbum, cujo nome será         O grep entendeu que deveria procurar a           #!/bin/bash
passado como parâmetro. Veja o código        cadeia de caracteres album nos arquivos          # Exclui CDs (versao 1)
na Listagem 3:                               2 e musicas. Como o arquivo 2 não                #
  Vamos executá-lo, procurando pelo          existe, grep gerou o erro e, por encontrar       grep -v “$1” musicas > /tmp/mus$$
album 2. Como já vimos antes, para pas-      a palavra album em todos os registros de         mv -f /tmp/mus$$ musicas
sar a string album 2 é necessário pro-       musicas, listou a todos.
tegê-la da interpretação do Shell, para        É melhor ignorarmos maiúsculas e
que ele não a interprete como dois           minúsculas na pesquisa. Resolveremos          mando. Estamos então prontos para
parâmetros. Exemplo:                         os dois problemas com a Listagem 4.           desenvolver o script para remover CDs
                                               Nesse caso, usamos a opção -i do grep       empenados da sua “CDteca”. Veja o
 $ muslist “album 2”                         que, como já vimos, serve para ignorar        código da Listagem 5.
 grep: can’t open 2                          maiúsculas e minúsculas, e colocamos o           Na primeira linha mandei para
 musicas: album1^Artista1~Musica1U           $1 entre aspas, para que o grep continu-      /tmp/mus$$ o arquivo musicas, sem os
 :Artista2~Musica2                           asse a ver a cadeia de caracteres resul-      registros que atendessem a consulta feita
 musicas: album2^Artista3~Musica3U           tante da expansão da linha pelo Shell         pelo comando grep. Em seguida, movi
 :Artista4~Musica4                           como um único argumento de pesquisa.          /tmp/mus$$ por cima do antigo musicas.
 musicas:album3^Artista5~Musica5U                                                          Usei o arquivo /tmp/mus$$ como arqui-
 :Artista6~Musica6                             $ muslist “album 2”                         vo de trabalho porque, como já havia
                                               album2^Artista3~Musica3:Artista4U           citado no artigo anterior, o $$ contém o
Que lambança! Onde está o erro? Eu tive        ~Musica4                                    PID (identificação do processo) e, dessa
o cuidado de colocar o parâmetro pas-                                                      forma, cada um que editar o arquivo
sado entre aspas para o Shell não o             Agora repare que o grep localiza a         musicas o fará em um arquivo de tra-
dividir em dois! É, mas repare como o        cadeia pesquisada em qualquer lugar do        balho diferente, evitando colisões.
grep está sendo executado:                   registro; então, da forma que estamos            Os programas que fizemos até aqui
                                             fazendo, podemos pesquisar por álbum,         ainda são muito simples, devido à falta
 grep $1 musicas                             por música, por intérprete e mais.            de ferramentas que ainda temos. Mas é
                                             Quando conhecermos os comandos                bom praticar os exemplos dados porque,
Mesmo colocando álbum 2 entre aspas,         condicionais, montaremos uma nova             eu prometo, chegaremos a desenvolver
para que fosse encarado como um único        versão de muslist que permitirá especi-       um sistema bacana para controle dos
parâmetro, quando o $1 foi passado pelo      ficar por qual campo pesquisar.               seus CDs. Na próxima vez que nos
Shell para o comando grep, transformou-         Ah! Em um dia de verão você foi à          encontrarmos, vou te ensinar como fun-
se em dois argumentos. Dessa forma, o        praia, esqueceu os CDs no carro, aquele       cionam os comandos condicionais e
conteúdo da linha que o grep executou        “solzinho” de 40 graus empenou seu            aprimoraremos mais um pouco esses
foi o seguinte:                              disco favorito e agora você precisa de        scripts. Por hoje chega! Já falei demais e
                                             uma ferramenta para removê-lo do              estou de goela seca! Garçom! Mais um
 grep album 2 musicas                        banco de dados? Não tem problema,             sem colarinho!                          s
                                             vamos desenvolver um script chamado
Como a sintaxe do grep é:                    musexc, para excluir estes CDs.                                     INFORMAÇÕES
                                                Antes de desenvolver o “bacalho”,
     Listagem 3 - muslist                    quero te apresentar a uma opção bas-           [1] http://www.revistadolinux.com.br/ed/003/
                                             tante útil da família de comandos grep. É          ferramentas.php3
 $ cat muslist
                                             a opção -v, que quando usada lista todos       [2] http://www.revistadolinux.com.br/ed/007/
 #!/bin/bash
                                             os registros da entrada, exceto o(s) local-        ereg.php3
 # Consulta CDs (versao 1)
                                             izado(s) pelo comando. Exemplos:               [3] http://www.aurelio.net/er/livro/
 #
 grep $1 musicas
                                               $ grep -v “album 2” musicas
                                               album1^Artista1~Musica1:Artista2U                            Julio Cezar Neves é
                                                                                            SOBRE O AUTOR




                                                                                                            Analista de Suporte de
         Listagem 4                            ~Musica2
                                                                                                            Sistemas desde 1969 e
      muslist melhorado                        album3^Artista5~Musica5:Artista6U                            trabalha com Unix
                                               ~Musica6                                                     desde 1980, quando
 $ cat muslist
                                                                                                            fez parte da equipe
 #!/bin/bash
                                             Conforme expliquei antes, o grep do                            que desenvolveu o
 # Consulta CDs (versao 2)                                                                                  SOX, um sistema
                                             exemplo listou todos os registros de
 #                                                                                                          operacional similar ao Unix, produzido
                                             musicas exceto o referente a album 2,                          pela Cobra Computadores.
 grep -i “$1” musicas
                                             porque atendia ao argumento do co-




90       Setembro 2004      www.linuxmagazine.com.br
����������������������������������������������������
�����������������������������������������������������������������������������������������������������������������������������������������������������
                                                                                         Papo de Botequim            LINUX USER




                                                         Curso de Shell Script


                                                         Papo de
                                                         botequim III
                                                         Um chopinho, um aperitivo e o papo continua. Desta vez vamos aprender
                                                         alguns comandos de manipulação de cadeias de caracteres, que serão muito

                                                         úteis na hora de incrementar nossa “CDteca”. POR JULIO CEZAR NEVES




            G         arçon! traga dois chopes por
                      favor que hoje eu vou ter que
                      falar muito. Primeiro quero
            mostrar uns programinhas simples
            de usar e muito úteis, como o cut, que
                                                            Então, recapitulando, o layout
                                                         do arquivo é o seguinte: nome do
                                                         álbum^intérprete1~nome da música1:...:
                                                         intérpreten~nome da músican, isto é, o
                                                         nome do álbum será separado por um
                                                                                                          Artista2
                                                                                                          Artista4
                                                                                                          Artista6
                                                                                                          Artista8

            é usado para cortar um determinado           circunflexo (^) do resto do registro, que     Para entender melhor isso, vamos anali-
            pedaço de um arquivo. A sintaxe e            é formado por diversos grupos compos-        sar a primeira linha de musicas:
            alguns exemplos de uso podem ser vis-        tos pelo intérprete de cada música do
            tos no Quadro 1:                             CD e a respectiva música interpretada.           $ head -1 musicas
               Como dá para ver, existem quatro          Estes grupos são separados entre si por          album 1^Artista1~Musica1: U
            sintaxes distintas: na primeira (-c 1-5)     dois-pontos (:) e o intérprete será sepa-        Artista2~Musica2
            especifiquei uma faixa, na segunda           rado do nome da música por um til (~).
            (-c -6) especifiquei todo o texto até           Então, para pegar os dados referentes     Então observe o que foi feito:
            uma posição, na terceira (-c 4-) tudo de     a todas as segundas músicas do arquivo
            uma determinada posição em diante e          musicas, devemos digitar:                        album 1^Artista1~Musica1: U
            na quarta (-c 1,3,5,7,9), só as posições                                                      Artista2~Musica2
            determinadas. A última possibilidade          $ cut -f2 -d: musicas
            (-c -3,5,8-) foi só para mostrar que pode-    Artista2~Musica2                            Desta forma, no primeiro cut o primeiro
            mos misturar tudo.                            Artista4~Musica4                            campo do delimitador (-d) dois-pon-
               Mas não pense que acabou por aí!           Artista6~Musica5                            tos (:) é album 1^Artista1~Musica1 e o
            Como você deve ter percebido, esta            Artista8~Musica8@10_L:                      segundo, que é o que nos interessa, é
            forma de cut é muito útil para lidar com                                                  Artista2~Musica2. Vamos então ver o
            arquivos com campos de tamanho fi xo,         Ou seja, cortamos o segundo campo            que aconteceu no segundo cut:
            mas atualmente o que mais existe são         z(-f de field, campo em inglês) delimi-
            arquivos com campos de tamanho vari-         tado (-d) por dois-pontos (:). Mas, se           Artista2~Musica2
            ável, onde cada campo termina com um         quisermos somente os intérpretes, deve-
            delimitador. Vamos dar uma olhada no         mos digitar:                                 Agora, primeiro campo do delimitador
            arquivo musicas que começamos a pre-                                                      (-d) til (~), que é o que nos interessa,
            parar na última vez que viemos aqui no        $ cut -f2 -d: musicas | cut U               é Artista2 e o segundo é Musica2. Se
            botequim. Veja o Quadro 2.                   -f1 -d~                                      o raciocínio que fizemos para a pri-




                                                                 �����������������������������
                                                                               www.linuxmagazine.com.br              Outubro 2004      85
                                                                      ��������������������������������������������������������������������������������
���������������������������������������������������
����������������������������������������������������������������������������������������������������������������������������������������������������
                     LINUX USER                Papo de Botequim




           Quadro 1 – O comando cut                            meira linha for aplicado ao restante do
                                                               arquivo, chegaremos à resposta ante-
                                                                                                           posta a um exercício prático, valendo
                                                                                                           nota, que passei ele me entregou um
                                                               riormente dada. Outro comando muito         script com todos os comandos sepa-
           A sintaxe do cut é: cut -c PosIni-PosFim
                                                               interessante é o tr que serve para subs-    rados por ponto-e-vírgula (lembre-se
           [arquivo], onde PosIni é a posição inicial, e
                                                               tituir, comprimir ou remover caracteres.    que o ponto-e-vírgula serve para sepa-
           PosFim a posição final. Veja os exemplos:
                                                               Sua sintaxe segue o seguinte padrão:        rar diversos comandos em uma mesma
                                                                                                           linha). Vou dar um exemplo simplifi-
           $ cat numeros
                                                                tr [opções] cadeia1 [cadeia2]              cado, e idiota, de um script assim:
           1234567890
           0987654321
                                                               O comando copia o texto da entrada           $ cat confuso
           1234554321
                                                               padrão (stdin), troca as ocorrência dos      echo leia Programação Shell U
           9876556789
                                                               caracteres de cadeia1 pelo seu corres-       Linux do Julio Cezar Neves U
                                                               pondente na cadeia2 ou troca múltiplas       > livro;cat livro;pwd;ls;rm U
           $ cut -c1-5 numeros
                                                               ocorrências dos caracteres de cadeia1       -f livro2>/dev/null;cd ~
           12345
                                                               por somente um caracter, ou ainda
           09876
                                                               caracteres da cadeia1. As principais        Eu executei o programa e ele funcionou:
           12345
                                                               opções do comando são mostradas na
           98765
                                                               Tabela 1.                                    $ confuso
                                                                 Primeiro veja um exemplo bem bobo:         leia Programação Shell Linux U
           $ cut -c-6 numeros
                                                                                                            do Julio Cezar Neves
           123456
                                                                $ echo bobo | tr o a                        /home/jneves/LM
           098765
                                                                baba                                        confuso livro musexc musicas
           123455
                                                                                                            musinc muslist numeros
           987655
                                                               Isto é, troquei todas as ocorrências da
                                                               letra o pela letra a. Suponha que em        Mas nota de prova é coisa séria (e nota
           $ cut -c4- numeros
                                                               determinado ponto do meu script eu          de dólar é mais ainda) então, para
           4567890
                                                               peça ao operador para digitar s ou n        entender o que o aluno havia feito, o
           7654321
                                                               (sim ou não), e guardo sua resposta         chamei e em sua frente digitei:
           4554321
                                                               na variável $Resp. Ora, o conteúdo de
           6556789
                                                               $Resp pode conter letras maiúsculas          $ tr ”;” ”n” < confuso
                                                               ou minúsculas, e desta forma eu teria        echo leia Programação Shell U
           $ cut -c1,3,5,7,9 numeros
                                                               que fazer diversos testes para saber se      Linux do Julio Cezar Neves
           13579
                                                               a resposta dada foi S, s, N ou n. Então o    pwd
           08642
                                                               melhor é fazer:                              cd ~
           13542
                                                                                                            ls -l
           97568
                                                                $ Resp=$(echo $Resp | tr SN sn)             rm -f lixo 2>/dev/null

           $ cut -c -3,5,8- numeros
                                                               e após este comando eu teria certeza        O cara ficou muito desapontado, porque
           1235890
                                                               de que o conteúdo de $Resp seria um         em dois ou três segundos eu desfi z a
           0986321
                                                               s ou um n. Se o meu arquivo ArqEnt          gozação que ele perdeu horas para fazer.
           1235321
                                                               está todo em letras maiúsculas e desejo     Mas preste atenção! Se eu estivesse em
           9875789
                                                               passá-las para minúsculas eu faço:          uma máquina Unix, eu teria digitado:

                                                                $ tr A-Z a-z < ArqEnt > / tmp/$$            $ tr ”;” ”012” < confuso
               Quadro 2 – O arquivo                             $ mv -f /tmp/$$ ArqEnt
                    musicas                                                                                Agora veja a diferença entre o resultado
                                                               Note que neste caso usei a notação A-       de um comando date executado hoje e
                                                               Z para não escrever ABCD…YZ. Outro          outro executado há duas semanas:
           $ cat musicas
                                                               tipo de notação que pode ser usada são
           album 1^Artista1~Musica1:U
                                                               as escape sequences (como eu traduzi-        Sun Sep 19 14:59:54       2004
           Artista2~Musica2
                                                               ria? Seqüências de escape? Meio sem          Sun Sep 5 10:12:33        2004
           album 2^Artista3~Musica3:U
                                                               sentido, né? Mas vá lá…) que também
           Artista4~Musica4
                                                               são reconhecidas por outros comandos        Notou o espaço extra após o “Sep” na
           album 3^Artista5~Musica5:U
                                                               e também na linguagem C, e cujo signi-      segunda linha? Para pegar a hora eu
           Artista6~Musica5
                                                               ficado você verá na Tabela 2:                deveria digitar:
           album 4^Artista7~Musica7:U
                                                                  Deixa eu te contar um “causo”: um
           Artista8~Musica8
                                                               aluno que estava danado comigo resol-        $ date | cut -f 4 -d ’ ’
                                                               veu complicar minha vida e como res-         14:59:54




�����������������������������
              86        Outubro 2004                       www.linuxmagazine.com.br
��������������������������������������������������������������������������������
����������������������������������������������������
�����������������������������������������������������������������������������������������������������������������������������������������������������
                                                                                          Papo de Botequim           LINUX USER




            Mas há duas semanas ocorreria o             Bem a opção -d do tr remove do arquivo         E veja também o date:
            seguinte:                                   todas as ocorrências do caractere espe-
                                                        cificado. Desta forma eu removi os                 $ date
              $ date | cut -f 4 -d ’ ’                  caracteres indesejados, salvei o texto             Mon Sep 20 10:47:19 BRT 2004
              5                                         em um arquivo temporário e posterior-
                                                        mente renomeei-o para o nome original.       Repare que o mês e o dia estão no
            Isto porque existem 2 caracteres em         Uma observação: em um sistema Unix           mesmo formato em ambos os coman-
            branco antes do 5 (dia). Então o ideal      eu deveria digitar:                          dos. Ora, se em algum registro do who
            seria transformar os espaços em branco                                                   eu não encontrar a data de hoje, é sinal
            consecutivos em somente um espaço             $ tr -d ’015’ < ArqDoDOS.U                que o usuário está “logado” há mais
            para poder tratar os dois resultados do       txt > /tmp/$$                              de um dia, já que ele não pode ter se
            comando date da mesma forma, e isso                                                     “logado” amanhã… Então vamos guar-
            se faz assim:                                Uma dica: o problema com os termina- dar o pedaço que importa da data de
                                                         dores de linha (CR/LF) só aconteceu         hoje para depois procurá-la na saída do
              $ date | tr -s ” ”                         porque a transferência do arquivo foi       comando who:
              Sun Sep 5 10:12:33 2004                    feita no modo binário (ou image), Se
                                                         antes da transmissão do arquivo tivesse      $ Data=$(date | cut -f 2-3 U
            E agora eu posso cortar:                     sido estipulada a opção ascii do ftp, isto  -d’ ’)
                                                         não teria ocorrido.
              $ date | tr -s ” ” | cut -f 4 U           – Olha, depois desta dica tô começando a     Eu usei a construção $(...), para prio-
             -d ” ”                                      gostar deste tal de shell, mas ainda tem    rizar a execução dos comandos antes
              10:12:33                                   muita coisa que não consigo fazer.          de atribuir a sua saída à variável Data.
                                                        – Pois é, ainda não te falei quase nada      Vamos ver se funcionou:
            Olha só como o Shell está quebrando o         sobre programação em shell, ainda
            galho. Veja o conteúdo de um arquivo          tem muita coisa para aprender, mas          $ echo $Data
            baixado de uma máquina Windows:               com o que aprendeu, já dá para resol-       Sep 20
                                                          ver muitos problemas, desde que você
             $ cat -ve ArqDoDOS.txt                       adquira o “modo shell de pensar”. Você     Beleza! Agora, o que temos que fazer é
             Este arquivo^M$                              seria capaz de fazer um script que diga    procurar no comando who os registros
             foi gerado pelo^M$                           quais pessoas estão “logadas” há mais      que não possuem esta data.
             DOS/Win e foi^M$                             de um dia no seu servidor?
             baixado por um^M$                          – Claro que não! Para isso seria necessá- – Ah! Eu acho que estou entendendo!
             ftp mal feito.^M$                            rio eu conhecer os comandos condicio-       Você falou em procurar e me ocorreu o
                                                          nais que você ainda não me explicou         comando grep, estou certo?
            Dica: a opção -v do cat mostra os carac-      como funcionam. - Deixa eu tentar – Certíssimo! Só que eu tenho que usar o
            teres de controle invisíveis, com a nota-     mudar um pouco a sua lógica e trazê-        grep com aquela opção que ele só lista
            ção ^L, onde ^ é a tecla Control e L é        la para o “modo shell de pensar”, mas       os registros nos quais ele não encon-
            a respectiva letra. A opção -e mostra o       antes é melhor tomarmos um chope.           trou a cadeia. Você se lembra que
            fi nal da linha como um cifrão ($).             Agora que já molhei a palavra, vamos       opção é essa?
               Isto ocorre porque no DOS o fi m dos       resolver o problema que te propus. Veja – Claro, a -v…
            registros é indicado por um Carriage         como funciona o comando who:               – Isso! Tá ficando bom! Vamos ver:
            Return (r – Retorno de Carro, CR) e
            um Line Feed (f – Avanço de Linha, ou       $ who                                             $ who | grep -v ”$Data”
            LF). No Linux porém o fi nal do regis-        jneves     pts/ U                                 jneves  pts/ U
            tro é indicado somente pelo Line Feed.       1          Sep 18      13:40                      1       Sep 18 13:40
            Vamos limpar este arquivo:                   rtorres    pts/ U
                                                         0          Sep 20      07:01                  Se eu quisesse um pouco mais de perfu-
              $ tr -d ’r’ < ArqDoDOS.txt > /tmp/$$      rlegaria   pts/ U                             maria eu faria assim:
              $ mv -f /tmp/$$ ArqDoDOS.txt               1          Sep 20      08:19
                                                         lcarlos    pts/ U                                 $  who | grep -v ”$Data” |U
            Agora vamos ver o que aconteceu:             3          Sep 20      10:01                       cut -f1 -d ’ ’
                                                                                                           jneves
             $ cat -ve ArqDoDOS.txt                        Tabela 1 – O comando tr
             Este arquivo$                                Opção    Significado                          Viu? Não foi necessário usar comando
             foi gerado pelo$                                                                          condicional, até porque o nosso
                                                          -s       Comprime n ocorrências de
             DOS/Rwin e foi$                                       cadeia1 em apenas uma
                                                                                                       comando condicional, o famoso if, não
             baixado por um$                                                                           testa condição, mas sim instruções.
                                                          -d       Remove os caracteres de cadeia1
             ftp mal feito.$                                                                           Mas antes veja isso:




                                                                  �����������������������������
                                                                                www.linuxmagazine.com.br             Outubro 2004    87
                                                                     ��������������������������������������������������������������������������������
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script
Curso de Shell Script

Mais conteúdo relacionado

Mais procurados

Comandos Linux
Comandos LinuxComandos Linux
Comandos Linuxlol
 
Fundamentos de linux
Fundamentos de linuxFundamentos de linux
Fundamentos de linuxPedro Neto
 
Dicas e Princípios Básicos do Linux
Dicas e Princípios Básicos do LinuxDicas e Princípios Básicos do Linux
Dicas e Princípios Básicos do LinuxWellington Oliveira
 
Guia com mais de 500 comandos do linux
Guia com mais de 500 comandos do linuxGuia com mais de 500 comandos do linux
Guia com mais de 500 comandos do linuxKalanzans
 
Linux - Shell e Comandos Básicos
Linux - Shell e Comandos BásicosLinux - Shell e Comandos Básicos
Linux - Shell e Comandos BásicosFrederico Madeira
 
Comandos do linux
Comandos do linuxComandos do linux
Comandos do linuxPeslPinguim
 
Treinamento de comandos Unix e Linux
Treinamento de comandos Unix e LinuxTreinamento de comandos Unix e Linux
Treinamento de comandos Unix e LinuxCid de Andrade
 
Guia 500 comandos_linux
Guia 500 comandos_linuxGuia 500 comandos_linux
Guia 500 comandos_linuxDario Nakazima
 
Sistema Operacional GNU/Linux
Sistema Operacional GNU/LinuxSistema Operacional GNU/Linux
Sistema Operacional GNU/LinuxPedro Neto
 
Linux - Bruno Oliveira 12ºL
Linux - Bruno Oliveira 12ºLLinux - Bruno Oliveira 12ºL
Linux - Bruno Oliveira 12ºLBrunoOliveira1070
 

Mais procurados (18)

Comandos Linux
Comandos LinuxComandos Linux
Comandos Linux
 
Introdução ao Ssh
Introdução ao SshIntrodução ao Ssh
Introdução ao Ssh
 
Comandos Linux Parte 1
Comandos Linux Parte 1Comandos Linux Parte 1
Comandos Linux Parte 1
 
Fundamentos de linux
Fundamentos de linuxFundamentos de linux
Fundamentos de linux
 
Dicas e Princípios Básicos do Linux
Dicas e Princípios Básicos do LinuxDicas e Princípios Básicos do Linux
Dicas e Princípios Básicos do Linux
 
Aprendendo linux
Aprendendo linuxAprendendo linux
Aprendendo linux
 
Guia com mais de 500 comandos do linux
Guia com mais de 500 comandos do linuxGuia com mais de 500 comandos do linux
Guia com mais de 500 comandos do linux
 
Aula 06 comandos linux
Aula 06   comandos linuxAula 06   comandos linux
Aula 06 comandos linux
 
Linux - Shell e Comandos Básicos
Linux - Shell e Comandos BásicosLinux - Shell e Comandos Básicos
Linux - Shell e Comandos Básicos
 
Comandos do linux
Comandos do linuxComandos do linux
Comandos do linux
 
Treinamento de comandos Unix e Linux
Treinamento de comandos Unix e LinuxTreinamento de comandos Unix e Linux
Treinamento de comandos Unix e Linux
 
Guia 500 comandos_linux
Guia 500 comandos_linuxGuia 500 comandos_linux
Guia 500 comandos_linux
 
Apostila(1)
Apostila(1)Apostila(1)
Apostila(1)
 
Comandos Linux Parte 2
Comandos Linux Parte 2Comandos Linux Parte 2
Comandos Linux Parte 2
 
Sistema Operacional GNU/Linux
Sistema Operacional GNU/LinuxSistema Operacional GNU/Linux
Sistema Operacional GNU/Linux
 
Sistema operacional-1-ano-de-informatica-completa
Sistema operacional-1-ano-de-informatica-completaSistema operacional-1-ano-de-informatica-completa
Sistema operacional-1-ano-de-informatica-completa
 
Linux - Bruno Oliveira 12ºL
Linux - Bruno Oliveira 12ºLLinux - Bruno Oliveira 12ºL
Linux - Bruno Oliveira 12ºL
 
Comandos basicos linux
Comandos basicos linuxComandos basicos linux
Comandos basicos linux
 

Destaque

Curso de Shell Script 06/11
Curso de Shell Script 06/11Curso de Shell Script 06/11
Curso de Shell Script 06/11Rodrigo Silva
 
Shell Scripting
Shell ScriptingShell Scripting
Shell Scriptingdcarneir
 
12 aula - shell script-2015
12   aula - shell script-201512   aula - shell script-2015
12 aula - shell script-2015Flávia Santos
 
Programação em Shell Script
Programação em Shell ScriptProgramação em Shell Script
Programação em Shell ScriptReinaldo Lima
 
Huumeet ja ensiapu
Huumeet ja ensiapuHuumeet ja ensiapu
Huumeet ja ensiapuTaneli Yad
 
Shell Script - Luz e trevas
Shell Script - Luz e trevasShell Script - Luz e trevas
Shell Script - Luz e trevasOsvaldo Filho
 
Oficina de shell script
Oficina de shell scriptOficina de shell script
Oficina de shell scriptbrunobione
 
Introdução à Shellscript
Introdução à ShellscriptIntrodução à Shellscript
Introdução à ShellscriptVinícius Hax
 
Informática do básico ao essencial autor maurício v pires -amostra
Informática do básico ao essencial   autor maurício v pires -amostraInformática do básico ao essencial   autor maurício v pires -amostra
Informática do básico ao essencial autor maurício v pires -amostraMaurício V.Pires
 
Shell script
Shell scriptShell script
Shell scriptTiago
 
Minicurso Shell Script
Minicurso Shell ScriptMinicurso Shell Script
Minicurso Shell ScriptLuís Eduardo
 
Shell Script - Controle de fluxo
Shell Script - Controle de fluxoShell Script - Controle de fluxo
Shell Script - Controle de fluxoFrederico Madeira
 
Introducao ao Shell Script
Introducao ao Shell ScriptIntroducao ao Shell Script
Introducao ao Shell ScriptHugo Maia Vieira
 
Introdução ao Shell Script (versão estendida)
Introdução ao Shell Script (versão estendida)Introdução ao Shell Script (versão estendida)
Introdução ao Shell Script (versão estendida)Hugo Maia Vieira
 

Destaque (20)

Curso de Shell Script 06/11
Curso de Shell Script 06/11Curso de Shell Script 06/11
Curso de Shell Script 06/11
 
Shell Script v0
Shell Script v0Shell Script v0
Shell Script v0
 
Shell Scripting
Shell ScriptingShell Scripting
Shell Scripting
 
12 aula - shell script-2015
12   aula - shell script-201512   aula - shell script-2015
12 aula - shell script-2015
 
Shell script
Shell scriptShell script
Shell script
 
Programação em Shell Script
Programação em Shell ScriptProgramação em Shell Script
Programação em Shell Script
 
Huumeet ja ensiapu
Huumeet ja ensiapuHuumeet ja ensiapu
Huumeet ja ensiapu
 
Shell Script - Luz e trevas
Shell Script - Luz e trevasShell Script - Luz e trevas
Shell Script - Luz e trevas
 
Tutorial Shell Script
Tutorial Shell ScriptTutorial Shell Script
Tutorial Shell Script
 
Oficina de shell script
Oficina de shell scriptOficina de shell script
Oficina de shell script
 
Introdução à Shellscript
Introdução à ShellscriptIntrodução à Shellscript
Introdução à Shellscript
 
Shell script
Shell scriptShell script
Shell script
 
Informática do básico ao essencial autor maurício v pires -amostra
Informática do básico ao essencial   autor maurício v pires -amostraInformática do básico ao essencial   autor maurício v pires -amostra
Informática do básico ao essencial autor maurício v pires -amostra
 
Shell script
Shell scriptShell script
Shell script
 
Minicurso Shell Script
Minicurso Shell ScriptMinicurso Shell Script
Minicurso Shell Script
 
Shell Script - Controle de fluxo
Shell Script - Controle de fluxoShell Script - Controle de fluxo
Shell Script - Controle de fluxo
 
Introducao ao Shell Script
Introducao ao Shell ScriptIntroducao ao Shell Script
Introducao ao Shell Script
 
Introdução ao Shell Script (versão estendida)
Introdução ao Shell Script (versão estendida)Introdução ao Shell Script (versão estendida)
Introdução ao Shell Script (versão estendida)
 
Shell Script Linux
Shell Script LinuxShell Script Linux
Shell Script Linux
 
Curso Gratuito de Shell Script
Curso Gratuito de Shell ScriptCurso Gratuito de Shell Script
Curso Gratuito de Shell Script
 

Semelhante a Curso de Shell Script

Curso de ShellScript - Lm01 shellscript
Curso de ShellScript - Lm01 shellscriptCurso de ShellScript - Lm01 shellscript
Curso de ShellScript - Lm01 shellscriptPessoal
 
Quero Arch! (Parte 1)
Quero Arch! (Parte 1)Quero Arch! (Parte 1)
Quero Arch! (Parte 1)Felipe Santos
 
01 apostila-introducao-shell
01   apostila-introducao-shell01   apostila-introducao-shell
01 apostila-introducao-shellvinicius caldeira
 
Quero Slack! (Parte 1)
Quero Slack! (Parte 1)Quero Slack! (Parte 1)
Quero Slack! (Parte 1)Felipe Santos
 
Sistemas operacionais1
Sistemas operacionais1Sistemas operacionais1
Sistemas operacionais1Nauber Gois
 
Oficinalinux Comotudo Começou
Oficinalinux Comotudo ComeçouOficinalinux Comotudo Começou
Oficinalinux Comotudo Começouguest96251d
 
Linux Como Tudo Começou
Linux Como Tudo ComeçouLinux Como Tudo Começou
Linux Como Tudo Começouguestaa94fe
 
Introdução ao Linux
Introdução ao LinuxIntrodução ao Linux
Introdução ao Linuxguest82cc1d
 
ApresentaçãO2 Sistema Operacional
ApresentaçãO2  Sistema OperacionalApresentaçãO2  Sistema Operacional
ApresentaçãO2 Sistema OperacionalCláudia Costa
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linuxeliezer
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linuxeliezer
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linuxguest7a481e8
 
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...Tchelinux
 

Semelhante a Curso de Shell Script (20)

Curso de ShellScript - Lm01 shellscript
Curso de ShellScript - Lm01 shellscriptCurso de ShellScript - Lm01 shellscript
Curso de ShellScript - Lm01 shellscript
 
Quero Arch! (Parte 1)
Quero Arch! (Parte 1)Quero Arch! (Parte 1)
Quero Arch! (Parte 1)
 
Unidade 3.6 Introdução ao Shell
Unidade 3.6 Introdução ao ShellUnidade 3.6 Introdução ao Shell
Unidade 3.6 Introdução ao Shell
 
01 apostila-introducao-shell
01   apostila-introducao-shell01   apostila-introducao-shell
01 apostila-introducao-shell
 
Apostila introducao-shell
Apostila introducao-shellApostila introducao-shell
Apostila introducao-shell
 
Quero Slack! (Parte 1)
Quero Slack! (Parte 1)Quero Slack! (Parte 1)
Quero Slack! (Parte 1)
 
O kernel do linux
O kernel do linuxO kernel do linux
O kernel do linux
 
Suse - GNU/Linux
Suse - GNU/LinuxSuse - GNU/Linux
Suse - GNU/Linux
 
Trabalho OpenSUSe
Trabalho OpenSUSeTrabalho OpenSUSe
Trabalho OpenSUSe
 
A.S.O 2 - Linux
A.S.O 2 - LinuxA.S.O 2 - Linux
A.S.O 2 - Linux
 
Sistemas operacionais1
Sistemas operacionais1Sistemas operacionais1
Sistemas operacionais1
 
Oficinalinux Comotudo Começou
Oficinalinux Comotudo ComeçouOficinalinux Comotudo Começou
Oficinalinux Comotudo Começou
 
Linux Como Tudo Começou
Linux Como Tudo ComeçouLinux Como Tudo Começou
Linux Como Tudo Começou
 
Introdução ao Linux
Introdução ao LinuxIntrodução ao Linux
Introdução ao Linux
 
Linux
LinuxLinux
Linux
 
ApresentaçãO2 Sistema Operacional
ApresentaçãO2  Sistema OperacionalApresentaçãO2  Sistema Operacional
ApresentaçãO2 Sistema Operacional
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
 
Apostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em LinuxApostila Treinamento AvançAdo Em Linux
Apostila Treinamento AvançAdo Em Linux
 
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
 

Curso de Shell Script

  • 1. LINUX USER Papo de Botequim Curso de Shell Script Papo de Botequim Você não agüenta mais aquele seu porque, em inglês, Shell significa con- cha, carapaça, isto é, fica entre o u- amigo usuário de Linux enchendo o suário e o sistema operacional, de forma que tudo que interage com seu saco com aquela história de que o o sistema operacional, tem que passar pelo seu crivo. sistema é fantástico e o Shell é uma ferramenta maravilhosa? A partir O ambiente Shell Bom já que para chegar ao desta edição vai ficar mais fácil en- núcleo do Linux, no seu ker- nel que é o que interessa a tender o porquê deste entusiasmo... todo aplicativo, é necessária a filtragem do Shell, vamos enten- POR JULIO CEZAR NEVES der como ele funciona de forma a tirar o máximo proveito das inú- meras facilidades que ele nos oferece. D iálogo entreouvido em uma mesa O Linux, por definição, é um sistema de um botequim, entre um multiusuário – não podemos nunca nos usuário de Linux e um empur- esquecer disto – e para permitir o acesso rador de mouse: O ambiente Linux de determinados usuários e barrar a en- • Quem é o Bash? Para você entender o que é e como fun- trada de outros, existe um arquivo cha- • É o filho caçula da família Shell. ciona o Shell, primeiro vou te mostrar mado /etc/passwd, que além de fornecer • Pô cara! Estás a fim de me deixar como funciona o ambiente em camadas dados para esta função de “leão-de-chá- maluco? Eu tinha uma dúvida e você do Linux. Dê uma olhada no gráfico cara” do Linux, também provê informa- me deixa com duas! mostrado na Figura 1. ções para o início de uma sessão (ou • Não, maluco você já é há muito tem- Neste gráfico podemos ver que a ca- “login”, para os íntimos) daqueles que po: desde que decidiu usar aquele sis- mada de hardware é a mais profunda e é passaram por esta primeira barreira. O tema operacional que você precisa formada pelos componentes físicos do último campo de seus registros informa reiniciar dez vezes por dia e ainda por seu computador. Em torno dela, vem a ao sistema qual é o Shell que a pessoa cima não tem domínio nenhum sobre camada do kernel que é o cerne do vai receber ao iniciar sua sessão. o que esta acontecendo no seu com- Linux, seu núcleo, e é quem põe o hard- Lembra que eu te falei de Shell, fa- putador. Mas deixa isso prá lá, pois ware para funcionar, fazendo seu geren- mília, irmão? Pois é, vamos começar a vou te explicar o que é Shell e os com- ciamento e controle. Os programas e entender isto: o Shell é a conceituação ponentes de sua família e ao final da comandos que envolvem o kernel, dele de concha envolvendo o sistema opera- nossa conversa você dirá: “Meu Deus se utilizam para realizar as tarefas para cional propriamente dito, é o nome do Shell! Porque eu não optei pelo que foram desenvolvidos. Fechando tudo genérico para tratar os filhos desta idéia Linux antes?”. isso vem o Shell, que leva este nome que, ao longo dos muitos anos de exis- Quadro 1: Uma rapidinha nos principais sabores de Shell Bourne Shell (sh): Desenvolvido por Stephen do sh e a elas agregou muitas outras. A com- C Shell (csh): Desenvolvido por Bill Joy, da Bourne do Bell Labs (da AT&T, onde também patibilidade total com o sh vem trazendo Universidade de Berkley, é o Shell mais uti- foi desenvolvido o Unix), foi durante muitos muitos usuários e programadores de Shell lizado em ambientes BSD. Foi ele quem intro- anos o Shell padrão do sistema operacional para este ambiente. duziu o histórico de comandos. A Unix. É também chamado de Standard Shell Boune Again Shell (bash): Desenvolvido ini- estruturação de seus comandos é bem simi- por ter sido durante vários anos o único, e é cialmente por Brian Fox e Chet Ramey, este é lar à da linguagem C. Seu grande pecado foi até hoje o mais utilizado. Foi portado para o Shell do projeto GNU. O número de seus ignorar a compatibilidade com o sh, partindo praticamente todos os ambientes Unix e dis- adeptos é o que mais cresce em todo o por um caminho próprio. tribuições Linux. mundo, seja por que ele é o Shell padrão do Além destes Shells existem outros, mas irei Korn Shell (ksh): Desenvolvido por David Linux, seja por sua grande diversidade de falar somente sobre os três primeiros, tratan- Korn, também do Bell Labs, é um supercon- comandos, que incorpora inclusive diversos do-os genericamente por Shell e assinalando junto do sh, isto é, possui todas as facilidades comandos característicos do C Shell. as especificidades de cada um. 82 Agosto 2004 www.linuxmagazine.com.br
  • 2. Papo de Botequim LINUX USER tência do sistema operacional Unix, redirecionamento, que pode ser de foram aparecendo. Atualmente existem Com que Shell eu vou? entrada (stdin), de saída (stdout) ou dos Quando digo que o último campo do arqui- diversos sabores de Shell (veja Quadro 1 erros (stderr), conforme vou explicar a vo /etc/passwd informa ao sistema qual é o na página anterior). seguir. Mas antes precisamos falar de... Shell que o usuário vai usar ao se “logar”, isto deve ser interpretado ao pé-da-letra. Se este Como funciona o Shell campo do seu registro contém o termo prog, Substituição de Variáveis O Shell é o primeiro programa que você ao acessar o sistema o usuário executará o Neste ponto, o Shell verifica se as even- ganha ao iniciar sua sessão (se quiser- programa prog. Ao término da execução, a tuais variáveis (parâmetros começados mos assassinar a língua portuguesa sessão do usuário se encerra automatica- por $), encontradas no escopo do mente. Imagine quanto se pode incremen- podemos também dizer “ao se logar”) no comando, estão definidas e as substitui tar a segurança com este simples artifício. Linux. É ele quem vai resolver um monte por seus valores atuais. de coisas de forma a não onerar o kernel com tarefas repetitivas, poupando-o para volvidos (inclusive o próprio programa), Substituição de Meta- tratar assuntos mais nobres. Como cada e retorna um erro caso o usuário que Caracteres usuário possui o seu próprio Shell inter- chamou o programa não esteja autor- Se algum meta-caracter (ou “coringa”, pondo-se entre ele e o Linux, é o Shell izado a executar esta tarefa. como *, ? ou []) for encontrado na linha quem interpreta os comandos digitados e de comando, ele será substituído por examina as suas sintaxes, passando-os $ ls linux seus possíveis valores. esmiuçados para execução. linux Supondo que o único item no seu • Êpa! Esse negócio de interpretar co- diretório corrente cujo nome começa mando não tem nada a ver com inter- Neste exemplo o Shell identificou o ls co- com a letra n seja um diretório chamado pretador não, né? mo um programa e o linux como um pa- nomegrandeprachuchu, se você fizer: • Tem sim: na verdade o Shell é um in- râmetro passado para o programa ls. terpretador que traz consigo uma po- $ cd n* derosa linguagem com comandos de Atribuição alto nível, que permite construção de Se o Shell encontra dois campos separa- como até aqui quem está manipulando a loops, de tomadas de decisão e de ar- dos por um sinal de igual (=) sem espa- linha de comando ainda é o Shell e o mazenamento de valores em variáveis, ços em branco entre eles, ele identifica programa cd ainda não foi executado, o como vou te mostrar. esta seqüência como uma atribuição. Shell expande o n* para nomegrandepra- • Vou explicar as principais tarefas que o chuchu (a única possibilidade válida) e Shell cumpre, na sua ordem de exe- $ valor=1000 executa o comando cd com sucesso. cução. Preste atenção, porque esta ordem é fundamental para o entendi- Neste caso, por não haver espaços em Entrega da linha de comando mento do resto do nosso bate papo. branco (que é um dos caracteres reserva- para o kernel dos), o Shell identificou uma atribuição e Completadas todas as tarefas anteriores, Análise da linha de comando colocou 1000 na variável valor. o Shell monta a linha de comando, já Neste exame o Shell identifica os carac- com todas as substituições feitas e teres especiais (reservados) que têm sig- Resolução de chama o kernel para executá-la em um nificado para a interpretação da linha e Redirecionamentos novo Shell (Shell filho), que ganha um logo em seguida verifica se a linha pas- Após identificar os componentes da li- número de processo (PID ou Process sada é um comando ou uma atribuição nha que você digitou, o Shell parte para IDentification) e fica inativo, tirando de valores, que são os ítens que vou a resolução de redirecionamentos. uma soneca durante a execução do pro- descrever a seguir. O Shell tem incorporado ao seu elenco grama. Uma vez encerrado este processo de habilidades o que chamamos de (e o Shell filho), o “Shell pai” recebe Comando novamente o controle e exibe um Quando um comando é digi- “prompt”, mostrando que está pronto tado no “prompt” (ou linha de Shell para executar outros comandos. comando) do Linux, ele é divi- dido em partes, separadas por Programas e Comandos Cuidado na Atribuição espaços em branco: a primeira Núcleo ou Kernel Jamais faça: parte é o nome do programa, cuja existência será verificada; Hardware $ valor = 1000 bash: valor: not found em seguida, nesta ordem, vêm Neste caso, o Bash achou a palavra valor iso- as opções/parâmetros, redire- lada por espaços e julgou que você estivesse cionamentos e variáveis. mandando executar um programa chama- Quando o programa identifi- do valor, para o qual estaria passando dois cado existe, o Shell verifica as parâmetros: = e 1000. permissões dos arquivos en- Figura 1: Ambiente em camadas de um sistema Linux www.linuxmagazine.com.br Agosto 2004 83
  • 3. LINUX USER Papo de Botequim Decifrando a Pedra de Roseta $ echo * esperando pelo teclado (Entrada Padrão) Para tirar aquela sensação que você tem $ echo * e como também não citei a saída, o que quando vê um script Shell, que mais eu teclar irá para a tela (Saída Padrão), parece uma sopa de letrinhas ou um con- Viu a diferença? criando desta forma – como eu havia junto de hieróglifos, vou lhe mostrar os • Aspas (“): exatamente iguais ao após- proposto – um programa gago. Experi- principais caracteres especiais para que trofo, exceto que, se a cadeia entre mente! você saia por aí como Champollion deci- aspas contiver um cifrão ($), uma frando a Pedra de Roseta. crase (`), ou uma barra invertida (), Redirecionamentop da Saída estes caracteres serão interpretados Padrão Caracteres para remoção do pelo Shell. Para especificarmos a saída de um pro- significado. Não precisa se estressar, eu não te dei grama usamos o símbolo “>” ou o É isso mesmo, quando não desejamos exemplos do uso das aspas por que “>>”, seguido do nome do arquivo pa- que o Shell interprete um caractere você ainda não conhece o cifrão ($) ra o qual se deseja mandar a saída. específico, devemos “escondê-lo” dele. nem a crase (`). Daqui para frente - Vamos transformar o programa ante- Isso pode ser feito de três maneiras difer- veremos com muita constância o uso rior em um “editor de textos”: entes, cada uma com sua peculiaridade: destes caracteres especiais; o mais • Apóstrofo (´): quando o Shell vê uma importante é entender seu significado. $ cat > Arq cadeia de caracteres entre apóstrofos, ele retira os apóstrofos da cadeia e não Caracteres de O cat continua sem ter a entrada especi- interpreta seu conteúdo. redirecionamento ficada, portanto está aguardando que os A maioria dos comandos tem uma entra- dados sejam teclados, porém a sua saída $ ls linuxm* da, uma saída e pode gerar erros. Esta está sendo desviada para o arquivo Arq. linuxmagazine entrada é chamada Entrada Padrão ou Assim sendo, tudo que esta sendo tecla- $ ls 'linuxm*' stdin e seu dispositivo padrão é o teclado do esta indo para dentro de Arq, de for- bash: linuxm* no such file U do terminal. Analogamente, a saída do ma que fizemos o editor de textos mais or directory comando é chamada Saída Padrão ou curto e ruim do planeta. stdout e seu dispositivo padrão é a tela Se eu fizer novamente: No primeiro caso o Shell “expandiu” o do terminal. Para a tela também são asterisco e descobriu o arquivo linux- enviadas normalmente as mensagens de $ cat > Arq magazine para listar. No segundo, os erro oriundas dos comandos, chamada apóstrofos inibiram a interpretação do neste caso de Saída de Erro Padrão ou Os dados contidos em Arq serão perdi- Shell e veio a resposta que não existe o stderr. Veremos agora como alterar este dos, já que antes do redirecionamento o arquivo linuxm*. estado de coisas. Shell criará um Arq vazio. Para colocar • Contrabarra ou Barra Invertida (): i- Vamos fazer um programa gago. Para mais informações no final do arquivo eu dêntico aos apóstrofos exceto que a isto digite (tecle “Enter” ao final de cada deveria ter feito: barra invertida inibe a interpretação linha – comandos do usuário são ilus- somente do caractere que a segue. trados em negrito): $ cat >> Arq Suponha que você, acidentalmente, tenha criado um arquivo chamado * $ cat Redirecionamento da Saída (asterisco) – o que alguns sabores de E-e-eu sou gago. Vai encarar? de Erro Padrão Unix permitem – e deseja removê-lo. E-e-eu sou gago. Vai encarar? Assim como por padrão o Shell recebe os Se você fizesse: dados do teclado e envia a saída para a O cat é um comando que lista o con- tela, os erros também vão para a tela se $ rm * teúdo do arquivo especificado para a você não especificar para onde eles de- Saída Padrão (stdout). Caso a entrada vem ser enviados. Para redirecionar os Você estaria na maior encrenca, pois o não seja definida, ele espera os dados da erros, use 2> SaidaDeErro. Note que en- rm removeria todos os arquivos do stdin (a entrada padrão). Ora como eu tre o número 2 e o sinal de maior (>) diretório corrente. A melhor forma de não especifiquei a entrada, ele a está não existe espaço em branco. fazer o serviço é: Vamos supor que durante a execução Redirecionamento Perigoso de um script você pode, ou não (depen- $ rm * Como já havia dito, o Shell resolve a linha e dendo do rumo tomado pela execução depois manda o comando para a execução. do programa), ter criado um arquivo Desta forma, o Shell não interpreta o Assim, se você redirecionar a saída de um chamado /tmp/seraqueexiste$$. Como asterisco, evitando a sua expansão. arquivo para ele próprio, primeiramente o não quer ficar com sujeira no disco Faça a seguinte experiência científica: Shell “esvazia”este arquivo e depois manda rígido, ao final do script você coloca a o comando para execução! Desta forma, linha a seguir: para sua alegria, você acabou de perder o $ cd /etc conteúdo de seu querido arquivo. $ echo '*' rm /tmp/seraqueexiste$$ 84 Agosto 2004 www.linuxmagazine.com.br
  • 4. Papo de Botequim LINUX USER caprichamos, né? Então ao invés de sair Dados ou Erros? redigindo o mail direto no “prompt”, de Etiquetas Erradas Preste atenção! Não confunda >> com 2>. O forma a tornar impossível a correção de Um erro comum no uso de labels (como o primeiro anexa dados ao final de um arqui- fimftp do exemplo anterior) é causado pela uma frase anterior onde, sem querer, vo, e o segundo redireciona a Saída de Erro presença de espaços em branco antes ou você escreveu um “nós vai”, você edita Padrão (stderr) para um arquivo que está após o mesmo. Fique muito atento quanto a um arquivo com o conteúdo da mensa- sendo designado. Isto é importante! isso, por que este tipo de erro costuma dar gem e após umas quinze verificações uma boa surra no programador, até que seja sem constatar nenhum erro, decide detectado. Lembre-se: um label que se preze Caso o arquivo não existisse seria envi- enviá-lo e para tal faz: tem que ter uma linha inteira só para ele. ado para a tela uma mensagem de erro. Para que isso não aconteça faça: $ mail chefe@chefia.com.br < U arquivocommailparaochefe nada a partir deste ponto até encontrar rm /tmp/seraqueexiste$$ 2> U o ‘label’ fimftp. Você não entenderia /dev/null e o chefe receberá uma mensagem com o droga nenhuma, já que são instruções conteúdo do arquivocommailparaochefe. específicas do ftp”. Para que você teste a Saída de Erro Pa- Outro tipo de redirecionamento “muito Se fosse só isso seria simples, mas drão direto no prompt do seu Shell, vou louco” que o Shell permite é o chamado pelo próprio exemplo dá para ver que dar mais um exemplo. Faça: “here document”. Ele é representado por existem duas variáveis ($Usuario e << e serve para indicar ao Shell que o $Senha), que o Shell vai resolver antes $ ls naoexiste escopo de um comando começa na linha do redirecionamento. Mas a grande bash: naoexiste no such file U seguinte e termina quando encontra uma vantagem deste tipo de construção é or directory linha cujo conteúdo seja unicamente o que ela permite que comandos tam- $ ls naoexiste 2> arquivodeerros “label” que segue o sinal <<. bém sejam interpretados dentro do $ Veja o fragmento de script a seguir, escopo do “here document”, o que, $ cat arquivodeerros com uma rotina de ftp: aliás, contraria o que acabei de dizer. bash: naoexiste no such file U Logo a seguir te explico como esse or directory ftp -ivn hostremoto << fimftp negócio funciona. Agora ainda não dá, user $Usuario $Senha estão faltando ferramentas. Neste exemplo, vimos que quando fize- binary • O comando user é do repertório de mos um ls em naoexiste, ganhamos uma get arquivoremoto instruções do ftp e serve para passar o mensagem de erro. Após redirecionar a fimftp usuário e a senha que haviam sido Saída de Erro Padrão para arquivodeerros lidos em uma rotina anterior a este e executar o mesmo comando, recebe- neste pedacinho de programa temos um fragmento de código e colocados res- mos somente o “prompt” na tela. Quan- monte de detalhes interessantes: pectivamente nas duas variáveis: do listamos o conteúdo do arquivo para • As opções usadas para o ftp (-ivn) $Usuario e $Senha. o qual foi redirecionada a Saída de Erro servem para ele listar tudo que está • O binary é outra instrução do ftp, que Padrão, vimos que a mensagem de erro acontecendo (opção -v de “verbose”), serve para indicar que a transferência tinha sido armazenada nele. para não ficar perguntando se você de arquivoremoto será feita em modo É interessante notar que estes carac- tem certeza que deseja transmitir cada binário, isto é o conteúdo do arquivo teres de redirecionamento são cumula- arquivo (opção -i de “interactive”) e não será inteerpretado para saber se tivos, isto é, se no exemplo anterior finalmente a opção -n serve para dizer está em ASCII, EBCDIC, … fizéssemos o seguinte: ao ftp para ele não solicitar o usuário e • O comando get arquivoremoto diz ao sua senha, pois estes serão informados cliente ftp para pegar este arquivo no $ ls naoexiste 2>> U pela instrução específica (user); servidor hostremoto e trazê-lo para a arquivodeerros • Quando eu usei o << fimftp, estava nossa máquina local. Se quiséssemos dizendo o seguinte para o interpreta- enviar um arquivo, bastaria usar, por a mensagem de erro oriunda do ls seria dor: “Olha aqui Shell, não se meta em exemplo, o comando put arquivolocal. anexada ao final de arquivodeerros. Direito de Posse Redirecionamento de Redirecionamento da O $$ contém o PID,isto é,o número do seu comandos Entrada Padrão processo. Como o Linux é multiusuário,é Os redirecionamentos de que falamos até Para fazermos o redirecionamento da En- bom anexar sempre o $$ ao nome dos seus agora sempre se referiam a arquivos, isto trada Padrão usamos o < (menor que). arquivos para não haver problema de propri- é, mandavam para arquivo, recebiam de “E pra que serve isso?”, você vai me per- edade,isto é,caso você batizasse o seu ar- arquivo, simulavam arquivo local, … O guntar. Deixa eu dar um exemplo, que quivo simplesmente como seraqueexiste,a que veremos a partir de agora, redirecio- você vai entender rapidinho. primeira pessoa que o usasse (criando-o na a saída de um comando para a entra- então) seria o seu dono e a segunda ganharia Suponha que você queira mandar um da de outro. É utilíssimo e, apesar de não um erro quando tentasse gravar algo nele. mail para o seu chefe. Para o chefe nós ser macaco gordo, sempre quebra os www.linuxmagazine.com.br Agosto 2004 85
  • 5. LINUX USER Papo de Botequim maiores galhos. Seu nome é “pipe” (que $ echo "Existem who | wc -l U $ (pwd ; cd /etc ; pwd) em inglês significa tubo, já que ele cana- usuarios conectados" /home/meudir liza a saída de um comando para a Existem who | wc -l usuarios U /etc entrada de outro) e sua representação é a conectados $ pwd | (barra vertical). /home/meudir Hi! Olha só, não funcionou! É mesmo, $ ls | wc -l não funcionou e não foi por causa das “Quequeiiisso” minha gente? Eu estava 21 aspas que eu coloquei, mas sim por que no /home/meudir, mudei para o /etc, eu teria que ter executado o who | wc -l constatei que estava neste diretório com O comando ls passou a lista de arquivos antes do echo. Para resolver este proble- o pwd seguinte e quando o agrupamento para o comando wc, que quando está ma, tenho que priorizar a segunda parte de comandos terminou, eu vi que conti- com a opção -l conta a quantidade de li- do comando com o uso de crases: nuava no /etc/meudir! nhas que recebeu. Desta forma, pode- Hi! Será que tem coisa do mágico mos afirmar categoricamente que no $ echo "Existem `who | wc -l` U Mandrake por aí? Nada disso. O interes- meu diretório existiam 21 arquivos. usuarios conectados" sante do uso de parênteses é que eles Existem 8 usuarios U invocam um novo Shell para executar os $ cat /etc/passwd | sort | lp conectados comandos que estão em seu interior. Desta forma, fomos realmente para o A linha de comandos acima manda a Para eliminar esse monte de brancos diretório /etc, porém após a execução de listagem do arquivo /etc/passwd para a antes do 8 que o wc -l produziu, basta todos os comandos, o novo Shell que entrada do comando sort. Este a classi- retirar as aspas. Assim: estava no diretório /etc morreu e retor- fica e envia para o lp que é o gerenciador namos ao Shell anterior que estava em da fila de impressão. $ echo Existem `who | wc -l` U /home/meudir. usuarios conectados Que tal usar nossos novos conceitos? Caracteres de ambiente Existem 8 usuarios conectados Quando queremos priorizar uma expres- $ mail suporte@linux.br << FIM são, nós a colocamos entre parênteses, As aspas protegem da interpretação do Ola suporte, hoje as `date U não é? Pois é, por causa da aritmética é Shell tudo que está dentro dos seus lim- “+%hh:mm”` ocorreu novamente U normal pensarmos deste jeito. Mas em ites. Como para o Shell basta um espaço aquele problema que eu havia U Shell o que prioriza mesmo são as crases em branco como separador, o monte de reportado por telefone. De U (`) e não os parênteses. Vou dar exemp- espaços será trocado por um único após acordo com seu pedido segue a U los para você entender melhor. a retirada das aspas. listagem do diretorio: Eu quero saber quantos usuários estão Outra coisa interessante é o uso do `ls -l` “logados” no computador que eu admi- ponto-e-vírgula. Quando estiver no Shell, Abracos a todos. nistro. Eu posso fazer: você deve sempre dar um comando em FIM cada linha. Para agrupar comandos em $ who | wc -l uma mesma linha, temos que separá-los Finalmente agora podemos demonstrar o 8 por ponto-e-vírgula. Então: que conversamos anteriormente sobre “here document”. Os comandos entre O comando who passa a lista de usuários $ pwd ; cd /etc; pwd ;cd -;pwd crases tem prioridade, portanto o Shell conectados ao sistema para o comando /home/meudir os executará antes do redirecionamento wc -l, que conta quantas linhas recebeu e /etc do “here document”. Quando o suporte mostra a resposta na tela. Muito bem, /home/meudir receber a mensagem, verá que os mas ao invés de ter um número oito comandos date e ls foram executados solto na tela, o que eu quero mesmo é Neste exemplo, listei o nome do diretório antes do comando mail, recebendo então que ele esteja no meio de uma frase. Ora, corrente com o comando pwd, mudei um instantâneo do ambiente no para mandar frases para a tela eu só pre- para o diretório /etc, novamente listei o momento de envio do email. ciso usar o comando echo; então vamos nome do diretório e finalmente voltei pa- - Garçom, passa a régua! s ver como é que fica: ra o diretório onde estava anteriormente (cd -), listando seu nome. Repare que Julio Cezar Neves é Analista de Su- SOBRE O AUTOR Buraco Negro coloquei o ponto-e-vírgula de todas as porte de Sistemas desde 1969 e tra- Em Unix existe um arquivo fantasma. formas possíveis, para mostrar que não balha com Unix desde 1980, quando Chama-se /dev/null.Tudo que é enviado importa se existem espaços em branco fez parte da equipe que desenvolveu para este arquivo some. Assemelha-se a um antes ou após este caracter. o SOX, sistema operacional, similar Buraco Negro. No caso do exemplo, como ao Unix, da Cobra Computadores. É Finalmente, vamos ver o caso dos não me interessava guardar a possível men- professor do curso de Mestrado em parênteses. No exemplo a seguir, colo- sagem de erro oriunda do comando rm, redi- Software Livre das Faculdades Estácio camos diversos comandos separados por recionei-a para este arquivo. de Sá, no Rio de Janeiro. ponto-e-vírgula entre parênteses: 86 Agosto 2004 www.linuxmagazine.com.br
  • 6. Papo de Botequim LINUX USER Curso de Shell Script Papo de Botequim - Parte II Nossos personagens voltam à mesa do bar para discutir expressões regulares e linhas que usavam a palavra grep, em todos os arquivos terminados em .sh. colocar a “mão na massa” pela primeira vez, construindo um aplicativo simples Como uso essa extensão para definir meus arquivos com programas em Shell, para catalogar uma coleção de CDs. POR JÚLIO CÉSAR NEVES malandramente, o que fiz foi listar as lin- has dos programas que poderia usar como exemplo do comando grep. G arçom! Traz um “chops” e dois Olha que legal! O grep aceita como “pastel”. O meu amigo hoje não entrada a saída de outro comando, redi- vai beber porque está finalmente recionado por um pipe (isso é muito sendo apresentado a um verdadeiro sis- comum em Shell e é um tremendo tema operacional, e ainda tem muita acelerador da execução de coman- coisa a aprender! dos). Dessa forma, no 3° exemplo, – E então, amigo, tá entendendo o comando who listou as pessoas tudo que te expliquei até agora? “logadas” na mesma máquina que – Entendendo eu tô, mas não vi você (não se esqueça jamais: o nada prático nisso… Linux é multiusuário) e o grep foi – Calma rapaz, o que te falei até usado para verificar se o Carvalho agora serve como base ao que há estava trabalhando ou “coçando”. de vir daqui pra frente. Vamos usar O grep é um comando muito con- essas ferramentas que vimos para hecido, pois é usado com muita fre- montar programas estruturados. Você qüência. O que muitas pessoas não verá porque até na TV já teve pro- sabem é que existem três comandos na grama chamado “O Shell é o Limite”. família grep: grep, egrep e fgrep. A princi- Para começar vamos falar dos coman- pais diferenças entre os 3 são: dos da família grep • grep - Pode ou não usar expressões – Grep? Não conheço nenhum termo em $ grep franklin /etc/passwd regulares simples, porém no caso de inglês com este nome… não usá-las, o fgrep é melhor, por ser – É claro, grep é um acrônimo (sigla) Pesquisando em vários arquivos: mais rápido. para Global Regular Expression Print, • egrep (“e” de extended, estendido) - É que usa expressões regulares para $ grep grep *.sh muito poderoso no uso de expressões pesquisar a ocorrência de cadeias de regulares. Por ser o mais poderoso dos caracteres na entrada definida. Pesquisando na saída de um comando: três, só deve ser usado quando for Por falar em expressões regulares (ou necessária a elaboração de uma regexp), o Aurélio Marinho Jargas es- $ who | grep carvalho expressão regular não aceita pelo grep. creveu dois artigos [1 e 2] imperdíveis • fgrep (“f” de fast, rápido) - Como o para a Revista do Linux sobre esse No 1º exemplo, procurei a palavra nome diz, é o ligeirinho da família, assunto e também publicou um livro [3] franklin em qualquer lugar do arquivo executando o serviço de forma muito pela Editora Novatec. Acho bom você ler /etc/passwd. Se quisesse procurar um veloz (por vezes é cerca de 30% mais esses artigos, eles vão te ajudar no que nome de usuário, isto é, somente no iní- rápido que o grep e 50% mais que o está para vir. cio dos registros desse arquivo, poderia egrep), porém não permite o uso de digitar $ grep ‘^franklin’ /etc/passwd. expressões regulares na pesquisa. Eu fico com grep,você com gripe “E para que servem o circunflexo e os –Agora que você já conhece as difer- Esse negócio de gripe é brincadeira, só apóstrofos?”, você vai me perguntar. Se enças entre os membros da família, me um pretexto para pedir umas caipirinhas. tivesse lido os artigos que mencionei, diga: o que você acha dos três exemplos Eu te falei que o grep procura cadeias de saberia que o circunflexo serve para limi- que eu dei antes das explicações? caracteres dentro de uma entrada defi- tar a pesquisa ao início de cada linha e – Achei que o fgrep resolveria o teu prob- nida, mas o que vem a ser uma “entrada os apóstrofos servem para o Shell não lema mais rapidamente que o grep. definida”? Bem, existem várias formas interpretar esse circunflexo, deixando-o – Perfeito! Tô vendo que você está de definir a entrada do comando grep. passar incólume para o comando grep. atento, entendendo tudo que estou te Veja só. Para pesquisar em um arquivo: No 2º exemplo mandei listar todas as explicando! Vamos ver mais exemplos www.linuxmagazine.com.br Setembro 2004 87
  • 7. LINUX USER Papo de Botequim Quadro 1 - Listando subdiretórios ser explorado). – Péra aí! De onde eu vou receber os $ ls -l | grep ‘^d’ dados dos CDs? drwxr-xr-x 3 root root 4096 Dec 18 2000 doc – Vou mostrar como o programa pode drwxr-xr-x 11 root root 4096 Jul 13 18:58 freeciv receber parâmetros de quem o estiver drwxr-xr-x 3 root root 4096 Oct 17 2000 gimp executando e, em breve, ensinarei a ler drwxr-xr-x 3 root root 4096 Aug 8 2000 gnome os dados da tela ou de um arquivo. drwxr-xr-x 2 root root 4096 Aug 8 2000 idl drwxrwxr-x 14 root root 4096 Jul 13 18:58 locale Passando parâmetros drwxrwxr-x 12 root root 4096 Jan 14 2000 lyx Veja abaixo a estrutura do arquivo con- drwxrwxr-x 3 root root 4096 Jan 17 2000 pixmaps tendo a lista das músicas: drwxr-xr-x 3 root root 4096 Jul 2 20:30 scribus drwxrwxr-x 3 root root 4096 Jan 17 2000 sounds nomedoálbum^intérprete1~nomeU drwxr-xr-x 3 root root 4096 Dec 18 2000 xine damúsica1:...:intérpreten~nomeU drwxr-xr-x 3 root root 4096 Jun 19 2000 xplns damúsican para clarear de vez as diferenças de -l). Os apóstrofos foram usados para o Isto é, o nome do álbum será separado uso entre os membros da família. Shell não “ver” o circunflexo. Vamos ver por um circunflexo do resto do registro, Eu sei que em um arquivo qualquer mais um. Veja na Tabela 1 as quatro formado por diversos grupos compostos existe um texto falando sobre Linux, só primeiras posições possíveis da saída de pelo intérprete de cada música do CD e a não tenho certeza se está escrito com L um ls -l em um arquivo comum (não é música interpretada. Estes grupos são maiúsculo ou minúsculo. Posso fazer diretório, nem link, nem …). separados entre si por dois pontos (:) e, uma busca de duas formas: Para descobrir todos os arquivos exe- internamente, o intérprete será separado cutáveis em um determinado diretório por um til (~) do nome da música. egrep (Linux | linux) arquivo.txt eu poderia fazer: Quero escrever um programa chamado musinc, que incluirá registros no meu ou então: $ ls -la | egrep ‘^-..(x|s)’ arquivo músicas. Passarei cada álbum como parâmetro para o programa: grep [Ll]inux arquivo.txt novamente usamos o circunflexo para limitar a pesquisa ao início de cada $ musinc “álbum^interprete~U No primeiro caso, a expressão regular linha, ou seja, listamos as linhas que musica:interprete~musica:...” complexa (Linux | linux) usa os parênte- começam por um traço (-), seguido de ses para agrupar as opções e a barra ver- qualquer coisa (o ponto), novamente Desta forma, musinc estará recebendo os tical (|) é usada como um “ou” (or, em seguido de qualquer coisa, e por fim um dados de cada álbum como se fosse uma inglês) lógico, isto é, estou procurando x ou um s. Obteríamos o mesmo resul- variável. A única diferença entre um Linux ou linux. tado se usássemos o comando: parâmetro recebido e uma variável é que No segundo, a expressão regular os primeiros recebem nomes numéricos [Ll]inux significa: começado por L ou l $ ls -la | grep ‘^-..[xs]’ (o que quis dizer é que seus nomes são seguido de inux. Como esta é uma formados somente por um algarismo, expressão simples, o grep consegue e além disso, agilizaríamos a pesquisa. isto é, $1, $2, $3, …, $9). Vamos, fazer resolvê-la, por isso é melhor usar a mais alguns testes: segunda forma, já que o egrep tornaria a A “CDteca” pesquisa mais lenta. Vamos começar a desenvolver progra- $ cat teste Outro exemplo. Para listar todos os mas! Creio que a montagem de um #!/bin/bash subdiretórios do diretório corrente, basta banco de dados de músicas é bacana #Teste de passagem de parametros usar o comando $ ls -l | grep ‘^d’. Veja o para efeito didático (e útil nestes tempos echo “1o. parm -> $1” resultado no Quadro 1. de downloads de arquivos MP3 e echo “2o. parm -> $2” No exemplo, o circunflexo (^) serviu queimadores de CDs). Não se esqueça echo “3o. parm -> $3” para limitar a pesquisa à primeira que, da mesma forma que vamos desen- posição da saída do ls longo (parâmetro volver um monte de programas para Agora vamos rodar esse programinha: organizar os seus CDs de música, com Tabela 1 pequenas adaptações você pode fazer o $ teste passando parametros para U mesmo para organizar os CDs de soft- testar Posição Valores possíveis 1ª - ware que vêm com a Linux Magazine e bash: teste: cannot execute 2ª r ou - outros que você compra ou queima, e 3ª w ou - disponibilizar esse banco de software Ops! Esqueci-me de tornar o script exe- 4ª x,s(suid) ou - para todos os que trabalham com você cutável. Vou fazer isso e testar nova- (o Linux é multiusuário, e como tal deve mente o programa: 88 Setembro 2004 www.linuxmagazine.com.br
  • 8. Papo de Botequim LINUX USER $ chmod 755 teste Execute o programa: inclusão de CDs no meu banco chamado $ teste passando parametros para U musicas. O programa é muito simples testar $ teste passando parametros para testar (como tudo em Shell). Veja a Listagem 1. 1o. parm -> passando O programa teste recebeu 4 U O script é simples e funcional; limito- 2o. parm -> parametros parametros me a anexar ao fim do arquivo musicas o 3o. parm -> para 1o. parm -> passando parâmetro recebido. Vamos cadastrar 3 2o. parm -> parametros álbuns para ver se funciona (para não Repare que a palavra testar, que seria o 3o. parm -> para ficar “enchendo lingüiça,” suponho que quarto parâmetro, não foi listada. Isso Para listar todos de uma U em cada CD só existem duas músicas): ocorreu porque o programa teste só lista “tacada” eu faco passando U os três primeiros parâmetros recebidos. parametros para testar $ musinc “album3^Artista5U Vamos executá-lo de outra forma: ~Musica5:Artista6~Musica5” Repare que antes das aspas usei uma $ musinc “album1^Artista1U $ teste “passando parametros” U barra invertida, para escondê-las da ~Musica1:Artista2~Musica2” para testar interpretação do Shell (se não usasse as $ musinc “album 2^Artista3U 1o. parm -> passando parametros contrabarras as aspas não apareceriam). ~Musica3:Artista4~Musica4” 2o. parm -> para Como disse, os parâmetros recebem 3o. parm -> testar números de 1 a 9, mas isso não significa Listando o conteúdo do arquivo musicas: que não posso usar mais de nove As aspas não deixaram o Shell ver o parâmetros. Significa que só posso $ cat musicas espaço em branco entre as duas endereçar nove. Vamos testar isso: album3^Artista5~Musica5:Artista6U primeiras palavras, e elas foram consid- ~Musica6 eradas como um único parâmetro. E $ cat teste album1^Artista1~Musica1:Artista2U falando em passagem de parâmetros, #!/bin/bash ~Musica2 uma dica: veja na Tabela 2 algumas var- # Programa para testar passagem U album2^Artista3~Musica3:Artista4U iáveis especiais. Vamos alterar o pro- de parametros (3a. Versao) ~Musica4 grama teste para usar as novas variáveis: echo O programa $0 recebeu $# U parametros Podia ter ficado melhor. Os álbuns estão $ cat teste echo “11o. parm -> $11” fora de ordem, dificultando a pesquisa. #!/bin/bash shift Vamos alterar nosso script e depois testá- # Programa para testar passagem U echo “2o. parm -> $1” lo novamente. Veja a listagem 2. Sim- de parametros (2a. Versao) shift 2 plesmente inseri uma linha que classifica echo O programa $0 recebeu $# U echo “4o. parm -> $1” o arquivo musicas, redirecionando a parametros saída para ele mesmo (para isso serve a echo “1o. parm -> $1” Execute o programa: opção -o), após cada álbum ser anexado. echo “2o. parm -> $2” echo “3o. parm -> $3” $ teste passando parametros para U $ cat musicas echo Para listar todos de uma U testar album1^Artista1~Musica1:Artista2U ”tacada” eu faco $* O programa teste recebeu 4 U ~Musica2 parametros que são: albu2^Artista3~Musica3:Artista4U Listagem 1: Incluindo CDs 11o. parm -> passando1 ~Musica4 na “CDTeca” 2o. parm -> parametros album3^Artista5~Musica5:Artista6U 4o. parm -> testar ~Musica6 $ cat musinc #!/bin/bash Duas coisas muito interessantes aconte- Oba! Agora o programa está legal e # Cadastra CDs (versao 1) ceram neste script. Para mostrar que os quase funcional. Ficará muito melhor em # nomes dos parâmetros variam de $1 a $9 uma nova versão, que desenvolveremos echo $1 >> musicas digitei echo $11 e o que aconteceu? O após aprender a adquirir os dados da tela Shell interpretou como sendo $1 seguido e formatar a entrada. do algarismo 1 e listou passando1; Listagem 2 O comando shift, cuja sintaxe é shift n, Tabela 2: Variáveis especiais podendo o n assumir qualquer valor $ cat musinc Variável Significado numérico, despreza os n primeiros #!/bin/bash $0 Contém o nome do programa parâmetros, tornando o parâmetro de # Cadastra CDs (versao 2) $# Contém a quantidade de ordem n+1. parâmetros passados # Bem, agora que você já sabe sobre $* Contém o conjunto de todos os echo $1 >> musicas passagem de parâmetros, vamos voltar à parâmetros (muito parecido com $@) sort -o musicas musicas nossa “cdteca” para fazer o script de www.linuxmagazine.com.br Setembro 2004 89
  • 9. LINUX USER Papo de Botequim Ficar listando arquivos com o grep <cadeia de caracteres> U Listagem 5 - musexc comando cat não está com nada, vamos [arq1, arq2, ..., arqn] fazer um programa chamado muslist $ cat musexc para listar um álbum, cujo nome será O grep entendeu que deveria procurar a #!/bin/bash passado como parâmetro. Veja o código cadeia de caracteres album nos arquivos # Exclui CDs (versao 1) na Listagem 3: 2 e musicas. Como o arquivo 2 não # Vamos executá-lo, procurando pelo existe, grep gerou o erro e, por encontrar grep -v “$1” musicas > /tmp/mus$$ album 2. Como já vimos antes, para pas- a palavra album em todos os registros de mv -f /tmp/mus$$ musicas sar a string album 2 é necessário pro- musicas, listou a todos. tegê-la da interpretação do Shell, para É melhor ignorarmos maiúsculas e que ele não a interprete como dois minúsculas na pesquisa. Resolveremos mando. Estamos então prontos para parâmetros. Exemplo: os dois problemas com a Listagem 4. desenvolver o script para remover CDs Nesse caso, usamos a opção -i do grep empenados da sua “CDteca”. Veja o $ muslist “album 2” que, como já vimos, serve para ignorar código da Listagem 5. grep: can’t open 2 maiúsculas e minúsculas, e colocamos o Na primeira linha mandei para musicas: album1^Artista1~Musica1U $1 entre aspas, para que o grep continu- /tmp/mus$$ o arquivo musicas, sem os :Artista2~Musica2 asse a ver a cadeia de caracteres resul- registros que atendessem a consulta feita musicas: album2^Artista3~Musica3U tante da expansão da linha pelo Shell pelo comando grep. Em seguida, movi :Artista4~Musica4 como um único argumento de pesquisa. /tmp/mus$$ por cima do antigo musicas. musicas:album3^Artista5~Musica5U Usei o arquivo /tmp/mus$$ como arqui- :Artista6~Musica6 $ muslist “album 2” vo de trabalho porque, como já havia album2^Artista3~Musica3:Artista4U citado no artigo anterior, o $$ contém o Que lambança! Onde está o erro? Eu tive ~Musica4 PID (identificação do processo) e, dessa o cuidado de colocar o parâmetro pas- forma, cada um que editar o arquivo sado entre aspas para o Shell não o Agora repare que o grep localiza a musicas o fará em um arquivo de tra- dividir em dois! É, mas repare como o cadeia pesquisada em qualquer lugar do balho diferente, evitando colisões. grep está sendo executado: registro; então, da forma que estamos Os programas que fizemos até aqui fazendo, podemos pesquisar por álbum, ainda são muito simples, devido à falta grep $1 musicas por música, por intérprete e mais. de ferramentas que ainda temos. Mas é Quando conhecermos os comandos bom praticar os exemplos dados porque, Mesmo colocando álbum 2 entre aspas, condicionais, montaremos uma nova eu prometo, chegaremos a desenvolver para que fosse encarado como um único versão de muslist que permitirá especi- um sistema bacana para controle dos parâmetro, quando o $1 foi passado pelo ficar por qual campo pesquisar. seus CDs. Na próxima vez que nos Shell para o comando grep, transformou- Ah! Em um dia de verão você foi à encontrarmos, vou te ensinar como fun- se em dois argumentos. Dessa forma, o praia, esqueceu os CDs no carro, aquele cionam os comandos condicionais e conteúdo da linha que o grep executou “solzinho” de 40 graus empenou seu aprimoraremos mais um pouco esses foi o seguinte: disco favorito e agora você precisa de scripts. Por hoje chega! Já falei demais e uma ferramenta para removê-lo do estou de goela seca! Garçom! Mais um grep album 2 musicas banco de dados? Não tem problema, sem colarinho! s vamos desenvolver um script chamado Como a sintaxe do grep é: musexc, para excluir estes CDs. INFORMAÇÕES Antes de desenvolver o “bacalho”, Listagem 3 - muslist quero te apresentar a uma opção bas- [1] http://www.revistadolinux.com.br/ed/003/ tante útil da família de comandos grep. É ferramentas.php3 $ cat muslist a opção -v, que quando usada lista todos [2] http://www.revistadolinux.com.br/ed/007/ #!/bin/bash os registros da entrada, exceto o(s) local- ereg.php3 # Consulta CDs (versao 1) izado(s) pelo comando. Exemplos: [3] http://www.aurelio.net/er/livro/ # grep $1 musicas $ grep -v “album 2” musicas album1^Artista1~Musica1:Artista2U Julio Cezar Neves é SOBRE O AUTOR Analista de Suporte de Listagem 4 ~Musica2 Sistemas desde 1969 e muslist melhorado album3^Artista5~Musica5:Artista6U trabalha com Unix ~Musica6 desde 1980, quando $ cat muslist fez parte da equipe #!/bin/bash Conforme expliquei antes, o grep do que desenvolveu o # Consulta CDs (versao 2) SOX, um sistema exemplo listou todos os registros de # operacional similar ao Unix, produzido musicas exceto o referente a album 2, pela Cobra Computadores. grep -i “$1” musicas porque atendia ao argumento do co- 90 Setembro 2004 www.linuxmagazine.com.br
  • 10. ���������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������� Papo de Botequim LINUX USER Curso de Shell Script Papo de botequim III Um chopinho, um aperitivo e o papo continua. Desta vez vamos aprender alguns comandos de manipulação de cadeias de caracteres, que serão muito úteis na hora de incrementar nossa “CDteca”. POR JULIO CEZAR NEVES G arçon! traga dois chopes por favor que hoje eu vou ter que falar muito. Primeiro quero mostrar uns programinhas simples de usar e muito úteis, como o cut, que Então, recapitulando, o layout do arquivo é o seguinte: nome do álbum^intérprete1~nome da música1:...: intérpreten~nome da músican, isto é, o nome do álbum será separado por um Artista2 Artista4 Artista6 Artista8 é usado para cortar um determinado circunflexo (^) do resto do registro, que Para entender melhor isso, vamos anali- pedaço de um arquivo. A sintaxe e é formado por diversos grupos compos- sar a primeira linha de musicas: alguns exemplos de uso podem ser vis- tos pelo intérprete de cada música do tos no Quadro 1: CD e a respectiva música interpretada. $ head -1 musicas Como dá para ver, existem quatro Estes grupos são separados entre si por album 1^Artista1~Musica1: U sintaxes distintas: na primeira (-c 1-5) dois-pontos (:) e o intérprete será sepa- Artista2~Musica2 especifiquei uma faixa, na segunda rado do nome da música por um til (~). (-c -6) especifiquei todo o texto até Então, para pegar os dados referentes Então observe o que foi feito: uma posição, na terceira (-c 4-) tudo de a todas as segundas músicas do arquivo uma determinada posição em diante e musicas, devemos digitar: album 1^Artista1~Musica1: U na quarta (-c 1,3,5,7,9), só as posições Artista2~Musica2 determinadas. A última possibilidade $ cut -f2 -d: musicas (-c -3,5,8-) foi só para mostrar que pode- Artista2~Musica2 Desta forma, no primeiro cut o primeiro mos misturar tudo. Artista4~Musica4 campo do delimitador (-d) dois-pon- Mas não pense que acabou por aí! Artista6~Musica5 tos (:) é album 1^Artista1~Musica1 e o Como você deve ter percebido, esta Artista8~Musica8@10_L: segundo, que é o que nos interessa, é forma de cut é muito útil para lidar com Artista2~Musica2. Vamos então ver o arquivos com campos de tamanho fi xo, Ou seja, cortamos o segundo campo que aconteceu no segundo cut: mas atualmente o que mais existe são z(-f de field, campo em inglês) delimi- arquivos com campos de tamanho vari- tado (-d) por dois-pontos (:). Mas, se Artista2~Musica2 ável, onde cada campo termina com um quisermos somente os intérpretes, deve- delimitador. Vamos dar uma olhada no mos digitar: Agora, primeiro campo do delimitador arquivo musicas que começamos a pre- (-d) til (~), que é o que nos interessa, parar na última vez que viemos aqui no $ cut -f2 -d: musicas | cut U é Artista2 e o segundo é Musica2. Se botequim. Veja o Quadro 2. -f1 -d~ o raciocínio que fizemos para a pri- ����������������������������� www.linuxmagazine.com.br Outubro 2004 85 ��������������������������������������������������������������������������������
  • 11. ��������������������������������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������� LINUX USER Papo de Botequim Quadro 1 – O comando cut meira linha for aplicado ao restante do arquivo, chegaremos à resposta ante- posta a um exercício prático, valendo nota, que passei ele me entregou um riormente dada. Outro comando muito script com todos os comandos sepa- A sintaxe do cut é: cut -c PosIni-PosFim interessante é o tr que serve para subs- rados por ponto-e-vírgula (lembre-se [arquivo], onde PosIni é a posição inicial, e tituir, comprimir ou remover caracteres. que o ponto-e-vírgula serve para sepa- PosFim a posição final. Veja os exemplos: Sua sintaxe segue o seguinte padrão: rar diversos comandos em uma mesma linha). Vou dar um exemplo simplifi- $ cat numeros tr [opções] cadeia1 [cadeia2] cado, e idiota, de um script assim: 1234567890 0987654321 O comando copia o texto da entrada $ cat confuso 1234554321 padrão (stdin), troca as ocorrência dos echo leia Programação Shell U 9876556789 caracteres de cadeia1 pelo seu corres- Linux do Julio Cezar Neves U pondente na cadeia2 ou troca múltiplas > livro;cat livro;pwd;ls;rm U $ cut -c1-5 numeros ocorrências dos caracteres de cadeia1 -f livro2>/dev/null;cd ~ 12345 por somente um caracter, ou ainda 09876 caracteres da cadeia1. As principais Eu executei o programa e ele funcionou: 12345 opções do comando são mostradas na 98765 Tabela 1. $ confuso Primeiro veja um exemplo bem bobo: leia Programação Shell Linux U $ cut -c-6 numeros do Julio Cezar Neves 123456 $ echo bobo | tr o a /home/jneves/LM 098765 baba confuso livro musexc musicas 123455 musinc muslist numeros 987655 Isto é, troquei todas as ocorrências da letra o pela letra a. Suponha que em Mas nota de prova é coisa séria (e nota $ cut -c4- numeros determinado ponto do meu script eu de dólar é mais ainda) então, para 4567890 peça ao operador para digitar s ou n entender o que o aluno havia feito, o 7654321 (sim ou não), e guardo sua resposta chamei e em sua frente digitei: 4554321 na variável $Resp. Ora, o conteúdo de 6556789 $Resp pode conter letras maiúsculas $ tr ”;” ”n” < confuso ou minúsculas, e desta forma eu teria echo leia Programação Shell U $ cut -c1,3,5,7,9 numeros que fazer diversos testes para saber se Linux do Julio Cezar Neves 13579 a resposta dada foi S, s, N ou n. Então o pwd 08642 melhor é fazer: cd ~ 13542 ls -l 97568 $ Resp=$(echo $Resp | tr SN sn) rm -f lixo 2>/dev/null $ cut -c -3,5,8- numeros e após este comando eu teria certeza O cara ficou muito desapontado, porque 1235890 de que o conteúdo de $Resp seria um em dois ou três segundos eu desfi z a 0986321 s ou um n. Se o meu arquivo ArqEnt gozação que ele perdeu horas para fazer. 1235321 está todo em letras maiúsculas e desejo Mas preste atenção! Se eu estivesse em 9875789 passá-las para minúsculas eu faço: uma máquina Unix, eu teria digitado: $ tr A-Z a-z < ArqEnt > / tmp/$$ $ tr ”;” ”012” < confuso Quadro 2 – O arquivo $ mv -f /tmp/$$ ArqEnt musicas Agora veja a diferença entre o resultado Note que neste caso usei a notação A- de um comando date executado hoje e Z para não escrever ABCD…YZ. Outro outro executado há duas semanas: $ cat musicas tipo de notação que pode ser usada são album 1^Artista1~Musica1:U as escape sequences (como eu traduzi- Sun Sep 19 14:59:54 2004 Artista2~Musica2 ria? Seqüências de escape? Meio sem Sun Sep 5 10:12:33 2004 album 2^Artista3~Musica3:U sentido, né? Mas vá lá…) que também Artista4~Musica4 são reconhecidas por outros comandos Notou o espaço extra após o “Sep” na album 3^Artista5~Musica5:U e também na linguagem C, e cujo signi- segunda linha? Para pegar a hora eu Artista6~Musica5 ficado você verá na Tabela 2: deveria digitar: album 4^Artista7~Musica7:U Deixa eu te contar um “causo”: um Artista8~Musica8 aluno que estava danado comigo resol- $ date | cut -f 4 -d ’ ’ veu complicar minha vida e como res- 14:59:54 ����������������������������� 86 Outubro 2004 www.linuxmagazine.com.br ��������������������������������������������������������������������������������
  • 12. ���������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������� Papo de Botequim LINUX USER Mas há duas semanas ocorreria o Bem a opção -d do tr remove do arquivo E veja também o date: seguinte: todas as ocorrências do caractere espe- cificado. Desta forma eu removi os $ date $ date | cut -f 4 -d ’ ’ caracteres indesejados, salvei o texto Mon Sep 20 10:47:19 BRT 2004 5 em um arquivo temporário e posterior- mente renomeei-o para o nome original. Repare que o mês e o dia estão no Isto porque existem 2 caracteres em Uma observação: em um sistema Unix mesmo formato em ambos os coman- branco antes do 5 (dia). Então o ideal eu deveria digitar: dos. Ora, se em algum registro do who seria transformar os espaços em branco eu não encontrar a data de hoje, é sinal consecutivos em somente um espaço $ tr -d ’015’ < ArqDoDOS.U que o usuário está “logado” há mais para poder tratar os dois resultados do txt > /tmp/$$ de um dia, já que ele não pode ter se comando date da mesma forma, e isso “logado” amanhã… Então vamos guar- se faz assim: Uma dica: o problema com os termina- dar o pedaço que importa da data de dores de linha (CR/LF) só aconteceu hoje para depois procurá-la na saída do $ date | tr -s ” ” porque a transferência do arquivo foi comando who: Sun Sep 5 10:12:33 2004 feita no modo binário (ou image), Se antes da transmissão do arquivo tivesse $ Data=$(date | cut -f 2-3 U E agora eu posso cortar: sido estipulada a opção ascii do ftp, isto -d’ ’) não teria ocorrido. $ date | tr -s ” ” | cut -f 4 U – Olha, depois desta dica tô começando a Eu usei a construção $(...), para prio- -d ” ” gostar deste tal de shell, mas ainda tem rizar a execução dos comandos antes 10:12:33 muita coisa que não consigo fazer. de atribuir a sua saída à variável Data. – Pois é, ainda não te falei quase nada Vamos ver se funcionou: Olha só como o Shell está quebrando o sobre programação em shell, ainda galho. Veja o conteúdo de um arquivo tem muita coisa para aprender, mas $ echo $Data baixado de uma máquina Windows: com o que aprendeu, já dá para resol- Sep 20 ver muitos problemas, desde que você $ cat -ve ArqDoDOS.txt adquira o “modo shell de pensar”. Você Beleza! Agora, o que temos que fazer é Este arquivo^M$ seria capaz de fazer um script que diga procurar no comando who os registros foi gerado pelo^M$ quais pessoas estão “logadas” há mais que não possuem esta data. DOS/Win e foi^M$ de um dia no seu servidor? baixado por um^M$ – Claro que não! Para isso seria necessá- – Ah! Eu acho que estou entendendo! ftp mal feito.^M$ rio eu conhecer os comandos condicio- Você falou em procurar e me ocorreu o nais que você ainda não me explicou comando grep, estou certo? Dica: a opção -v do cat mostra os carac- como funcionam. - Deixa eu tentar – Certíssimo! Só que eu tenho que usar o teres de controle invisíveis, com a nota- mudar um pouco a sua lógica e trazê- grep com aquela opção que ele só lista ção ^L, onde ^ é a tecla Control e L é la para o “modo shell de pensar”, mas os registros nos quais ele não encon- a respectiva letra. A opção -e mostra o antes é melhor tomarmos um chope. trou a cadeia. Você se lembra que fi nal da linha como um cifrão ($). Agora que já molhei a palavra, vamos opção é essa? Isto ocorre porque no DOS o fi m dos resolver o problema que te propus. Veja – Claro, a -v… registros é indicado por um Carriage como funciona o comando who: – Isso! Tá ficando bom! Vamos ver: Return (r – Retorno de Carro, CR) e um Line Feed (f – Avanço de Linha, ou $ who $ who | grep -v ”$Data” LF). No Linux porém o fi nal do regis- jneves pts/ U jneves pts/ U tro é indicado somente pelo Line Feed. 1 Sep 18 13:40 1 Sep 18 13:40 Vamos limpar este arquivo: rtorres pts/ U 0 Sep 20 07:01 Se eu quisesse um pouco mais de perfu- $ tr -d ’r’ < ArqDoDOS.txt > /tmp/$$ rlegaria pts/ U maria eu faria assim: $ mv -f /tmp/$$ ArqDoDOS.txt 1 Sep 20 08:19 lcarlos pts/ U $ who | grep -v ”$Data” |U Agora vamos ver o que aconteceu: 3 Sep 20 10:01 cut -f1 -d ’ ’ jneves $ cat -ve ArqDoDOS.txt Tabela 1 – O comando tr Este arquivo$ Opção Significado Viu? Não foi necessário usar comando foi gerado pelo$ condicional, até porque o nosso -s Comprime n ocorrências de DOS/Rwin e foi$ cadeia1 em apenas uma comando condicional, o famoso if, não baixado por um$ testa condição, mas sim instruções. -d Remove os caracteres de cadeia1 ftp mal feito.$ Mas antes veja isso: ����������������������������� www.linuxmagazine.com.br Outubro 2004 87 ��������������������������������������������������������������������������������