Difference: TWikiTasca001 (1 vs. 4)

Revision 414 Feb 2012 - MarioSilva

Line: 1 to 1
 

Conversa de Tasca - Parte I

* Em processo de adaptação * Regista-te e ajuda a adaptar *

Line: 497 to 497
 Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para julio.neves@gmail.com. Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para julio.neves@uniriotec.br para informar-se.

Valeu!

Added:
>
>

Revision 304 Feb 2008 - MarcoSilva

Line: 1 to 1
 

Conversa de Tasca - Parte I

* Em processo de adaptação * Regista-te e ajuda a adaptar *

Line: 15 to 15
      - Meu! Queres deixar-me maluco? Eu tinha uma dúvida e agora fico com duas!
Changed:
<
<
    - Não, maluco já tu és há muito tempo. Desde que te decidiste usar aquele sistema operativo em que tens de dar dez boots por dia e não tens domínio nenhum sobre o que esta a acontecer no teu computador. Mas deixa isso, vou-te explicar o que é Shell e os componentes da sua família e ao final da explicação dirás: "Meu Deus do Shell! Porque eu não optei pelo Linux antes?".
>
>
    - Não, maluco já tu és há muito tempo. Desde que te decidiste usar aquele sistema operativo em que tens de dar dez boots por dia e não tens domínio nenhum sobre o que esta a acontecer no teu computador. Mas deixa isso, vou-te explicar o que é Shell e os componentes da sua família e ao final da explicação dirás: "Meu Deus da Shell! Porque eu não optei pelo Linux antes?".
 

O Ambiente Linux

Changed:
<
<
Para entenderes o que é e como funciona o Shell, primeiro vou-te mostrar como funciona o ambiente em camadas do Linux. Dá uma vista de olhos no gráfico abaixo:
>
>
Para entenderes o que é e como funciona a Shell, primeiro vou-te mostrar como funciona o ambiente em camadas do Linux. Dá uma vista de olhos no gráfico abaixo:
 
Visão do shell em relação do Kernel do Linux
Changed:
<
<
Neste gráfico dá para ver que a camada de hardware é a mais profunda e é formada pelos componentes físicos do teu computador. Envolvendo esta, vem a camada do kernel que é o cerne do Linux, seu núcleo, e é quem bota o hardware para funcionar, fazendo a sua gestão e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas aplicativas para que foram desenvolvidos. Fechando tudo isso vem o Shell que leva este nome porque em inglês, Shell significa concha, carapaça, isto é, fica entre o utilizador e o sistema operativo, de forma que tudo que interage com o sistema operativo, tem que passar pelo seu crivo.
>
>
Neste gráfico dá para ver que a camada de hardware é a mais profunda e é formada pelos componentes físicos do teu computador. Envolvendo esta, vem a camada do kernel que é o cerne do Linux, seu núcleo, e é quem coloca o hardware para funcionar, fazendo a sua gestão e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas aplicativas para que foram desenvolvidos. Fechando tudo isso vem o Shell que leva este nome porque em inglês, Shell significa concha, carapaça, isto é, fica entre o utilizador e o sistema operativo, de forma que tudo que interage com o sistema operativo, tem que passar pelo seu crivo.
 

O Ambiente Shell

Changed:
<
<
Bom já que para chegar ao núcleo do Linux, no seu kernel que é o que interessa a todo aplicativo, é necessária a filtragem do Shell, vamos entender como é que ele funciona de forma a tirar o máximo proveito das inúmeras facilidades que ele nos oferece.
>
>
Bom já que para chegar ao núcleo do Linux, no seu kernel que é o que interessa a todo aplicativo, é necessária a filtragem da Shell, vamos entender como é que ele funciona de forma a tirar o máximo proveito das inúmeras facilidades que ele nos oferece.
  O Linux por definição é um sistema multi-utilizador - não podemos nunca esquecer disto – e para permitir o acesso de determinados utilizadores e barrar a entrada de outros, existe um arquivo chamado /etc/passwd que além fornecer dados para esta função de "leão-de-chácara" do Linux, também provê informações para o login daqueles que passaram por esta primeira barreira. O último campo de seus registos informa ao sistema qual Shell a pessoa vai receber ao se "logar" (ARGH!!!).

Pinguim com placa de dica
Changed:
<
<
Quando eu disse que o último campo do /etc/passwd informa ao sistema qual é o Shell que o utilizador vai receber ao se "logar", é para ser interpretado ao pé-da-letra, isto é, se neste campo do teu registro estiver prog, a pessoa ao acessar o sistema receberá a tela de execução do programa prog e ao terminar a sua execução ganhará imediatamente um logout. Imagine o quanto se pode incrementar a segurança com este simples artifício.
>
>
Quando eu disse que o último campo do /etc/passwd informa ao sistema qual é a Shell que o utilizador vai receber ao se "logar", é para ser interpretado ao pé-da-letra, isto é, se neste campo do teu registro estiver prog, a pessoa ao acessar o sistema receberá a tela de execução do programa prog e ao terminar a sua execução ganhará imediatamente um logout. Imagine o quanto se pode incrementar a segurança com este simples artifício.
 
Changed:
<
<
Lembras-te que eu te falei do Shell, família, irmão? Pois é, vamos começar a entender isto: o Shell, que se vale da imagem de uma concha envolvendo o sistema operativo propriamente dito, é o nome genérico para tratar os filhos desta idéia que, ao longo dos anos de existência do sistema operativo Unix foram aparecendo. Actualmente existem diversos sabores de Shell, dentre estes eu destaco o sh (Bourne Shell), o ksh (Korn Shell), bash (Bourne Again Shell) e o csh (C Shell).
>
>
Lembras-te que eu te falei da Shell, família, irmão? Pois é, vamos começar a entender isto: a Shell, que se vale da imagem de uma concha envolvendo o sistema operativo propriamente dito, é o nome genérico para tratar os filhos desta idéia que, ao longo dos anos de existência do sistema operativo Unix foram aparecendo. Actualmente existem diversos sabores de Shell, dentre estes eu destaco o sh (Bourne Shell), o ksh (Korn Shell), bash (Bourne Again Shell) e o csh (C Shell).
 

Uma Rapidinha nos Principais Sabores de Shell

Bourne Shell (sh)

Changed:
<
<
Desenvolvido por Stephen Bourne da Bell Labs (da AT&T onde também foi desenvolvido o Unix), este foi durante muitos anos o Shell default do sistema operativo Unix. É também chamado de Standard Shell por ter sido durante vários anos o único e até hoje é o mais utilizado até porque ele foi portado para todos os ambientes Unix e distros Linux.
>
>
Desenvolvido por Stephen Bourne da Bell Labs (da AT&T onde também foi desenvolvido o Unix), este foi durante muitos anos o Shell default do sistema operativo Unix. É também chamado de Standard Shell por ter sido durante vários anos o único e até hoje é o mais utilizado até porque ele foi portado para todos os ambientes Unix e distribuições (também chamadas de distros) Linux.
 

Korn Shell (ksh)

Changed:
<
<
Desenvolvido por David Korn, também da Bell Labs, é um superset do sh, isto é, possui todas as facilidades do sh e a elas agregou muitas outras. A compatibilidade total com o sh vem trazendo muitos utilizadores e programadores de Shell para este ambiente.
>
>
Desenvolvido por David Korn, também da Bell Labs, é um superset do sh, isto é, possui todas as facilidades do sh e a elas juntou muitas outras. A compatibilidade total com o sh chama muitos utilizadores e programadores de Shell para este ambiente.
 

Boune Again Shell (bash)

Changed:
<
<
Este é o Shell mais moderno e cujo número de adeptos mais cresce em todo o mundo, seja por ser o Shell default do Linux, seu sistema operativo hospedeiro, seja por sua grande diversidade de comandos, que incorpora inclusive diversos instruções características do C Shell.
>
>
Este é a Shell mais moderno e cujo número de adeptos mais cresce em todo o mundo, seja por ser o Shell default do Linux, o seu sistema operativo hospedeiro, seja pela sua grande diversidade de comandos, que incorpora inclusivé diversos instruções características do C Shell.
 

C Shell (csh)

Changed:
<
<
Desenvolvido por Bill Joy da Berkley University é o Shell mais utilizado em ambientes *BSD e Xenix. A estruturação de seus comandos é bem similar à da linguagem C. Seu grande pecado foi ignorar a compatibilidade com o sh, partindo por um caminho próprio.
>
>
Desenvolvido por Bill Joy da Berkley University é a Shell mais utilizada em ambientes *BSD e Xenix. A estruturação dos seus comandos é muito parecida à da linguagem C. O seu grande pecado foi ignorar a compatibilidade com o sh, partindo por um caminho próprio.
 
Changed:
<
<
Além destes Shells existem outros, mas irei falar contigo somente sobre os três primeiros, tratando-os genericamente por Shell e assinalando as especificidades de cada um que porventura hajam.
>
>
Além destas Shells existem outras, mas irei falar-te somente sobre os três primeiros, tratando-os genericamente por Shell e assinalando as especificidades de cada um que porventura hajam.
 
Changed:
<
<

Explicando o funcionamento do Shell

>
>

Explicando o funcionamento da Shell

 
Changed:
<
<
O Shell é o primeiro programa que ganhas ao te "logares" no Linux. É ele que vai resolver um monte de coisas de forma a não onerar o kernel com tarefas repetitivas, aliviando-o para tratar assuntos mais nobres. Como cada utilizador possui o seu próprio Shell interpondo-se entre ele e o Linux, é o Shell quem interpreta os comandos que são teclados e examina as suas sintaxes, passando-os esmiuçados para execução.
>
>
A Shell é o primeiro programa que tens ao te "logares" no Linux. É ele que vai resolver um monte de coisas de forma a não onerar o kernel com tarefas repetitivas, aliviando-o para tratar assuntos mais nobres. Como cada utilizador possui a sua própria Shell interpondo-se entre ele e o Linux, é a Shell quem interpreta os comandos que são teclados e examina as suas sintaxes, passando-os esmiuçados para execução.
 
Changed:
<
<
    - Êpa! Esse negócio de interpreta comando não tem nada a haver com interpretador não, né?
