



Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Você não agüenta mais aquele seu amigo usuário de Linux enchendo o seu saco com aquela história de que o sistema é fantástico e o Shell é uma ferramenta maravilhosa? A partir desta edição vai ficar mais fácil entender o porquê deste entusiasmo... POR JULIO CEZAR NEVES
Tipologia: Notas de estudo
1 / 5
Esta página não é visível na pré-visualização
Não perca as partes importantes!




Para você entender o que é e como fun- ciona o Shell, primeiro vou te mostrar como funciona o ambiente em camadas do Linux. Dê uma olhada no gráfico mostrado na Figura 1. Neste gráfico podemos ver que a ca- mada de hardware é a mais profunda e é formada pelos componentes físicos do seu computador. Em torno dela, vem a camada do kernel que é o cerne do Linux, seu núcleo, e é quem põe o hard- ware para funcionar, fazendo seu geren- ciamento e controle. Os programas e comandos que envolvem o kernel, dele se utilizam para realizar as tarefas para que foram desenvolvidos. Fechando tudo isso vem o Shell, que leva este nome
porque, em inglês, Shell significa con- cha, carapaça, isto é, fica entre o u- suário e o sistema operacional, de forma que tudo que interage com o sistema operacional, tem que passar pelo seu crivo.
Bom já que para chegar ao núcleo do Linux, no seu ker- nel que é o que interessa a todo aplicativo, é necessária a filtragem do Shell, vamos enten- der 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 nos esquecer disto – e para permitir o acesso de determinados usuários e barrar a en- trada de outros, existe um arquivo cha- mado /etc/passwd , que além de fornecer dados para esta função de “leão-de-chá- cara” do Linux, também provê informa- ções para o início de uma sessão (ou “login”, para os íntimos) daqueles que passaram por esta primeira barreira. O último campo de seus registros informa ao sistema qual é o Shell que a pessoa vai receber ao iniciar sua sessão. Lembra que eu te falei de Shell, fa- mília, irmão? Pois é, vamos começar a entender isto: o Shell é a conceituação de concha envolvendo o sistema opera- cional propriamente dito, é o nome genérico para tratar os filhos desta idéia que, ao longo dos muitos anos de exis-
iálogo entreouvido em uma mesa de um botequim, entre um usuário de Linux e um empur- rador de mouse:
Curso de Shell Script
Bourne Shell (sh): Desenvolvido por Stephen Bourne do Bell Labs (da AT&T, onde também foi desenvolvido o Unix), foi durante muitos anos o Shell padrão do sistema operacional Unix. É também chamado de Standard Shell por ter sido durante vários anos o único, e é até hoje o mais utilizado. Foi portado para praticamente todos os ambientes Unix e dis- tribuições Linux. Korn Shell (ksh): Desenvolvido por David Korn, também do Bell Labs, é um supercon- junto do sh, isto é, possui todas as facilidades
do sh e a elas agregou muitas outras. A com- patibilidade total com o sh vem trazendo muitos usuários e programadores de Shell para este ambiente. Boune Again Shell (bash): Desenvolvido ini- cialmente por Brian Fox e Chet Ramey, este é o Shell do projeto GNU. O número de seus adeptos é o que mais cresce em todo o mundo, seja por que ele é o Shell padrão do Linux, seja por sua grande diversidade de comandos, que incorpora inclusive diversos comandos característicos do C Shell.
C Shell (csh): Desenvolvido por Bill Joy, da Universidade de Berkley, é o Shell mais uti- lizado em ambientes BSD. Foi ele quem intro- duziu o histórico de comandos. A estruturação de seus comandos é bem simi- lar à 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 somente sobre os três primeiros, tratan- do-os genericamente por Shell e assinalando as especificidades de cada um.
tência do sistema operacional Unix, foram aparecendo. Atualmente existem diversos sabores de Shell (veja Quadro 1 na página anterior).
O Shell é o primeiro programa que você ganha ao iniciar sua sessão (se quiser- mos assassinar a língua portuguesa podemos também dizer “ao se logar”) no Linux. É ele quem vai resolver um monte de coisas de forma a não onerar o kernel com tarefas repetitivas, poupando-o para tratar assuntos mais nobres. Como cada usuário possui o seu próprio Shell inter- pondo-se entre ele e o Linux, é o Shell quem interpreta os comandos digitados e examina as suas sintaxes, passando-os esmiuçados para execução.
Neste exame o Shell identifica os carac- teres especiais (reservados) que têm sig- nificado para a interpretação da linha e logo em seguida verifica se a linha pas- sada é um comando ou uma atribuição de valores, que são os ítens que vou descrever a seguir.
Quando um comando é digi- tado no “prompt” (ou linha de comando) do Linux, ele é divi- dido em partes, separadas por espaços em branco: a primeira parte é o nome do programa, cuja existência será verificada; em seguida, nesta ordem, vêm as opções/parâmetros, redire- cionamentos e variáveis. Quando o programa identifi- cado existe, o Shell verifica as permissões dos arquivos en-
volvidos (inclusive o próprio programa), e retorna um erro caso o usuário que chamou o programa não esteja autor- izado a executar esta tarefa.
$ ls linux linux
Neste exemplo o Shell identificou o ls co- mo um programa e o linux como um pa- râmetro passado para o programa ls.
Se o Shell encontra dois campos separa- dos por um sinal de igual (=) sem espa- ços em branco entre eles, ele identifica esta seqüência como uma atribuição.
$ valor=
Neste caso, por não haver espaços em branco (que é um dos caracteres reserva- dos), o Shell identificou uma atribuição e colocou 1000 na variável valor.
Após identificar os componentes da li- nha que você digitou, o Shell parte para a resolução de redirecionamentos. O Shell tem incorporado ao seu elenco de habilidades o que chamamos de
redirecionamento, que pode ser de entrada ( stdin ), de saída ( stdout ) ou dos erros ( stderr ), conforme vou explicar a seguir. Mas antes precisamos falar de...
Neste ponto, o Shell verifica se as even- tuais variáveis (parâmetros começados por $), encontradas no escopo do comando, estão definidas e as substitui por seus valores atuais.
Se algum meta-caracter (ou “coringa”, como * ,? ou [] ) for encontrado na linha de comando, ele será substituído por seus possíveis valores. Supondo que o único item no seu diretório corrente cujo nome começa com a letra n seja um diretório chamado nomegrandeprachuchu , se você fizer:
$ cd n*
como até aqui quem está manipulando a linha de comando ainda é o Shell e o programa cd ainda não foi executado, o Shell expande o n* para nomegrandepra- chuchu (a única possibilidade válida) e executa o comando cd com sucesso.
Completadas todas as tarefas anteriores, o Shell monta a linha de comando, já com todas as substituições feitas e chama o kernel para executá-la em um novo Shell (Shell filho), que ganha um número de processo (PID ou Process IDentification) e fica inativo, tirando uma soneca durante a execução do pro- grama. Uma vez encerrado este processo (e o Shell filho), o “Shell pai” recebe novamente o controle e exibe um “prompt”, mostrando que está pronto para executar outros comandos.
Figura 1: Ambiente em camadas de um sistema Linux
Shell
Programas e Comandos
Núcleo ou Kernel Hardware
Quando digo que o último campo do arqui- vo /etc/passwd informa ao sistema qual é o Shell que o usuário vai usar ao se “logar”, isto deve ser interpretado ao pé-da-letra. Se este campo do seu registro contém o termo prog , ao acessar o sistema o usuário executará o programa prog. Ao término da execução, a sessão do usuário se encerra automatica- mente. Imagine quanto se pode incremen- tar a segurança com este simples artifício.
Jamais faça: $ valor = 1000 bash: valor: not found Neste caso, o Bash achou a palavra valor iso- lada por espaços e julgou que você estivesse mandando executar um programa chama- do valor , para o qual estaria passando dois parâmetros: = e 1000.
Caso o arquivo não existisse seria envi- ado para a tela uma mensagem de erro. Para que isso não aconteça faça:
rm /tmp/seraqueexiste$$ 2> U /dev/null
Para que você teste a Saída de Erro Pa- drão direto no prompt do seu Shell, vou dar mais um exemplo. Faça:
$ ls naoexiste bash: naoexiste no such file U or directory $ ls naoexiste 2> arquivodeerros $ $ cat arquivodeerros bash: naoexiste no such file U or directory
Neste exemplo, vimos que quando fize- mos um ls em naoexiste , ganhamos uma mensagem de erro. Após redirecionar a Saída de Erro Padrão para arquivodeerros e executar o mesmo comando, recebe- mos somente o “prompt” na tela. Quan- do 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. É interessante notar que estes carac- teres de redirecionamento são cumula- tivos, isto é, se no exemplo anterior fizéssemos o seguinte:
$ ls naoexiste 2>> U arquivodeerros
a mensagem de erro oriunda do ls seria anexada ao final de arquivodeerros.
Para fazermos o redirecionamento da En- trada Padrão usamos o < (menor que). “E pra que serve isso?”, você vai me per- guntar. Deixa eu 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”, de forma a tornar impossível a correção de uma frase anterior onde, sem querer, você escreveu um “nós vai”, você edita um arquivo com o conteúdo da mensa- gem e após umas quinze verificações sem constatar nenhum erro, decide enviá-lo e para tal faz:
$ mail [email protected] < UU arquivocommailparaochefe
e o chefe receberá uma mensagem com o conteúdo do arquivocommailparaochefe. Outro tipo de redirecionamento “muito louco” que o Shell permite é o chamado “here document”. Ele é representado por << e serve para indicar ao Shell que o escopo de um comando 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 $Usuario $Senha binary get arquivoremoto fimftp
neste pedacinho de programa temos um monte de detalhes interessantes:
nada a partir deste ponto até encontrar o ‘label’ fimftp. Você não entenderia droga nenhuma, já que são instruções específicas do ftp ”. Se fosse só isso seria simples, mas pelo próprio exemplo dá para ver que existem duas variáveis ( $Usuario e $Senha ), que o Shell vai resolver antes do redirecionamento. Mas a grande vantagem deste tipo de construção é que ela permite que comandos tam- bém sejam interpretados dentro do escopo do “here document”, o que, aliás, contraria o que acabei de dizer. Logo a seguir te explico como esse negócio funciona. Agora ainda não dá, estão faltando ferramentas.
Os redirecionamentos de que falamos até agora sempre se referiam a arquivos, isto é, mandavam para arquivo, recebiam de arquivo, simulavam arquivo local, … O que veremos a partir de agora, redirecio- na a saída de um comando para a entra- da de outro. É utilíssimo e, apesar de não ser macaco gordo, sempre quebra os
Preste atenção! Não confunda >> com 2>. O primeiro anexa dados ao final de um arqui- vo, e o segundo redireciona a Saída de Erro Padrão ( stderr ) para um arquivo que está sendo designado. Isto é importante!
O $$ contém o PID,isto é,o número do seu processo. Como o Linux é multiusuário,é bom anexar sempre o $$ ao nome dos seus arquivos para não haver problema de propri- edade,isto é,caso você batizasse o seu ar- quivo simplesmente como seraqueexiste ,a primeira pessoa que o usasse (criando-o então) seria o seu dono e a segunda ganharia um erro quando tentasse gravar algo nele.
Um erro comum 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.
$ echo "Existem who | wc -l UU usuarios conectados" Existem who | wc -l usuarios U 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 proble- ma, tenho que priorizar a segunda parte do comando com o uso de crases:
$ echo "Existem who | wc -l UU usuarios conectados" Existem 8 usuarios U conectados
Para eliminar esse monte de brancos antes do 8 que o wc -l produziu, basta retirar as aspas. Assim:
$ echo Existem who | wc -l UU usuarios conectados Existem 8 usuarios conectados
As aspas protegem da interpretação do Shell tudo que está dentro dos seus lim- ites. 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. Outra coisa interessante é o uso do ponto-e-vírgula. Quando estiver no Shell, você deve sempre dar um comando em cada linha. Para agrupar comandos em uma mesma linha, temos que separá-los por ponto-e-vírgula. Então:
$ pwd ; cd /etc; pwd ;cd -;pwd /home/meudir /etc /home/meudir
Neste exemplo, listei o nome do diretório corrente com o comando pwd , mudei para o diretório /etc , novamente listei o nome do diretório e finalmente voltei pa- ra o diretó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 existem espaços em branco antes ou após este caracter. Finalmente, vamos ver o caso dos parênteses. No exemplo a seguir, colo- camos diversos comandos separados por ponto-e-vírgula entre parênteses:
$ (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 diretório com o pwd seguinte e quando o agrupamento de comandos terminou, eu vi que conti- nuava no /etc/meudir! Hi! Será que tem coisa do mágico Mandrake por aí? Nada disso. O interes- sante do uso de parênteses é que eles invocam um novo Shell para executar os comandos que estão em seu interior. Desta forma, fomos realmente para o diretório /etc , porém após a execução de todos os comandos, o novo Shell que estava no diretório /etc morreu e retor- namos ao Shell anterior que estava em /home/meudir. Que tal usar nossos novos conceitos?
$ mail [email protected] << FIM Ola suporte, hoje as date** UU **“+%hh:mm” ocorreu novamente UU aquele problema que eu havia UU reportado por telefone. De UU acordo com seu pedido segue a UU listagem do diretorio: ls -l Abracos a todos. FIM
Finalmente agora podemos demonstrar o que conversamos anteriormente sobre “here document”. Os comandos entre crases tem prioridade, portanto o Shell os executará antes do redirecionamento do “here document”. Quando o suporte receber a mensagem, verá que os comandos date e ls foram executados antes do comando mail, recebendo então um instantâneo do ambiente no momento de envio do email.
maiores galhos. Seu nome é “pipe” (que em inglês significa tubo, já que ele cana- liza a saída de um comando para a entrada de outro) e sua representação é a | (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 li- nhas que recebeu. Desta forma, pode- mos afirmar categoricamente que no meu diretório existiam 21 arquivos.
$ cat /etc/passwd | sort | lp
A linha de comandos acima manda a listagem do arquivo /etc/passwd para a entrada do comando sort. Este a classi- fica e envia para o lp que é o gerenciador da fila de impressão.
Quando queremos priorizar uma expres- são, nós a colocamos 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 exemp- los para você entender melhor. Eu quero saber quantos usuários estão “logados” no computador que eu admi- nistro. Eu posso fazer:
$ who | wc -l 8
O comando who passa a lista de usuários conectados ao sistema para o comando wc -l, que conta quantas linhas recebeu e mostra a resposta na tela. Muito bem, mas ao invés de ter um número oito solto na tela, o que eu quero mesmo é que ele esteja no meio de uma frase. Ora, para mandar frases para a tela eu só pre- ciso usar o comando echo ; então vamos ver como é que fica:
Julio Cezar Neves é Analista de Su- porte de Sistemas desde 1969 e tra- balha com Unix desde 1980, quando fez parte da equipe que desenvolveu o SOX, sistema operacional, similar ao Unix, da Cobra Computadores. É professor do curso de Mestrado em Software Livre das Faculdades Estácio SOBRE O AUTOR de Sá, no Rio de Janeiro.
Em Unix existe um arquivo fantasma. Chama-se /dev/null .Tudo que é enviado para este arquivo some. Assemelha-se a um Buraco Negro. No caso do exemplo, como não me interessava guardar a possível men- sagem de erro oriunda do comando rm , redi- recionei-a para este arquivo.