>
>
    -Epá! Isso de interpreta comando não tem nada haver com interpretador, pois não?
 
Changed:
<
<
    - Tem sim, na verdade o Shell é um interpretador (ou será intérprete) que traz consigo uma poderosa linguagem com comandos de alto nível, que permite construção de loops (laços), de tomadas de decisão e de armazenamento de valores em variáveis, como vou te mostrar.
>
>
    - Tem sim, na verdade a Shell é um interpretador (ou será intérprete) que traz consigo uma poderosa linguagem com comandos de alto nível, que permite construção de loops (ciclos), de tomadas de decisão e de armazenamento de valores em variáveis, como vou te mostrar.
 
Changed:
<
<
Vou te explicar as principais tarefas que o Shell cumpre, na sua ordem de execução. Preste atenção nesta ordem porque ela é fundamental para o entendimento do resto do nosso bate papo.
>
>
Vou te explicar as principais tarefas que a Shell cumpre, na sua ordem de execução. Presta atenção nesta ordem porque ela é fundamental para o entendimento do resto da nossa convesa.
 

Exame da Linha de Comandos

Changed:
<
<
Neste exame o Shell identifica os caracteres especiais (reservados) que têm significado para interpretação da linha, logo após verifica se a linha passada é uma atribuição ou um comando.
>
>
Nesta análise a Shell identifica os caracteres especiais (reservados) que têm significado para a interpretação da linha, logo a seguir verifica se a linha passada é uma atribuição ou um comando.
 
Atribuição
Changed:
<
<
Se o Shell encontra dois campos separados por um sinal de igual (=) sem espaços em branco entre eles, identifica esta seqüência como uma atribuição.
>
>
Se a Shell encontra dois campos separados por um sinal de igual (=) sem espaços em branco entre eles, identifica esta sequência como uma atribuição.
  Exemplos
Line: 81 to 81
  linux
Changed:
<
<
Neste exemplo o Shell identificou o ls como um programa e o linux como um parâmetro passado para o programa ls.
>
>
Neste exemplo a Shell identificou o ls como um programa e o linux como um parâmetro passado para o programa ls.
 
$ valor=1000
Changed:
<
<
Neste caso, por não haver espaços em branco (já dá para notar que o branco é um dos caracteres reservados) o Shell identificou uma atribuição e colocou 1000 na variável valor.
>
>
Neste caso, por não haver espaços em branco (já dá para notar que o espaço em branco é um dos caracteres reservados) a Shell identificou uma atribuição e colocou 1000 na variável valor.
 
Pinguim com placa de dica
Changed:
<
<
Jamais Faça:
>
>
Nunca Faça:
 
$ valor = 1000 bash: valor: not found
Changed:
<
<
Neste caso, o Bash achou a palavra valor isolada por brancos e julgou que você estivesse mandando executar um programa chamado valor, para o qual estaria passando dois parâmetros: = e 1000.
>
>
Neste caso, o Bash encontrou a palavra valor isolada por espaços brancos e julgou que estivesse a mandar executar um programa chamado valor, para o qual estaria a passar dois parâmetros: = e 1000.
 

Comando
Changed:
<
<
Quando uma linha é digitada no prompt do Linux, ela é dividida em pedaços separados por espaço em branco: o primeiro pedaço é o nome do programa que terá sua existência pesquisada; identifica em seguida, nesta ordem, opções/parâmetros, redireccionamentos e variáveis.
>
>
Quando uma linha é digitada na prompt do Linux, ela é dividida em pedaços separados por espaços em branco: o primeiro pedaço é o nome do programa que terá sua existência pesquisada; identifica em seguida, nesta ordem, opções/parâmetros, redireccionamentos e variáveis.
 
Changed:
<
<
Quando o programa identificado existe, o Shell verifica as permissões dos arquivos envolvidos (inclusive o próprio programa), dando um erro caso você não esteja credenciado a executar esta tarefa.
>
>
Quando o programa identificado existe, a Shell verifica as permissões dos arquivos envolvidos (inclusivé o próprio programa), dando um erro caso não estejas credenciado a executar esta tarefa.
 
Resolução de Redireccionamentos
Changed:
<
<
Após identificar os componentes da linha que você teclou, o Shell parte para a resolução de redireccionamentos. O Shell tem incorporado ao seu elenco de vantagens o que chamamos de redireccionamento, que pode ser de entrada (stdin), de saída (stdout) ou dos erros (stderr), conforme vou te explicar a seguir.
>
>
Após identificar os componentes da linha que digitaste, a Shell parte para a resolução de redireccionamentos. A Shell tem incorporado ao seu leque de vantagens o que chamamos de redireccionamento, que pode ser de entrada (stdin), de saída (stdout) ou dos erros (stderr), conforme te vou explicar a seguir.
 
Substituição de Variáveis
Changed:
<
<
Neste ponto, o Shell verifica se as eventuais variáveis (parâmetros começados por $), encontradas no escopo do comando, estão definidas e as substitui por seus valores atuais.
>
>
Neste ponto, a Shell verifica se as eventuais variáveis (parâmetros começados por $), encontradas nos limites do comando, estão definidas e substitui-as pelos seus valores actuais.
 
Substituição de Meta Caracteres
Changed:
<
<
Se algum metacaractere (*, ? ou []) foi encontrado na linha de comando, neste ponto ele será substituído por seus possíveis valores. Supondo que o único arquivo no seu directório corrente começado pela letra n seja um directório chamado nomegrandeprachuchu, se você fizer:
>
>
Se algum meta-carácter (*, ? ou []) foi encontrado na linha de comando, neste ponto ele será substituído pelos seus possíveis valores. Supondo que o único arquivo no teu directório corrente começado pela letra n seja um directório chamado nomegrandepacarambra, se fizeres:
 
$ cd n*
Changed:
<
<
Como até aqui quem esta trabalhando a sua linha é o Shell e o comando (programa) cd ainda não foi executado, o Shell transforma o n* em nomegrandeprachuchu e o comando cd será executado com sucesso.
>
>
Como até aqui quem esta a trabalhar a tua linha é a Shell e o comando (programa) cd ainda não foi executado, a Shell transforma o n* em nomegrandepacaramba e o comando cd será executado com sucesso.
 
Passa Linha de Comando para o kernel
Changed:
<
<
Completadas as tarefas anteriores, o Shell monta a linha de comandos, já com todas as substituições feitas, chama o kernel para executá-la em um novo Shell (Shell filho), ganhando um número de processo (PID ou Process IDentification) e permanece inativo, tirando uma soneca, durante a execução do programa. Uma vez encerrado este processo (juntamente com o Shell filho), recebe novamente o controle e, exibindo um prompt, mostra que está pronto para executar outros comandos.
>
>
Completadas as tarefas anteriores, a Shell monta a linha de comandos, já com todas as substituições feitas, chama o kernel para executá-la numa nova Shell (Shell filho), ganhando um número de processo (PID ou Process IDentification) e permanece inactivo, tirando uma soneca, durante a execução do programa. Uma vez encerrado este processo (juntamente com a Shell filho), recebe novamente o controle e, exibindo um prompt, mostra que está pronto para executar outros comandos.
 

Decifrando a Pedra da Roseta

Changed:
<
<
Para tirar aquela sensação que você tem quando vê um script Shell, que mais parece uma sopa de letrinhas ou um hieróglifo vou lhe mostrar os principais caracteres especiais para que você saia por ai como o Jean-François Champollion decifrando a Pedra da Roseta (dê uma "googlada" para descobrir quem é este cara, acho que vale a pena).
>
>
Para tirar aquela sensação que tens quando vês um script Shell, que mais parece uma sopa de letrinhas ou um hieróglifo vou mostrar-te os principais caracteres especiais para que saias por ai como o Jean-François Champollion decifrando a Pedra da Roseta (dá uma "googlada" para descobrir quem é este homem, acho que vale a pena).
 

Caracteres para remoção do significado

Changed:
<
<
É isso mesmo, quando não desejamos que o Shell interprete um carácter especial, devemos "escondê-lo" dele. Isso pode ser feito de três formas distintas:
>
>
É isso mesmo, quando não desejamos que a Shell interprete um carácter especial, devemos "escondê-lo" dele. Isso pode ser feito de três formas distintas:
 
Apóstrofo ou plic (')
Changed:
<
<
Quando o Shell vê uma cadeia de caracteres entre apóstrofos ('), ele tira os apóstrofos da cadeia e não interpreta seu conteúdo.
>
>
Quando a Shell vê uma cadeia de caracteres entre apóstrofos ('), ela tira os apóstrofos da cadeia e não interpreta o seu conteúdo.
 
$ ls linux*
Line: 149 to 149
  bash: linux* no such file or directory
Changed:
<
<
No primeiro caso o Shell "expandiu" o asterisco e descobriu o arquivo linuxmagazine para listar. No segundo, os apóstrofos inibiram a interpretação do Shell e veio a resposta que não existe o arquivo linux*.
>
>
No primeiro caso a Shell "expandiu" o asterísco e descobriu o arquivo linuxmagazine para listar. No segundo, os apóstrofos inibiram a interpretação da Shell e veio a resposta que não existe o arquivo linux*.
 
Contrabarra ou Barra Invertida (\)

Idêntico aos apóstrofos excepto que a barra invertida inibe a interpretação somente do carácter que a segue.

Changed:
<
<
Suponha que você acidentalmente tenha criado um arquivo chamado * (asterisco) – que alguns sabores de Unix permitem - e deseja removê-lo. Se você fizesse:
>
>
Supõem que acidentalmente tinhas criado um arquivo chamado * (asterísco) – que alguns sabores de Unix permitem - e deseja removê-lo. Se fizeres:
 
$ rm *
Changed:
<
<
Você estaria fazendo a maior encrenca, pois o rm removeria todos os arquivos do directório corrente. A melhor forma de fazer o pretendido é:
>
>
Estarias a fazer a maior burrada, pois o rm removeria todos os arquivos do directório corrente. A melhor forma de fazer o pretendido é:
 
$ rm \*
Changed:
<
<
Desta forma, o Shell não interpretaria o asterisco, e em consequência não faria a sua expansão.
>
>
Desta forma, a Shell não interpretaria o asterísco, e em consequência não faria a sua expansão.
  Faça a seguinte experiência científica:
Line: 178 to 178
  $ echo *
Changed:
<
<
Viu a diferença? Então não precisa explicar mais.
>
>
Viste a diferença? Então não é preciso explicar mais.
 
Aspas (")
Changed:
<
<
Exatamente igual ao apóstrofo excepto que, se a cadeia entre aspas contiver um cifrão ($), uma crase (`), ou uma barra invertida (\), estes caracteres serão interpretados pelo Shell.
>
>
Exatamente igual ao apóstrofo excepto que, se a cadeia entre aspas contiver um cifrão ($), uma crase (`), ou uma barra invertida (\), estes caracteres serão interpretados pela Shell.
  Não precisa se estressar, eu não te dei exemplos do uso das aspas por que você ainda não conhece o cifrão ($) nem a crase (`). Daqui para frente veremos com muita constância o uso destes caracteres especiais, o mais importante é entender o significado de cada um.
Line: 216 to 216
  $ cat > Arq
Changed:
<
<
Os dados contidos em Arq serão perdidos, já que antes do redireccionamento o Shell criará um Arq vazio. Para colocar mais informações no final do arquivo eu deveria ter feito:
>
>
Os dados contidos em Arq serão perdidos, já que antes do redireccionamento a Shell criará um Arq vazio. Para colocar mais informações no final do arquivo eu deveria ter feito:
 
$ cat >> Arq

Pinguim com placa de atenção
Changed:
<
<
Como já havia lhe dito, o Shell resolve a linha e depois manda o comando para a execução. Assim, se você redirecionar a saída de um arquivo para ele próprio, primeiramente o Shell "esvazia" este arquivo e depois manda o comando para execução, desta forma você acabou de perder o conteúdo do teu querido arquivo.
>
>
Como já havia lhe dito, a Shell resolve a linha e depois manda o comando para a execução. Assim, se você redirecionar a saída de um arquivo para ele próprio, primeiramente a Shell "esvazia" este arquivo e depois manda o comando para execução, desta forma você acabou de perder o conteúdo do teu querido arquivo.
 

Com isso dá para notar que o >> (maior maior) serve para inserir texto no final do arquivo.

Redireccionamento da Saída de Erro Padrão
Changed:
<
<
Assim como o default do Shell é receber os dados do teclado e mandar as saídas para a tela, os erros também serão enviados para a tela se você não especificar para onde deverão ser enviados. Para redirecionar os erros use 2> SaidaDeErro. Note que entre o número 2 e o sinal de maior (>) não existe espaço em branco.
>
>
Assim como o default da Shell é receber os dados do teclado e mandar as saídas para a tela, os erros também serão enviados para a tela se você não especificar para onde deverão ser enviados. Para redirecionar os erros use 2> SaidaDeErro. Note que entre o número 2 e o sinal de maior (>) não existe espaço em branco.
 
Pinguim com placa de atenção Preste atenção! Não confunda >> com 2>. O primeiro anexa dados ao final de um arquivo, e o segundo redireciona a Saída de Erro Padrão (stderr) para um arquivo que está sendo designado. Isso é importante!
Line: 303 to 303
 
Here Document
Changed:
<
<
Um outro tipo de redireccionamento muito louco que o Shell te permite é o chamado here document. Ele é representado por << (menor menor) e serve para indicar ao Shell que o escopo de um comando começa na linha seguinte e termina quando encontra uma linha cujo conteúdo seja unicamente o label que segue o sinal <<.
>
>
Um outro tipo de redireccionamento muito louco que a Shell te permite é o chamado here document. Ele é representado por << (menor menor) e serve para indicar aa Shell que o escopo de um comando começa na linha seguinte e termina quando encontra uma linha cujo conteúdo seja unicamente o label que segue o sinal <<.
  Veja o fragmento de script a seguir, com uma rotina de ftp:
Line: 317 to 317
  Neste pedacinho de programa temos um monte de detalhes interessantes:
  1. As opções que usei para o ftp (-ivn) servem para ele ir listando tudo que está acontecendo (—v de verbose), para não perguntar se você tem certeza de que deseja transmitir cada arquivo (—i de interactive), e finalmente a opção —n serve para dizer ao ftp para ele não solicitar o utilizador e sua senha, pois esses serão informados pela instrução específica (user);
Changed:
<
<
  1. Quando eu usei o << fimftp, estava dizendo o seguinte para o intérprete:
    - Olhe aqui Shell, não se meta em nada a partir daqui até encontrar o label fimftp. Você não entenderia nada, já que são instruções específicas do comando ftp e você não entende nada de ftp.
    Se fosse só isso seria simples, mas pelo próprio exemplo dá para ver que existem duas variáveis ($Utilizador e $Senha), que o Shell vai resolver antes do redireccionamento. Mas a grande vantagem desse tipo de construção é que ela permite que comandos também sejam interpretados dentro do escopo do here document, o que também contraria o que acabei de dizer. Logo a seguir explico como esse negócio funciona. Agora ainda não dá, está faltando ferramenta.
>
>
  1. Quando eu usei o << fimftp, estava dizendo o seguinte para o intérprete:
    - Olhe aqui Shell, não se meta em nada a partir daqui até encontrar o label fimftp. Você não entenderia nada, já que são instruções específicas do comando ftp e você não entende nada de ftp.
    Se fosse só isso seria simples, mas pelo próprio exemplo dá para ver que existem duas variáveis ($Utilizador e $Senha), que a Shell vai resolver antes do redireccionamento. Mas a grande vantagem desse tipo de construção é que ela permite que comandos também sejam interpretados dentro do escopo do here document, o que também contraria o que acabei de dizer. Logo a seguir explico como esse negócio funciona. Agora ainda não dá, está faltando ferramenta.
 
  1. O comando user é do repertório de instruções do ftp e serve para passar o utilizador e a senha que haviam sido lidos em uma rotina anterior a esse fragmento de código e colocados respectivamente nas duas variáveis: $Utilizador e $Senha.
  2. O binary é outra instrução do ftp, que serve para indicar que a transferência de arquivoremoto será feita em modo binário, isto é, o conteúdo do arquivo não será interpretado para saber se está em ASCII, EBCDIC, ...
  3. O get arquivoremoto diz ao ftp para pegar esse arquivo em hostremoto e trazê-lo para o nosso host local. Se fosse para mandar o arquivo, usaríamos o comando put.
Line: 379 to 379
  Existem 8 utilizadores conectados
Changed:
<
<
Como eu disse antes, as aspas protegem tudo que esta dentro dos seus limites, da interpretação do Shell. Como para o Shell basta um espaço em branco como separador, o monte de espaços será trocado por um único após a retirada das aspas.
>
>
Como eu disse antes, as aspas protegem tudo que esta dentro dos seus limites, da interpretação da Shell. Como para a Shell basta um espaço em branco como separador, o monte de espaços será trocado por um único após a retirada das aspas.
 
Changed:
<
<
Antes de falar sobre o uso dos parênteses deixa eu mandar uma rapidinha sobre o uso de ponto-e-vírgula (;). Quando estiver no Shell, você deve sempre dar um comando em cada linha. Para agrupar comandos em uma mesma linha teremos que separá-los por ponto-e-vírgula. Então:
>
>
Antes de falar sobre o uso dos parênteses deixa eu mandar uma rapidinha sobre o uso de ponto-e-vírgula (;). Quando estiver na Shell, você deve sempre dar um comando em cada linha. Para agrupar comandos em uma mesma linha teremos que separá-los por ponto-e-vírgula. Então:
 
$ pwd ; cd /etc; pwd; cd -; pwd
Line: 406 to 406
      - Ih! Será que é tem coisa de mágico aí?
Changed:
<
<
    - Tá me estranhando, rapaz? Não é nada disso! O interessante do uso de parênteses é que ele invoca um novo Shell para executar os comandos que estão no seu interior. Desta forma, realmente fomos para o directório /etc, porém quando todos os comandos dentro dos parênteses foram executados, o novo Shell que estava no directório /etc morreu e voltamos ao Shell anterior cujo directório corrente era /home/meudir. Faça outros testes usando cd, e ls para você firmar o conceito.
>
>
    - Tá me estranhando, rapaz? Não é nada disso! O interessante do uso de parênteses é que ele invoca um nova Shell para executar os comandos que estão no seu interior. Desta forma, realmente fomos para o directório /etc, porém quando todos os comandos dentro dos parênteses foram executados, o nova Shell que estava no directório /etc morreu e voltamos aa Shell anterior cujo directório corrente era /home/meudir. Faça outros testes usando cd, e ls para você firmar o conceito.
  Agora que já conhecemos estes conceitos veja só este exemplo a seguir:
Line: 423 to 423
  > FIM
Changed:
<
<
Finalmente agora temos conhecimento para mostrar o que havíamos conversado sobre here document. Os comandos entre crases (`) serão priorizados e portanto o Shell os executará antes da instrução mail. Quando o suporte receber o e-mail, verá que os comandos date e ls foram executados imediatamente antes do comando mail, recebendo então uma fotografia do ambiente no momento em que a correspondência foi enviada.
>
>
Finalmente agora temos conhecimento para mostrar o que havíamos conversado sobre here document. Os comandos entre crases (`) serão priorizados e portanto a Shell os executará antes da instrução mail. Quando o suporte receber o e-mail, verá que os comandos date e ls foram executados imediatamente antes do comando mail, recebendo então uma fotografia do ambiente no momento em que a correspondência foi enviada.
 
Changed:
<
<
O prompt primário default do Shell, como vimos, é o cifrão ($), porém o Shell usa o conceito de prompt secundário, ou de continuação de comando, que é enviado para a tela quando há uma quebra de linha e a instrução não terminou. Esse prompt, é representado por um sinal de maior (>), que vemos precedendo a partir da 2ª linha do exemplo.
>
>
O prompt primário default da Shell, como vimos, é o cifrão ($), porém a Shell usa o conceito de prompt secundário, ou de continuação de comando, que é enviado para a tela quando há uma quebra de linha e a instrução não terminou. Esse prompt, é representado por um sinal de maior (>), que vemos precedendo a partir da 2ª linha do exemplo.
 
Changed:
<
<
Para finalizar e bagunçar tudo, devo dizer que existe uma construção mais moderna que vem sendo utilizada como forma de priorização de execução de comandos, tal qual as crases (`). São as construções do tipo $(cmd), onde cmd é um (ou vários) comando que será(ão) executado(s) com prioridade em seu contexto.
>
>
Para finalizar e baralhar tudo, devo dizer que existe uma construção mais moderna que vem sendo utilizada como forma de priorização de execução de comandos, tal qual as crases (`). São as construções do tipo $(cmd), onde cmd é um (ou vários) comando que será(ão) executado(s) com prioridade em seu contexto.
  Assim sendo, o uso de crases (`) ou construções do tipo $(cmd) servem para o mesmo fim, porém para quem trabalha com sistemas operacionais de diversos fornecedores (multiplataforma), aconselho o uso das crases, já que o $(cmd) não foi portado para todos os sabores de Shell. Aqui dentro do Botequim, usarei ambas as formas, indistintamente.
Line: 479 to 479
      - Pô, saiu tudo embolado!
Changed:
<
<
    - Pois é cara, como eu já te disse, se você deixar o Shell “ver” os espaços em branco, sempre que houver diversos espaços juntos, eles serão trocados por apenas um. Para que a listagem saia bonitinha, é necessário proteger a variável da interpretação do Shell, assim:
>
>
    - Pois é cara, como eu já te disse, se você deixar a Shell “ver” os espaços em branco, sempre que houver diversos espaços juntos, eles serão trocados por apenas um. Para que a listagem saia bonitinha, é necessário proteger a variável da interpretação da Shell, assim:
 
$ echo "$Arqs"
Line: 488 to 488
  -rw-r--r-- 1 jneves jneves 1866 Jan 22 2003 arql
Changed:
<
<
    - Olhe, amigo, vá treinando esses exemplos, porque, quando nos encontrarmos novamente, vou lhe explicar uma série de instruções típicas de programação Shell. Tchau! Ahh! Só mais uma coisinha que eu ia esquecendo de lhe dizer. Em Shell, o "jogo da velha" (#) é usado quando desejamos fazer um comentário.
>
>
    - Olhe, amigo, vá treinando esses exemplos, porque, quando nos encontrarmos novamente, vou lhe explicar uma série de instruções típicas de programaçãa Shell. Tchau! Ahh! Só mais uma coisinha que eu ia esquecendo de lhe dizer. Em Shell, o "jogo da velha" (#) é usado quando desejamos fazer um comentário.
 
$ exit # pede a conta ao garcon frown

Revision 203 Feb 2008 - MarcoSilva

Line: 1 to 1
 

Conversa de Tasca - Parte I

Changed:
<
<
* Em processo de adaptação *
>
>
* Em processo de adaptação * Regista-te e ajuda a adaptar *
 

Changed:
<
<

Diálogo entreouvido entre um Linuxer e em empurrador de mouse:

>
>

Diálogo entreouvido entre um Linuxer e em empurrador de rato:

      - Quem é o Bash?
Line: 15 to 15
      - Meu! Queres deixar-me maluco? Eu tinha uma dúvida e agora fico com duas!
Changed:
<
<
    - Não, maluco já tu és há muito tempo. Desde que te decidiste usar aquele sistema operativo em que tens de dar dez boots por dia e não tens domínio nenhum sobre o que esta a acontecer no teu computador. Mas deixa isso, vou te explicar o que é Shell e os componentes da sua família e ao final da explicação dirás: "Meu Deus do Shell! Porque eu não optei pelo Linux antes?".
>
>
    - Não, maluco já tu és há muito tempo. Desde que te decidiste usar aquele sistema operativo em que tens de dar dez boots por dia e não tens domínio nenhum sobre o que esta a acontecer no teu computador. Mas deixa isso, vou-te explicar o que é Shell e os componentes da sua família e ao final da explicação dirás: "Meu Deus do Shell! Porque eu não optei pelo Linux antes?".
 

O Ambiente Linux

Changed:
<
<
Para entenderes o que é e como funciona o Shell, primeiro vou te mostrar como funciona o ambiente em camadas do Linux. Dá uma olhada no gráfico abaixo:
>
>
Para entenderes o que é e como funciona o Shell, primeiro vou-te mostrar como funciona o ambiente em camadas do Linux. Dá uma vista de olhos no gráfico abaixo:
 
Visão do shell em relação do Kernel do Linux
Changed:
<
<
Neste gráfico dá para ver que a camada de hardware é a mais profunda e é formada pelos componentes físicos do seu computador. Envolvendo esta, vem a camada do kernel que é o cerne do Linux, seu núcleo, e é quem bota o hardware para funcionar, fazendo seu gerenciamento e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas aplicativas para que foram desenvolvidos. Fechando tudo isso vem o Shell que leva este nome porque em inglês, Shell significa concha, carapaça, isto é, fica entre o utilizador e o sistema operativo, de forma que tudo que interage com o sistema operativo, tem que passar pelo seu crivo.
>
>
Neste gráfico dá para ver que a camada de hardware é a mais profunda e é formada pelos componentes físicos do teu computador. Envolvendo esta, vem a camada do kernel que é o cerne do Linux, seu núcleo, e é quem bota o hardware para funcionar, fazendo a sua gestão e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas aplicativas para que foram desenvolvidos. Fechando tudo isso vem o Shell que leva este nome porque em inglês, Shell significa concha, carapaça, isto é, fica entre o utilizador e o sistema operativo, de forma que tudo que interage com o sistema operativo, tem que passar pelo seu crivo.
 

O Ambiente Shell

Changed:
<
<
Bom já que para chegar ao núcleo do Linux, no seu kernel que é o que interessa a todo aplicativo, é necessária a filtragem do Shell, vamos entender como ele funciona de forma a tirar o máximo proveito das inúmeras facilidades que ele nos oferece.
>
>
Bom já que para chegar ao núcleo do Linux, no seu kernel que é o que interessa a todo aplicativo, é necessária a filtragem do Shell, vamos entender como é que ele funciona de forma a tirar o máximo proveito das inúmeras facilidades que ele nos oferece.
 
Changed:
<
<
O Linux por definição é um sistema multiusuário - não podemos nunca esquecer disto – e para permitir o acesso de determinados usuários e barrar a entrada de outros, existe um arquivo chamado /etc/passwd que além fornecer dados para esta função de "leão-de-chácara" do Linux, também provê informações para o login daqueles que passaram por esta primeira barreira. O último campo de seus registros informa ao sistema qual Shell a pessoa vai receber ao se "logar" (ARGH!!!).
>
>
O Linux por definição é um sistema multi-utilizador - não podemos nunca esquecer disto – e para permitir o acesso de determinados utilizadores e barrar a entrada de outros, existe um arquivo chamado /etc/passwd que além fornecer dados para esta função de "leão-de-chácara" do Linux, também provê informações para o login daqueles que passaram por esta primeira barreira. O último campo de seus registos informa ao sistema qual Shell a pessoa vai receber ao se "logar" (ARGH!!!).
 
Pinguim com placa de dica
Changed:
<
<
Quando eu disse que o último campo do /etc/passwd informa ao sistema qual é o Shell que o utilizador vai receber ao se "logar", é para ser interpretado ao pé-da-letra, isto é, se neste campo do seu registro estiver prog, a pessoa ao acessar o sistema receberá a tela de execução do programa prog e ao terminar a sua execução ganhará imediatamente um logout. Imagine o quanto se pode incrementar a segurança com este simples artifício.
>
>
Quando eu disse que o último campo do /etc/passwd informa ao sistema qual é o Shell que o utilizador vai receber ao se "logar", é para ser interpretado ao pé-da-letra, isto é, se neste campo do teu registro estiver prog, a pessoa ao acessar o sistema receberá a tela de execução do programa prog e ao terminar a sua execução ganhará imediatamente um logout. Imagine o quanto se pode incrementar a segurança com este simples artifício.
 
Changed:
<
<
Lembra que eu te falei de Shell, família, irmão? Pois é, vamos começar a entender isto: o Shell, que se vale da imagem de uma concha envolvendo o sistema operativo propriamente dito, é o nome genérico para tratar os filhos desta idéia que, ao longo dos anos de existência do sistema operativo Unix foram aparecendo. Atualmente existem diversos sabores de Shell, dentre estes eu destaco o sh (Bourne Shell), o ksh (Korn Shell), bash (Bourne Again Shell) e o csh (C Shell).
>
>
Lembras-te que eu te falei do Shell, família, irmão? Pois é, vamos começar a entender isto: o Shell, que se vale da imagem de uma concha envolvendo o sistema operativo propriamente dito, é o nome genérico para tratar os filhos desta idéia que, ao longo dos anos de existência do sistema operativo Unix foram aparecendo. Actualmente existem diversos sabores de Shell, dentre estes eu destaco o sh (Bourne Shell), o ksh (Korn Shell), bash (Bourne Again Shell) e o csh (C Shell).
 

Uma Rapidinha nos Principais Sabores de Shell

Line: 45 to 45
 

Korn Shell (ksh)

Changed:
<
<
Desenvolvido por David Korn, também da Bell Labs, é um superset do sh, isto é, possui todas as facilidades do sh e a elas agregou muitas outras. A compatibilidade total com o sh vem trazendo muitos usuários e programadores de Shell para este ambiente.
>
>
Desenvolvido por David Korn, também da Bell Labs, é um superset do sh, isto é, possui todas as facilidades do sh e a elas agregou muitas outras. A compatibilidade total com o sh vem trazendo muitos utilizadores e programadores de Shell para este ambiente.
 

Boune Again Shell (bash)

Line: 102 to 102
 
Comando
Changed:
<
<
Quando uma linha é digitada no prompt do Linux, ela é dividida em pedaços separados por espaço em branco: o primeiro pedaço é o nome do programa que terá sua existência pesquisada; identifica em seguida, nesta ordem, opções/parâmetros, redirecionamentos e variáveis.
>
>
Quando uma linha é digitada no prompt do Linux, ela é dividida em pedaços separados por espaço em branco: o primeiro pedaço é o nome do programa que terá sua existência pesquisada; identifica em seguida, nesta ordem, opções/parâmetros, redireccionamentos e variáveis.
  Quando o programa identificado existe, o Shell verifica as permissões dos arquivos envolvidos (inclusive o próprio programa), dando um erro caso você não esteja credenciado a executar esta tarefa.
Changed:
<
<
Resolução de Redirecionamentos
>
>
Resolução de Redireccionamentos
 
Changed:
<
<
Após identificar os componentes da linha que você teclou, o Shell parte para a resolução de redirecionamentos.
>
>
Após identificar os componentes da linha que você teclou, o Shell parte para a resolução de redireccionamentos.
 O Shell tem incorporado ao seu elenco de vantagens o que chamamos de redireccionamento, que pode ser de entrada (stdin), de saída (stdout) ou dos erros (stderr), conforme vou te explicar a seguir.

Substituição de Variáveis
Line: 198 to 198
  O cat é uma instrução que lista o conteúdo do arquivo especificado para a Saída Padrão (stdout). Caso a entrada não seja definida, ele espera os dados da stdin. Ora como eu não especifiquei a entrada, ele está esperando-a pelo teclado (Entrada Padrão) e como também não citei a saída, o que eu teclar irá para a tela (Saída Padrão) fazendo desta forma, como eu havia proposto um programa gago. Experimente!
Changed:
<
<
Redirecionamento da Saída Padrão
>
>
Redireccionamento da Saída Padrão
  Para especificarmos a saída de um programa usamos o > (maior que) ou o >> (maior, maior) seguido do nome do arquivo para o qual se deseja mandar a saída.
Line: 223 to 223
 

Pinguim com placa de atenção
Changed:
<
<
Como já havia lhe dito, o Shell resolve a linha e depois manda o comando para a execução. Assim, se você redirecionar a saída de um arquivo para ele próprio, primeiramente o Shell "esvazia" este arquivo e depois manda o comando para execução, desta forma você acabou de perder o conteúdo do seu querido arquivo.
>
>
Como já havia lhe dito, o Shell resolve a linha e depois manda o comando para a execução. Assim, se você redirecionar a saída de um arquivo para ele próprio, primeiramente o Shell "esvazia" este arquivo e depois manda o comando para execução, desta forma você acabou de perder o conteúdo do teu querido arquivo.
 

Com isso dá para notar que o >> (maior maior) serve para inserir texto no final do arquivo.

Changed:
<
<
Redirecionamento da Saída de Erro Padrão
>
>
Redireccionamento da Saída de Erro Padrão
  Assim como o default do Shell é receber os dados do teclado e mandar as saídas para a tela, os erros também serão enviados para a tela se você não especificar para onde deverão ser enviados. Para redirecionar os erros use 2> SaidaDeErro. Note que entre o número 2 e o sinal de maior (>) não existe espaço em branco.
Line: 253 to 253
 
Pinguim com placa de dica Dica # 1
Changed:
<
<
O $$ contém o PID, isto é, o número do seu processo. Como o Linux é multiusuário, é bom anexar sempre o $$ ao nome dos dos arquivos que serão usados por várias pessoas para não haver problema de propriedade, isto é, caso você baptizasse o seu arquivo simplesmente como seraqueexiste, o primeiro que o usasse (criando-o então) seria o seu dono e todos os outros ganhariam um erro quando tentassem gravar algo nele.
>
>
O $$ contém o PID, isto é, o número do teu processo. Como o Linux é multi-utilizador, é bom anexar sempre o $$ ao nome dos dos arquivos que serão usados por várias pessoas para não haver problema de propriedade, isto é, caso você baptizasse o seu arquivo simplesmente como seraqueexiste, o primeiro que o usasse (criando-o então) seria o seu dono e todos os outros ganhariam um erro quando tentassem gravar algo nele.
 
Changed:
<
<
Para que você teste a Saída de Erro Padrão direto no prompt do seu Shell, vou dar mais um exemplo. Faça:
>
>
Para que você teste a Saída de Erro Padrão direto no prompt do teu Shell, vou dar mais um exemplo. Faça:
 
$ ls naoexiste
Line: 285 to 285
  a mensagem de erro oriunda do ls seria anexada ao final de arquivodeerros.
Changed:
<
<
Redirecionamento da Entrada Padrão
>
>
Redireccionamento da Entrada Padrão
  Para fazermos o redireccionamento da Entrada Padrão usamos o < (menor que).
Line: 309 to 309
 
    ftp -ivn hostremoto << fimftp
Changed:
<
<
user $Usuário $Senha
>
>
user $Utilizador $Senha
  binary get arquivoremoto fimftp
Line: 317 to 317
  Neste pedacinho de programa temos um monte de detalhes interessantes:
  1. As opções que usei para o ftp (-ivn) servem para ele ir listando tudo que está acontecendo (—v de verbose), para não perguntar se você tem certeza de que deseja transmitir cada arquivo (—i de interactive), e finalmente a opção —n serve para dizer ao ftp para ele não solicitar o utilizador e sua senha, pois esses serão informados pela instrução específica (user);
Changed:
<
<
  1. Quando eu usei o << fimftp, estava dizendo o seguinte para o intérprete:
    - Olhe aqui Shell, não se meta em nada a partir daqui até encontrar o label fimftp. Você não entenderia nada, já que são instruções específicas do comando ftp e você não entende nada de ftp.
    Se fosse só isso seria simples, mas pelo próprio exemplo dá para ver que existem duas variáveis ($Usuário e $Senha), que o Shell vai resolver antes do redireccionamento. Mas a grande vantagem desse tipo de construção é que ela permite que comandos também sejam interpretados dentro do escopo do here document, o que também contraria o que acabei de dizer. Logo a seguir explico como esse negócio funciona. Agora ainda não dá, está faltando ferramenta.
  2. O comando user é do repertório de instruções do ftp e serve para passar o utilizador e a senha que haviam sido lidos em uma rotina anterior a esse fragmento de código e colocados respectivamente nas duas variáveis: $Usuário e $Senha.
>
>
  1. Quando eu usei o << fimftp, estava dizendo o seguinte para o intérprete:
    - Olhe aqui Shell, não se meta em nada a partir daqui até encontrar o label fimftp. Você não entenderia nada, já que são instruções específicas do comando ftp e você não entende nada de ftp.
    Se fosse só isso seria simples, mas pelo próprio exemplo dá para ver que existem duas variáveis ($Utilizador e $Senha), que o Shell vai resolver antes do redireccionamento. Mas a grande vantagem desse tipo de construção é que ela permite que comandos também sejam interpretados dentro do escopo do here document, o que também contraria o que acabei de dizer. Logo a seguir explico como esse negócio funciona. Agora ainda não dá, está faltando ferramenta.
  2. O comando user é do repertório de instruções do ftp e serve para passar o utilizador e a senha que haviam sido lidos em uma rotina anterior a esse fragmento de código e colocados respectivamente nas duas variáveis: $Utilizador e $Senha.
 
  1. O binary é outra instrução do ftp, que serve para indicar que a transferência de arquivoremoto será feita em modo binário, isto é, o conteúdo do arquivo não será interpretado para saber se está em ASCII, EBCDIC, ...
  2. O get arquivoremoto diz ao ftp para pegar esse arquivo em hostremoto e trazê-lo para o nosso host local. Se fosse para mandar o arquivo, usaríamos o comando put.
Line: 328 to 328
      - Está bem, está bem! Eu sei que dei uma viajada e entrei pelos comandos do ftp, fugindo ao nosso assunto que é Shell, mas como é sempre bom aprender e é raro as pessoas estarem disponíveis para ensinar...
Changed:
<
<
Redirecionamento de Comandos
>
>
Redireccionamento de Comandos
 
Changed:
<
<
Os redirecionamentos que falamos até aqui sempre se referiam a arquivos, isto é mandavam para arquivo, recebiam de arquivo, simulavam arquivo local, ... O que veremos a partir de agora redireciona a saída de um comando para a entrada de outro. É utilíssimo e quebra os maiores galhos. Seu nome é pipe (que em inglês significa tubo, já que ele encana a saída de um comando para a entrada de outro) e sua representação é uma barra vertical (|).
>
>
Os redireccionamentos que falamos até aqui sempre se referiam a arquivos, isto é mandavam para arquivo, recebiam de arquivo, simulavam arquivo local, ... O que veremos a partir de agora redireciona a saída de um comando para a entrada de outro. É utilíssimo e quebra os maiores galhos. Seu nome é pipe (que em inglês significa tubo, já que ele encana a saída de um comando para a entrada de outro) e sua representação é uma barra vertical (|).
 
$ ls | wc -l
Line: 349 to 349
  Quando quer priorizar uma expressão você coloca-a entre parênteses não é? Pois é, por causa da aritmética é normal pensarmos deste jeito. Mas em Shell o que prioriza mesmo são as crases (`) e não os parênteses. Vou dar exemplos de uso das crases para você entender melhor.
Changed:
<
<
Eu quero saber quantos usuários estão "logados" no computador que eu administro. Eu posso fazer:
>
>
Eu quero saber quantos utilizadores estão "logados" no computador que eu administro. Eu posso fazer:
 
$ who | wc -l     8
Changed:
<
<
O comando who passa a lista de usuários conectados para o comando wc –l que conta quantas linhas recebeu e lista a resposta na tela. Pois bem, mas ao invés de ter um oito solto na tela, o que eu quero é que ele esteja no meio de uma frase.
>
>
O comando who passa a lista de utilizadores conectados para o comando wc –l que conta quantas linhas recebeu e lista a resposta na tela. Pois bem, mas ao invés de ter um oito solto na tela, o que eu quero é que ele esteja no meio de uma frase.
  Ora para mandar frases para a tela eu uso o comando echo, então vamos ver como é que fica:

Changed:
<
<
$ echo "Existem who | wc -l usuários conectados" Existem who | wc -l usuários conectados
>
>
$ echo "Existem who | wc -l utilizadores conectados" Existem who | wc -l utilizadores conectados
 

Hi! Olha só, não funcionou! É mesmo, não funcionou e não foi por causa das aspas que eu coloquei, mas sim por que eu teria que ter executado o who | wc -l antes do echo. Para resolver este problema, tenho que priorizar esta segunda parte do comando com o uso de crases, fazendo assim:

Changed:
<
<
$ echo "Existem `who | wc -l` usuários conectados" Existem 8 usuários conectados
>
>
$ echo "Existem `who | wc -l` utilizadores conectados" Existem 8 utilizadores conectados
 

Para eliminar esse monte de brancos antes do 8 que o wc -l produziu, basta tirar as aspas. Assim:

Changed:
<
<
$ echo Existem `who | wc -l` usuários conectados Existem 8 usuários conectados
>
>
$ echo Existem `who | wc -l` utilizadores conectados Existem 8 utilizadores conectados
 

Como eu disse antes, as aspas protegem tudo que esta dentro dos seus limites, da interpretação do Shell. Como para o Shell basta um espaço em branco como separador, o monte de espaços será trocado por um único após a retirada das aspas.

Line: 390 to 390
  /home/meudir
Changed:
<
<
Neste exemplo, listei o nome do directório corrente com o comando pwd, mudei para o directório /etc, novamente listei o nome do directório e finalmente voltei para o directório onde estava anteriormente (cd -), listando seu nome. Repare que coloquei o ponto-e-vírgula (;) de todas as formas possíveis para mostrar que não importa se existe espaços em branco antes ou após este carácter.
>
>
Neste exemplo, listei o nome do directório corrente com o comando pwd, mudei para o directório /etc, novamente listei o nome do directório e finalmente voltei para o directório onde estava anteriormente (cd -), listando teu nome. Repare que coloquei o ponto-e-vírgula (;) de todas as formas possíveis para mostrar que não importa se existe espaços em branco antes ou após este carácter.
  Finalmente vamos ver o caso dos parênteses. Veja só o caso a seguir, bem parecido com o exemplo anterior:
Line: 434 to 434
 Vejamos novamente o exemplo dado para as crases sob esta nova ótica:

Changed:
<
<
$ echo Existem $(who | wc -l) usuários conectados Existem 8 usuários conectados
>
>
$ echo Existem $(who | wc -l) utilizadores conectados Existem 8 utilizadores conectados
 

Veja só este caso:

Revision 103 Feb 2008 - MarcoSilva

Line: 1 to 1
Added:
>
>

Conversa de Tasca - Parte I

* Em processo de adaptação *

Diálogo entreouvido entre um Linuxer e em empurrador de mouse:

    - Quem é o Bash?

    - O Bash é o filho mais novo da família Shell.

    - Meu! Queres deixar-me maluco? Eu tinha uma dúvida e agora fico com duas!

    - Não, maluco já tu és há muito tempo. Desde que te decidiste usar aquele sistema operativo em que tens de dar dez boots por dia e não tens domínio nenhum sobre o que esta a acontecer no teu computador. Mas deixa isso, vou te explicar o que é Shell e os componentes da sua família e ao final da explicação dirás: "Meu Deus do Shell! Porque eu não optei pelo Linux antes?".

O Ambiente Linux

Para entenderes o que é e como funciona o Shell, primeiro vou te mostrar como funciona o ambiente em camadas do Linux. Dá uma olhada no gráfico abaixo:

Visão do shell em relação do Kernel do Linux

Neste gráfico dá para ver que a camada de hardware é a mais profunda e é formada pelos componentes físicos do seu computador. Envolvendo esta, vem a camada do kernel que é o cerne do Linux, seu núcleo, e é quem bota o hardware para funcionar, fazendo seu gerenciamento e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas aplicativas para que foram desenvolvidos. Fechando tudo isso vem o Shell que leva este nome porque em inglês, Shell significa concha, carapaça, isto é, fica entre o utilizador e o sistema operativo, de forma que tudo que interage com o sistema operativo, tem que passar pelo seu crivo.

O Ambiente Shell

Bom já que para chegar ao núcleo do Linux, no seu kernel que é o que interessa a todo aplicativo, é necessária a filtragem do Shell, vamos entender como ele funciona de forma a tirar o máximo proveito das inúmeras facilidades que ele nos oferece.

O Linux por definição é um sistema multiusuário - não podemos nunca esquecer disto – e para permitir o acesso de determinados usuários e barrar a entrada de outros, existe um arquivo chamado /etc/passwd que além fornecer dados para esta função de "leão-de-chácara" do Linux, também provê informações para o login daqueles que passaram por esta primeira barreira. O último campo de seus registros informa ao sistema qual Shell a pessoa vai receber ao se "logar" (ARGH!!!).

Pinguim com placa de dica Quando eu disse que o último campo do /etc/passwd informa ao sistema qual é o Shell que o utilizador vai receber ao se "logar", é para ser interpretado ao pé-da-letra, isto é, se neste campo do seu registro estiver prog, a pessoa ao acessar o sistema receberá a tela de execução do programa prog e ao terminar a sua execução ganhará imediatamente um logout. Imagine o quanto se pode incrementar a segurança com este simples artifício.

Lembra que eu te falei de Shell, família, irmão? Pois é, vamos começar a entender isto: o Shell, que se vale da imagem de uma concha envolvendo o sistema operativo propriamente dito, é o nome genérico para tratar os filhos desta idéia que, ao longo dos anos de existência do sistema operativo Unix foram aparecendo. Atualmente existem diversos sabores de Shell, dentre estes eu destaco o sh (Bourne Shell), o ksh (Korn Shell), bash (Bourne Again Shell) e o csh (C Shell).

Uma Rapidinha nos Principais Sabores de Shell

Bourne Shell (sh)

Desenvolvido por Stephen Bourne da Bell Labs (da AT&T onde também foi desenvolvido o Unix), este foi durante muitos anos o Shell default do sistema operativo Unix. É também chamado de Standard Shell por ter sido durante vários anos o único e até hoje é o mais utilizado até porque ele foi portado para todos os ambientes Unix e distros Linux.

Korn Shell (ksh)

Desenvolvido por David Korn, também da Bell Labs, é um superset do sh, isto é, possui todas as facilidades do sh e a elas agregou muitas outras. A compatibilidade total com o sh vem trazendo muitos usuários e programadores de Shell para este ambiente.

Boune Again Shell (bash)

Este é o Shell mais moderno e cujo número de adeptos mais cresce em todo o mundo, seja por ser o Shell default do Linux, seu sistema operativo hospedeiro, seja por sua grande diversidade de comandos, que incorpora inclusive diversos instruções características do C Shell.

C Shell (csh)

Desenvolvido por Bill Joy da Berkley University é o Shell mais utilizado em ambientes *BSD e Xenix. A estruturação de seus comandos é bem similar à da linguagem C. Seu grande pecado foi ignorar a compatibilidade com o sh, partindo por um caminho próprio.

Além destes Shells existem outros, mas irei falar contigo somente sobre os três primeiros, tratando-os genericamente por Shell e assinalando as especificidades de cada um que porventura hajam.

Explicando o funcionamento do Shell

O Shell é o primeiro programa que ganhas ao te "logares" no Linux. É ele que vai resolver um monte de coisas de forma a não onerar o kernel com tarefas repetitivas, aliviando-o para tratar assuntos mais nobres. Como cada utilizador possui o seu próprio Shell interpondo-se entre ele e o Linux, é o Shell quem interpreta os comandos que são teclados e examina as suas sintaxes, passando-os esmiuçados para execução.

    - Êpa! Esse negócio de interpreta comando não tem nada a haver com interpretador não, né?

    - Tem sim, na verdade o Shell é um interpretador (ou será intérprete) que traz consigo uma poderosa linguagem com comandos de alto nível, que permite construção de loops (laços), de tomadas de decisão e de armazenamento de valores em variáveis, como vou te mostrar.

Vou te explicar as principais tarefas que o Shell cumpre, na sua ordem de execução. Preste atenção nesta ordem porque ela é fundamental para o entendimento do resto do nosso bate papo.

Exame da Linha de Comandos

Neste exame o Shell identifica os caracteres especiais (reservados) que têm significado para interpretação da linha, logo após verifica se a linha passada é uma atribuição ou um comando.

Atribuição

Se o Shell encontra dois campos separados por um sinal de igual (=) sem espaços em branco entre eles, identifica esta seqüência como uma atribuição.

Exemplos

$ ls linux linux

Neste exemplo o Shell identificou o ls como um programa e o linux como um parâmetro passado para o programa ls.

$ valor=1000

Neste caso, por não haver espaços em branco (já dá para notar que o branco é um dos caracteres reservados) o Shell identificou uma atribuição e colocou 1000 na variável valor.

Pinguim com placa de dica Jamais Faça:

$ valor = 1000 bash: valor: not found

Neste caso, o Bash achou a palavra valor isolada por brancos e julgou que você estivesse mandando executar um programa chamado valor, para o qual estaria passando dois parâmetros: = e 1000.

Comando

Quando uma linha é digitada no prompt do Linux, ela é dividida em pedaços separados por espaço em branco: o primeiro pedaço é o nome do programa que terá sua existência pesquisada; identifica em seguida, nesta ordem, opções/parâmetros, redirecionamentos e variáveis.

Quando o programa identificado existe, o Shell verifica as permissões dos arquivos envolvidos (inclusive o próprio programa), dando um erro caso você não esteja credenciado a executar esta tarefa.

Resolução de Redirecionamentos

Após identificar os componentes da linha que você teclou, o Shell parte para a resolução de redirecionamentos. O Shell tem incorporado ao seu elenco de vantagens o que chamamos de redireccionamento, que pode ser de entrada (stdin), de saída (stdout) ou dos erros (stderr), conforme vou te explicar a seguir.

Substituição de Variáveis

Neste ponto, o Shell verifica se as eventuais variáveis (parâmetros começados por $), encontradas no escopo do comando, estão definidas e as substitui por seus valores atuais.

Substituição de Meta Caracteres

Se algum metacaractere (*, ? ou []) foi encontrado na linha de comando, neste ponto ele será substituído por seus possíveis valores. Supondo que o único arquivo no seu directório corrente começado pela letra n seja um directório chamado nomegrandeprachuchu, se você fizer:

$ cd n*

Como até aqui quem esta trabalhando a sua linha é o Shell e o comando (programa) cd ainda não foi executado, o Shell transforma o n* em nomegrandeprachuchu e o comando cd será executado com sucesso.

Passa Linha de Comando para o kernel

Completadas as tarefas anteriores, o Shell monta a linha de comandos, já com todas as substituições feitas, chama o kernel para executá-la em um novo Shell (Shell filho), ganhando um número de processo (PID ou Process IDentification) e permanece inativo, tirando uma soneca, durante a execução do programa. Uma vez encerrado este processo (juntamente com o Shell filho), recebe novamente o controle e, exibindo um prompt, mostra que está pronto para executar outros comandos.

Decifrando a Pedra da Roseta

Para tirar aquela sensação que você tem quando vê um script Shell, que mais parece uma sopa de letrinhas ou um hieróglifo vou lhe mostrar os principais caracteres especiais para que você saia por ai como o Jean-François Champollion decifrando a Pedra da Roseta (dê uma "googlada" para descobrir quem é este cara, acho que vale a pena).

Caracteres para remoção do significado

É isso mesmo, quando não desejamos que o Shell interprete um carácter especial, devemos "escondê-lo" dele. Isso pode ser feito de três formas distintas:

Apóstrofo ou plic (')

Quando o Shell vê uma cadeia de caracteres entre apóstrofos ('), ele tira os apóstrofos da cadeia e não interpreta seu conteúdo.

$ ls linux* linuxmagazine $ ls 'linux*' bash: linux* no such file or directory

No primeiro caso o Shell "expandiu" o asterisco e descobriu o arquivo linuxmagazine para listar. No segundo, os apóstrofos inibiram a interpretação do Shell e veio a resposta que não existe o arquivo linux*.

Contrabarra ou Barra Invertida (\)

Idêntico aos apóstrofos excepto que a barra invertida inibe a interpretação somente do carácter que a segue.

Suponha que você acidentalmente tenha criado um arquivo chamado * (asterisco) – que alguns sabores de Unix permitem - e deseja removê-lo. Se você fizesse:

$ rm *

Você estaria fazendo a maior encrenca, pois o rm removeria todos os arquivos do directório corrente. A melhor forma de fazer o pretendido é:

$ rm \*

Desta forma, o Shell não interpretaria o asterisco, e em consequência não faria a sua expansão.

Faça a seguinte experiência científica:

$ cd /etc $ echo '*' $ echo \* $ echo *

Viu a diferença? Então não precisa explicar mais.

Aspas (")

Exatamente igual ao apóstrofo excepto que, se a cadeia entre aspas contiver um cifrão ($), uma crase (`), ou uma barra invertida (\), estes caracteres serão interpretados pelo Shell.

Não precisa se estressar, eu não te dei exemplos do uso das aspas por que você ainda não conhece o cifrão ($) nem a crase (`). Daqui para frente veremos com muita constância o uso destes caracteres especiais, o mais importante é entender o significado de cada um.

Caracteres de redireccionamento

A maioria dos comandos tem uma entrada, uma saída e pode gerar erros. Esta entrada é chamada Entrada Padrão ou stdin e seu default é o teclado do terminal. Analogamente, a saída do comando é chamada Saída Padrão ou stdout e seu default é a tela do terminal. Para a tela também são enviadas por default as mensagens de erro oriundas do comando que neste caso é a chamada Saída de Erro Padrão ou stderr. Veremos agora como alterar este estado de coisas.

Vamos fazer um programa gago. Para isto faça:

$ cat

O cat é uma instrução que lista o conteúdo do arquivo especificado para a Saída Padrão (stdout). Caso a entrada não seja definida, ele espera os dados da stdin. Ora como eu não especifiquei a entrada, ele está esperando-a pelo teclado (Entrada Padrão) e como também não citei a saída, o que eu teclar irá para a tela (Saída Padrão) fazendo desta forma, como eu havia proposto um programa gago. Experimente!

Redirecionamento da Saída Padrão

Para especificarmos a saída de um programa usamos o > (maior que) ou o >> (maior, maior) seguido do nome do arquivo para o qual se deseja mandar a saída.

Vamos transformar o programa gago em um editor de textos (que pretensão heim!). smile

$ cat > Arq

O cat continua sem ter a entrada especificada, portanto está aguardando que os dados sejam teclados, porém a sua saída está sendo desviada para o arquivo Arq. Assim sendo, tudo que esta sendo teclado esta indo para dentro de Arq, de forma que fizemos o editor de textos mais curto e ruim do planeta.

Se eu fizer novamente:

$ cat > Arq

Os dados contidos em Arq serão perdidos, já que antes do redireccionamento o Shell criará um Arq vazio. Para colocar mais informações no final do arquivo eu deveria ter feito:

$ cat >> Arq

Pinguim com placa de atenção Como já havia lhe dito, o Shell resolve a linha e depois manda o comando para a execução. Assim, se você redirecionar a saída de um arquivo para ele próprio, primeiramente o Shell "esvazia" este arquivo e depois manda o comando para execução, desta forma você acabou de perder o conteúdo do seu querido arquivo.

Com isso dá para notar que o >> (maior maior) serve para inserir texto no final do arquivo.

Redirecionamento da Saída de Erro Padrão

Assim como o default do Shell é receber os dados do teclado e mandar as saídas para a tela, os erros também serão enviados para a tela se você não especificar para onde deverão ser enviados. Para redirecionar os erros use 2> SaidaDeErro. Note que entre o número 2 e o sinal de maior (>) não existe espaço em branco.

Pinguim com placa de atenção Preste atenção! Não confunda >> com 2>. O primeiro anexa dados ao final de um arquivo, e o segundo redireciona a Saída de Erro Padrão (stderr) para um arquivo que está sendo designado. Isso é importante!

Suponha que durante a execução de um script você pode, ou não (dependendo do rumo tomado pela execução do programa), ter criado um arquivo chamado /tmp/seraqueexiste$$. Para não ficar sujeira no seu disco, ao final do script você colocaria uma linha:

$ rm /tmp/seraqueexiste$$

Caso o arquivo não existisse seria enviado para a tela uma mensagem de erro. Para que isso não aconteça deve-se fazer:

$ rm /tmp/seraqueexiste$$ 2> /dev/null

Sobre o exemplo que acabamos de ver tenho duas dicas a dar:

Pinguim com placa de dica Dica # 1

O $$ contém o PID, isto é, o número do seu processo. Como o Linux é multiusuário, é bom anexar sempre o $$ ao nome dos dos arquivos que serão usados por várias pessoas para não haver problema de propriedade, isto é, caso você baptizasse o seu arquivo simplesmente como seraqueexiste, o primeiro que o usasse (criando-o então) seria o seu dono e todos os outros ganhariam um erro quando tentassem gravar algo nele.

Para que você teste a Saída de Erro Padrão direto no prompt do seu Shell, vou dar mais um exemplo. Faça:

$ ls naoexiste bash: naoexiste no such file or directory $ ls naoexiste 2> arquivodeerros $ $ cat arquivodeerros bash: naoexiste no such file or directory

Neste exemplo, vimos que quando fizemos um ls em naoexiste, ganhamos uma mensagem de erro. Após, redirecionarmos a Saída de Erro Padrão para arquivodeerros e executarmos o mesmo comando, recebemos somente o prompt na tela. Quando listamos o conteúdo do arquivo para o qual foi redirecionada a Saída de Erro Padrão, vimos que a mensagem de erro tinha sido armazenada nele. Faça este teste ai.

Pinguim com placa de dica Dica # 2

    - Quem é esse tal de /dev/null?

    - Em Unix existe um arquivo fantasma. Chama-se /dev/null. Tudo que é mandado para este arquivo some. Assemelha-se a um Buraco Negro. No caso do exemplo, como não me interessava guardar a possível mensagem de erro oriunda do comando rm, redireccionei-a para este arquivo.

É interessante notar que estes caracteres de redireccionamento são acumulativos, isto é, se no exemplo anterior fizéssemos:

$ ls naoexiste 2>> arquivodeerros

a mensagem de erro oriunda do ls seria anexada ao final de arquivodeerros.

Redirecionamento da Entrada Padrão

Para fazermos o redireccionamento da Entrada Padrão usamos o < (menor que).

    - E prá que serve isso? - você vai me perguntar.

    - Deixa eu te dar um exemplo que você vai entender rapidinho.

Suponha que você queira mandar um mail para o seu chefe. Para o chefe nós caprichamos, né? então ao invés de sair redigindo o mail direto no prompt da tela de forma a tornar impossível a correcção de uma frase anterior onde, sem querer, escreveu um "nós vai", você edita um arquivo com o conteúdo da mensagem e após umas quinze verificações sem constatar nenhum erro, decide enviá-lo e para tal faz:

$ mail chefe < arquivocommailparaochefe

O teu chefe então receberá o conteúdo do arquivocommailparaochefe.

Here Document

Um outro tipo de redireccionamento muito louco que o Shell te permite é o chamado here document. Ele é representado por << (menor menor) e serve para indicar ao Shell que o escopo de um comando começa na linha seguinte e termina quando encontra uma linha cujo conteúdo seja unicamente o label que segue o sinal <<.

Veja o fragmento de script a seguir, com uma rotina de ftp:

    ftp -ivn hostremoto << fimftp
        user $Usuário $Senha
        binary
        get arquivoremoto
    fimftp

Neste pedacinho de programa temos um monte de detalhes interessantes:

  1. As opções que usei para o ftp (-ivn) servem para ele ir listando tudo que está acontecendo (—v de verbose), para não perguntar se você tem certeza de que deseja transmitir cada arquivo (—i de interactive), e finalmente a opção —n serve para dizer ao ftp para ele não solicitar o utilizador e sua senha, pois esses serão informados pela instrução específica (user);
  2. Quando eu usei o << fimftp, estava dizendo o seguinte para o intérprete:
    - Olhe aqui Shell, não se meta em nada a partir daqui até encontrar o label fimftp. Você não entenderia nada, já que são instruções específicas do comando ftp e você não entende nada de ftp.
    Se fosse só isso seria simples, mas pelo próprio exemplo dá para ver que existem duas variáveis ($Usuário e $Senha), que o Shell vai resolver antes do redireccionamento. Mas a grande vantagem desse tipo de construção é que ela permite que comandos também sejam interpretados dentro do escopo do here document, o que também contraria o que acabei de dizer. Logo a seguir explico como esse negócio funciona. Agora ainda não dá, está faltando ferramenta.
  3. O comando user é do repertório de instruções do ftp e serve para passar o utilizador e a senha que haviam sido lidos em uma rotina anterior a esse fragmento de código e colocados respectivamente nas duas variáveis: $Usuário e $Senha.
  4. O binary é outra instrução do ftp, que serve para indicar que a transferência de arquivoremoto será feita em modo binário, isto é, o conteúdo do arquivo não será interpretado para saber se está em ASCII, EBCDIC, ...
  5. O get arquivoremoto diz ao ftp para pegar esse arquivo em hostremoto e trazê-lo para o nosso host local. Se fosse para mandar o arquivo, usaríamos o comando put.

Pinguim com placa de atenção Um erro muito freqüente no uso de labels (como o fimftp do exemplo anterior) é causado pela presença de espaços em branco antes ou após o mesmo. Fique muito atento quanto a isso, por que este tipo de erro costuma dar uma boa surra no programador, até que seja detectado. Lembre-se: um label que se preze tem que ter uma linha inteira só para ele.

    - Está bem, está bem! Eu sei que dei uma viajada e entrei pelos comandos do ftp, fugindo ao nosso assunto que é Shell, mas como é sempre bom aprender e é raro as pessoas estarem disponíveis para ensinar...

Redirecionamento de Comandos

Os redirecionamentos que falamos até aqui sempre se referiam a arquivos, isto é mandavam para arquivo, recebiam de arquivo, simulavam arquivo local, ... O que veremos a partir de agora redireciona a saída de um comando para a entrada de outro. É utilíssimo e quebra os maiores galhos. Seu nome é pipe (que em inglês significa tubo, já que ele encana a saída de um comando para a entrada de outro) e sua representação é uma barra vertical (|).

$ ls | wc -l     21

O comando ls passou a lista de arquivos para o comando wc, que quando está com a opção –l conta a quantidade de linha que recebeu. Desta forma, podemos afirmar categoricamente que no meu directório existiam 21 arquivos.

$ cat /etc/passwd |sort | lp

Esta linha de comandos manda a listagem do arquivo /etc/passwd para a entrada do comando sort. Este a classifica e manda-a para o lp que é o gerenciador do spool de impressão.

Caracteres de Ambiente

Quando quer priorizar uma expressão você coloca-a entre parênteses não é? Pois é, por causa da aritmética é normal pensarmos deste jeito. Mas em Shell o que prioriza mesmo são as crases (`) e não os parênteses. Vou dar exemplos de uso das crases para você entender melhor.

Eu quero saber quantos usuários estão "logados" no computador que eu administro. Eu posso fazer:

$ who | wc -l     8

O comando who passa a lista de usuários conectados para o comando wc –l que conta quantas linhas recebeu e lista a resposta na tela. Pois bem, mas ao invés de ter um oito solto na tela, o que eu quero é que ele esteja no meio de uma frase.

Ora para mandar frases para a tela eu uso o comando echo, então vamos ver como é que fica:

$ echo "Existem who | wc -l usuários conectados" Existem who | wc -l usuários conectados

Hi! Olha só, não funcionou! É mesmo, não funcionou e não foi por causa das aspas que eu coloquei, mas sim por que eu teria que ter executado o who | wc -l antes do echo. Para resolver este problema, tenho que priorizar esta segunda parte do comando com o uso de crases, fazendo assim:

$ echo "Existem `who | wc -l` usuários conectados" Existem 8 usuários conectados

Para eliminar esse monte de brancos antes do 8 que o wc -l produziu, basta tirar as aspas. Assim:

$ echo Existem `who | wc -l` usuários conectados Existem 8 usuários conectados

Como eu disse antes, as aspas protegem tudo que esta dentro dos seus limites, da interpretação do Shell. Como para o Shell basta um espaço em branco como separador, o monte de espaços será trocado por um único após a retirada das aspas.

Antes de falar sobre o uso dos parênteses deixa eu mandar uma rapidinha sobre o uso de ponto-e-vírgula (;). Quando estiver no Shell, você deve sempre dar um comando em cada linha. Para agrupar comandos em uma mesma linha teremos que separá-los por ponto-e-vírgula. Então:

$ pwd ; cd /etc; pwd; cd -; pwd /home/meudir /etc/ /home/meudir

Neste exemplo, listei o nome do directório corrente com o comando pwd, mudei para o directório /etc, novamente listei o nome do directório e finalmente voltei para o directório onde estava anteriormente (cd -), listando seu nome. Repare que coloquei o ponto-e-vírgula (;) de todas as formas possíveis para mostrar que não importa se existe espaços em branco antes ou após este carácter.

Finalmente vamos ver o caso dos parênteses. Veja só o caso a seguir, bem parecido com o exemplo anterior:

$ (pwd ; cd /etc ; pwd;) /home/meudir /etc/ $ pwd /home/meudir

    - Quequeiiisso minha gente? Eu estava no /home/meudir, mudei para o /etc, constatei que estava neste directório com o pwd seguinte e quando o agrupamento de comandos terminou, eu vi que continuava no /home/meudir, como se eu nunca houvesse saído de lá!

    - Ih! Será que é tem coisa de mágico aí?

    - Tá me estranhando, rapaz? Não é nada disso! O interessante do uso de parênteses é que ele invoca um novo Shell para executar os comandos que estão no seu interior. Desta forma, realmente fomos para o directório /etc, porém quando todos os comandos dentro dos parênteses foram executados, o novo Shell que estava no directório /etc morreu e voltamos ao Shell anterior cujo directório corrente era /home/meudir. Faça outros testes usando cd, e ls para você firmar o conceito.

Agora que já conhecemos estes conceitos veja só este exemplo a seguir:

$ mail suporte << FIM > Ola suporte, hoje as ‘date "+%H:%M"‘ > ocorreu novamente aquele problema > que eu havia reportado por > telefone. Conforme seu pedido > ai vai uma listagem dos arquivos > do diretorio: > ‘ls —l‘ > Abracos a todos. > FIM

Finalmente agora temos conhecimento para mostrar o que havíamos conversado sobre here document. Os comandos entre crases (`) serão priorizados e portanto o Shell os executará antes da instrução mail. Quando o suporte receber o e-mail, verá que os comandos date e ls foram executados imediatamente antes do comando mail, recebendo então uma fotografia do ambiente no momento em que a correspondência foi enviada.

O prompt primário default do Shell, como vimos, é o cifrão ($), porém o Shell usa o conceito de prompt secundário, ou de continuação de comando, que é enviado para a tela quando há uma quebra de linha e a instrução não terminou. Esse prompt, é representado por um sinal de maior (>), que vemos precedendo a partir da 2ª linha do exemplo.

Para finalizar e bagunçar tudo, devo dizer que existe uma construção mais moderna que vem sendo utilizada como forma de priorização de execução de comandos, tal qual as crases (`). São as construções do tipo $(cmd), onde cmd é um (ou vários) comando que será(ão) executado(s) com prioridade em seu contexto.

Assim sendo, o uso de crases (`) ou construções do tipo $(cmd) servem para o mesmo fim, porém para quem trabalha com sistemas operacionais de diversos fornecedores (multiplataforma), aconselho o uso das crases, já que o $(cmd) não foi portado para todos os sabores de Shell. Aqui dentro do Botequim, usarei ambas as formas, indistintamente.

Vejamos novamente o exemplo dado para as crases sob esta nova ótica:

$ echo Existem $(who | wc -l) usuários conectados Existem 8 usuários conectados

Veja só este caso:

$ Arqs=ls $ echo $Arqs ls

Neste exemplo eu fiz uma atribuição (=) e executei uma instrução. O que eu queria era que a variável $Arqs, recebesse a saída do comando ls. Como as instruções de um script são interpretadas de cima para baixo e da esquerda para a direita, a atribuição foi feita antes da execução do ls. Para fazer o que desejamos é necessário que eu priorize a execução deste comando em detrimento da atribuição e isto pode ser feito de qualquer uma das maneiras a seguir:

$ Arqs=`ls`

ou:

$ Arqs=$(ls)

Para encerrar este assunto vamos ver só mais um exemplo. Digamos que eu queira colocar dentro da variável $Arqs a listagem longa (ls -l) de todos os arquivos começados por arq e seguidos de um único carácter (?). Eu deveria fazer:

$ Arqs=$(ls -l arq?)

ou:

$ Arqs=`ls -l arq?`

Mas veja:

$ echo $Arqs -rw-r--r-- 1 jneves jneves 19 May 24 19:41 arq1 -rw-r--r-- 1 jneves jneves 23 May 24 19:43 arq2 -rw-r--r-- 1 jneves jneves 1866 Jan 22 2003 arql

    - Pô, saiu tudo embolado!

    - Pois é cara, como eu já te disse, se você deixar o Shell “ver” os espaços em branco, sempre que houver diversos espaços juntos, eles serão trocados por apenas um. Para que a listagem saia bonitinha, é necessário proteger a variável da interpretação do Shell, assim:

$ echo "$Arqs" -rw-r--r-- 1 jneves jneves 19 May 24 19:41 arq1 -rw-r--r-- 1 jneves jneves 23 May 24 19:43 arq2 -rw-r--r-- 1 jneves jneves 1866 Jan 22 2003 arql

    - Olhe, amigo, vá treinando esses exemplos, porque, quando nos encontrarmos novamente, vou lhe explicar uma série de instruções típicas de programação Shell. Tchau! Ahh! Só mais uma coisinha que eu ia esquecendo de lhe dizer. Em Shell, o "jogo da velha" (#) é usado quando desejamos fazer um comentário.

$ exit # pede a conta ao garcon frown

Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para julio.neves@gmail.com. Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para julio.neves@uniriotec.br para informar-se.

Valeu!

 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki-SL? Send feedback