ASSOCIAÇÃO PARAIBANA DE ENSINO RENOVADO FACULDADE PARAIBANA DE PROCESSAMENTO DE DADOS CURSO SUPERIOR DE TECNOLOGIA EM PROCESSAMENTO DE DADOS Introdução ao UNIX Júlio César Ramalho leite ASPER Sistemas Operacionais 1 - Sistemas Operacionais Nos primeiros computadores, a programação era realizada em linguagem de máquina e todos os acessos aos recursos do sistema eram feitos através de rotinas escritas, pelo próprio usuário (programador), em linguagem de máquina. Desta forma, a utilização dos computadores era uma tarefa bastante complexa, já que o usuário precisava conhecer profundamente o hardware para desenvolver suas próprias rotinas de acesso aos recursos do sistema. Para facilitar a utilização dos computadores e padronizar as rotinas de acesso aos recursos do sistema, foram desenvolvidos os sistemas operacionais SO’s. Sistema Operacional é um programa que gerencia todos os recursos disponíveis no computador e oferece uma interface amigável, através da qual os usuários podem utilizar estes recursos sem ter conhecimento dos detalhes de hardware. Inicialmente, os próprios fabricantes desenvolviam o sistema operacional para as suas máquinas e o doava aos compradores. Com o passar do tempo, a indústria percebeu que a área de sistemas operacionais poderia originar um grande mercado e passou a não mais doar, e sim, vender este tipo de software. Com o surgimento dos sistemas operacionais, os computadores ficaram mais fáceis de serem utilizados por pessoais sem conhecimentos profundos de computação. São inúmeras as funções de um sistema operacional. Entretanto, podemos agrupá-las em duas classes que representam de uma forma geral o papel desempenhado por um sistema operacional em um computador: 1) Servir de interface entre o usuário e o computador. Desta forma, o usuário interage apenas com o sistema operacional, que se encarrega de acionar o hardware para atender às solicitações dos usuários. Como os SO’s possuem uma linguagem mais fácil do que a de máquina, a utilização dos computadores tornou-se bem mais simples. 2) Otimizar a utilização dos recursos disponíveis no computador. O sistema operacional deve utilizar técnicas e mecanismos para tirar o maior proveito dos recursos disponíveis no sistema. Um exemplo claro disto é permitir que o usuário realize mais de uma tarefa ao mesmo tempo (ex. acessar a Internet, imprimir um documento e formatar um disco) ou que o computador possa ser utilizado por vários usuários ao mesmo tempo. 2 – Histórico do UNIX No início dos anos 60, os sistemas operacionais da época utilizavam o conceito de processamento batch, isto é, várias tarefas de vários usuários eram agrupadas e só então submetidas para processamento seqüencial. O grande desafio nesta área, era desenvolver um sistema operacional que permitisse que vários usuários utilizassem o computador ao mesmo tempo de forma compartilhada, isto é, processamento de tempo compartilhado (time-sharing). Isto solucionaria os problema de baixo desempenho e baixa utilização de recursos, existentes no processamento batch. Introdução ao UNIX 2 ASPER Sistemas Operacionais As empresas MIT, Bell Labs e a General Eletrics se uniram para desenvolver o sistema operacional MULTICS (MULTiplexed Information and Computing Services). O MULTICS seria um sistema operacional multiusuário e de tempo compartilhado, que venceria os desafios daquela época. Entretanto, talvez pela sua própria grandiosidade, o projeto do MULTICS não deu certo, embora muitos resultados tenham sido conseguidos. Em 1969, Ken Thompson, pesquisador da Bell Labs, resolveu desenvolver um sistema operacional que seria uma simplificação do MULTICS, para uma máquina PDP-7. Thompson chamou este sistema operacional de UNICS (UNiplexed Information and Computing Services) que depois de UNIX. A primeira versão do UNIX foi escrita na linguagem assembler do PDP-7. Com os avanços tecnológicos, novos computadores foram sendo fabricados. Assim, Thompson e Dennis Ritchie resolveram reescrever o sistema operacional com o assembler dos computadores mais modernos (DPD-11/20, PDP-11/45. etc). Nesta fase, surgiu a seguinte questão: o UNIX vai ter que ser reescrito no assembler das máquina que forem surgindo? Isto seria um grande problema, já que o assembler era uma linguagem bastante difícil e o UNIX era um software de grande complexidade. A solução deste problema era desenvolver o UNIX usando uma linguagem de alto nível, mais fácil que o assembler. Como naquela época não existia nenhuma linguagem com tal poder, Dennis Ritchie criou a linguagem C. Em 1972, Thompson e Dennis Ritchie reescreveram o UNIX utilizando a linguagem C. Apenas os aspectos estritamente dependentes do hardware foram escritos em assembler. Desta forma, para o UNIX executar em uma nova máquina (arquitetura), seria necessário apenas escrever, em assembler desta máquina , os aspectos dependentes do hardware e desenvolver um compilador da linguagem C para a nova arquitetura. Para facilitar ainda mais a portabilidade do UNIX, mais tarde foi desenvolvido um compilador portável para a linguagem C (portable C compiler). Com isto, apenas uma pequena parte do compilador, o núcleo, precisaria ser desenvolvida para nova arquitetura, já que o restante poderia ser gerada a partir do núcleo. Apesar de ter criado e desenvolvido o sistema operacional UNIX, a Bell Labs não podia comercializá-lo na época devido às leis anti-monopólio que vigoravam nos EUA. Assim, em 1974, a Bell Labs resolveu liberar o UNIX, inclusive os códigos fontes, para as universidade licenciarem. A grande maioria das universidades utilizava computadores PDP-11, desta forma não havia dificuldades de usar o UNIX como sistema operacional. Com isto, o UNIX passou a ser a plataforma padrão no meio acadêmico. Isto contribuiu muito para o desenvolvimento do UNIX, uma vez que as universidades tinham posse do seu código fonte e passaram a realizar várias pesquisas científicas para o seu aperfeiçoamento. Em meados da década de 80, o UNIX deixou de ser um sistema operacional apenas do meio acadêmico e começou a ser utilizado em outras áreas. Várias empresas e universidades aperfeiçoaram o UNIX original e lançaram suas próprias versões do sistema operacional. Havia uma certa tendência do UNIX perder suas características fundamentais, já que cada versão era desenvolvida independentemente das outras. Para evitar que isto acontecesse, o IEEE (Institute of Electrical and Electronics Engineers) reuniu várias pessoas do meio acadêmico, da indústria e do governo e criou o comitê POSIX ( Portable Operating System UNIX) que desenvolveu o padrão IEEE 1003. Este padrão especifica todas as características que um sistema operacional deve possuir para pertencer ao padrão UNIX. Embora o UNIX tenha se tornado um produto comercial, ainda podemos encontrar algumas versões de domínio público, inclusive o código fonte. As mais conhecidas são: FreeBSD Introdução ao UNIX 3 ASPER Sistemas Operacionais desenvolvido pela universidade de Berkeley; e linux desenvolvido inicialmente por Linus Torvalds na década de 90. Atualmente, o termo UNIX é mais usado para designar a família de sistemas operacionais que seguem o padrão UNIX (POSIX), e não referenciar o UNIX criado inicialmente por Ken Thompson. No decorrer do tempo, surgiram vários sistemas operacionais UNIX, cada um com seu próprio nome suas próprias características. Alguns dos mais conhecidos são: • • • • • • • BSD: Universidade de Berkeley System V: AT&T LINUX: Domínio público SCO UNIX: Santa Cruz Operation AIX: IBM HP-UX: HP Solaris: Sun Microsystems 3 – Características do UNIX O sistema operacional UNIX, por ter predominado inicialmente no ambiente acadêmico, onde pesquisas na área de SO são realizadas constantemente, introduziu grande parte dos conceitos mais sofisticados presentes atualmente na maioria dos sistemas operacionais. Apresentamos, a seguir, algumas das principais características do UNIX. ⇒ Multiusuário: Permite que vários usuários acessem o sistema concorrentemente e compartilhem os diversos recursos. ⇒ Multitarefa: Permite que várias tarefas (processos) de vários usuários sejam executadas de forma concorrente. ⇒ Time-sharing: Compartilha o tempo do processador entre os diversos usuários conectados ao sistema, de maneira que cada usuário tenha a impressão de que o processador está dedicado exclusivamente a ele. ⇒ Portável: Pode ser facilmente transportado para várias arquiteturas. Esta característica está diretamente ligada ao fato do UNIX ser desenvolvido em uma linguagem de alto nível (linguagem C). ⇒ Memória Virtual: O UNIX utiliza área em disco como memória principal, para proporcionar a ilusão de uma memória RAM maior do que a real. Desta forma, mais processos podem ser alocados na memória principal e programas muito grandes podem ser executados. ⇒ Sistema de Arquivos Hierárquico: O espaço em disco é organizado em arquivos e diretórios. Adota-se uma estrutura de árvore de múltiplos níveis. ⇒ Sistema de Arquivos Montável: A área em disco é particionada em sistemas de arquivos (file systems). Cada file system pode ser montado (anexado) à estrutura hierárquica de Introdução ao UNIX 4 ASPER Sistemas Operacionais diretórios. Isto permite que certos file systems sejam disponibilizados apenas em momentos apropriados. 4 – Arquitetura do UNIX Os sistemas operacionais são softwares de natureza não seqüencial, isto é, não seguem uma lógica de execução do tipo início, meio e fim. Isto acontece porque os sistemas operacionais lidam com eventos assíncronos que podem ocorrer a qualquer instante, tais como: uma falta de página, uma solicitação de E/S, interrupções, etc. Esta característica torna mais difícil a tarefa de projetar um sistema operacional. A arquitetura de um sistema operacional é a forma como o seu código está organizado e como os seus diversos componentes estão inter-relacionados. Existem basicamente três arquiteturas de sistemas operacionais, são elas: monolítica, em camadas e cliente/servidor. O UNIX possui uma arquitetura em camadas, veja figura a seguir. Este tipo de arquitetura tem as vantagens: ♦ Separa as diversas funções do sistema operacional ♦ Facilita atualizações ♦ Oferece uma maior segurança para o sistema operacional ⇒ Kernel: é o núcleo do sistema operacional, sua principal função é gerenciar diretamente os recursos do sistema e oferecer serviços básicos para as os usuários do sistema e suas aplicações, como também a outros componentes do próprio sistema operacional. Algumas tarefas realizadas pelo kernel são: gerenciamento de processos, gerenciamento de memória, tratamento de interrupções, gerenciamento de entrada/saída. ⇒ SHELL: também conhecido como interpretador de comandos, o shell atua como interface entre o kernel e os usuários e suas aplicações. O shell deve interpretar os comandos solicitados pelos usuários e transformá-los em solicitações mais simples, de maneira tal que o kernel possa executá-las mais rapidamente. No UNIX, o administrador (root) especifica um shell para cada Introdução ao UNIX 5 ASPER Sistemas Operacionais usuário cadastrado no sistema. Os shells mais conhecidos são: Borne Shell (sh), C Shell (csh) e Korne Shell (ksh). ⇒ Comandos: constituem a porta de entrada do sistema operacional. Os usuários interagem com o sistema através da execução de comandos. Os utilitários, tais como: editores de texto e compiladores, também fazem parte desta camada. 5 – Arquivos no UNIX Para o UNIX, um arquivo é uma seqüência de bytes ligados logicamente. Os nomes dos arquivos podem ter até 256 caracteres, sempre devemos lembrar que o UNIX faz distinção entre letras maiúsculas e minúsculas, assim os arquivos prova_so.doc e Prova_so.doc são distintos para o UNIX. Existem basicamente três tipos de arquivos: ⇒ Ordinários: são arquivos que contêm dados na forma de textos, programas, figuras, vídeo, etc. ⇒ Diretórios: são arquivos que contêm referências para outros arquivos ordinários ou diretórios. Este tipo de arquivo é o responsável pela implementação da estrutura hierárquica do sistema de arquivos do UNIX. Veja que a hierarquia possui vários níveis, isto é, cada diretório pode possuir vários subdiretórios, e assim por diante. ⇒ Especiais: o conceito de arquivo é tão fundamental para o UNIX, que ele trata todos os dispositivos físicos do sistema como sendo arquivos. Para cada dispositivo existe um arquivo especial associado a ele. O UNIX classifica os arquivos especiais de acordo com os dispositivos a eles associados, desta forma, podemos ter os arquivos especiais do tipo bloco, que representam dispositivos de bloco, e os arquivos especiais do tipo caracter, que representam dispositivos de caracteres. Como vimos, o UNIX adota uma estrutura hierárquica para seu sistema de arquivos. A figura abaixo apresenta uma árvore de diretórios resumida de um sistema UNIX, os nomes dos diretórios podem mudar dependendo do fabricante. Diretório / /bin /sbin /etc /dev /tmp /lib /usr /u /home Descrição do conteúdo Diretório raiz (root) do sistema de arquivos arquivos executáveis freqüentemente usados (comandos) arquivos referentes à administração do sistema arquivos especiais para dispositivos de E/S arquivos temporários bibliotecas do UNIX (C, assembler...) diretório HOME dos usuários do sistema Introdução ao UNIX 6 ASPER Sistemas Operacionais No UNIX, um determinado arquivo ou diretório pode ser referenciado através do caminho (path) absoluto ou relativo. No caso da utilização da forma absoluta, devemos especificar todo o cominho, a partir da raiz (/) até o arquivo ou diretório que queremos referenciar. Já na forma relativa, podemos especificar o caminho a partir do diretório corrente. Para facilitar ainda mais, podemos usar as seguintes abreviações: . : para representar o diretório corrente; .. : para representar o diretório pai do diretório corrente. Veja a seguir alguns exemplos de como referenciar um arquivo ou diretório no UNIX, para isto tome como base a árvore de diretórios apresentada acima. Exemplo1: Para referenciar o diretório redes que está na área do usuário juliol (veja figura acima), podemos usar: Caminho absoluto: /usr/juliol/redes, esta forma, por ser absoluta, pode ser usada independente de qual seja o diretório corrente. Caminhos relativo: a forma relativa depende do diretório corrente, assim temos: Se o diretório corrente for o / podemos usar: usr/juliol/redes ou ./usr/juliol/redes Se o diretório corrente for o /bin podemos usar: ../usr/juliol/redes Se o diretório corrente for o /usr/joaob podemos usar: ../juliol/redes Exemplo2: Para referenciar o arquivo tcpip.cfg que está no diretório redes na área do usuário juliol (veja figura acima), podemos usar: Caminho absoluto: /usr/juliol/redes/tcpip.cfg, esta forma, por ser absoluta, pode ser usada independente de qual seja o diretório corrente. Caminhos relativo: a forma relativa depende do diretório corrente, assim temos: Se o diretório corrente for o / podemos usar: usr/juliol/redes/tcpip.cfg Se o diretório corrente for o /usr podemos usar: ./juliol/redes/tcpip.cfg Introdução ao UNIX 7 ASPER Sistemas Operacionais Se o diretório corrente for o /usr/juliol/SO podemos usar: ../redes/tcpip.cfg 6 – Comandos básicos do UNIX O UNIX possui um número muito grande de comandos, vamos apresentar apenas aqueles mais utilizados no dia a dia dos usuários de ambientes UNIX. man [comando] Manual on-line dos comandos do UNIX clear Limpa a tela de vídeo passwd [usuário] Altera a senha do usuário ls [-alR] [arquvos|diretórios] Lista arquivos e diretórios. Se nenhum arquivo ou diretório for especificado, o conteúdo do diretório corrente será apresentado. Opções: -a : mostra todos os arquivos, inclusive os ocultos (que começam com um ponto “.”) -l : Lista arquivos no formato longo, inclui tipo, permissões, posse e tamanho -R : Lista o conteúdo de todos os subdiretórios de forma recursiva Uso de curingas no UNIX * : Substitui qualquer conjunto de caracteres ? : Substitui apenas um caractere [] : Substitui uma lista de caracteres Exemplos: ( o $ é o sinal de prompt) $ls File.new file1 file5 fig file2 fin filea file3 fit file.new file4 fun $ls fi? fig fin fit $ls f?? fig fin fit $ls *.new File.new file.new fun $ls fi[gn] fig fin $ls file[1-4] file1 file2 Introdução ao UNIX file3 file4 8 ASPER Sistemas Operacionais $ls f?[!t] fig fin fun $ls /usr/julio asper dataprev $ls –a /usr/juliol . .profile .vtlrc .. .sh_history $ls –la /usr/juliol drwxr-xr-x 2 drwxr-xr-x 37 -rw-r--r-1 -rw------1 -rw-r--r-1 -rwxr-xr-x 1 -rwxr-xr-x 1 -rwxr-xr-x 1 diversos /* lista todos os arquivos e diretórios dataprev asper diversos juliol juliol juliol juliol juliol juliol juliol juliol admin admin admin admin admin users users users 512 1024 1025 1586 100 137 137 137 Aug 9 15:13 Sep 14 16:44 Dec 3 1998 Sep 20 09:58 Feb 3 1998 Jul 8 16:24 Jul 28 1998 Jul 28 1998 . .. .profile .sh_history .vtlrc asper dataprev diversos alias apelido=comando Cria um apelido para um determinado comando Exemplo: $alias cls=clear $cls /* este comando vai limpar a tela de vídeo $ls provas aulas exercicios trabalhos notas bibliografia $alias dir=ls /cria o apelido dir para o comando ls $dir provas aulas exercicios trabalhos notas bibliografia file arquivos Determina e exibe o tipo de arquivos Exemplos: $file fin fin: ASCII text $file dados dados: Directory $file notas notas: empty more arquivos Apresenta o conteúdo de um arquivo texto de forma paginada cat [arquivos] Concatena arquivos e apresenta o resultado na saída padrão. Se nenhum arquivo for especificado, a entrada padrão será gravada na saída padrão Exemplos: $cat agenda Joao Marcia Introdução ao UNIX 222-1122 221-1009 9 ASPER Sistemas Operacionais Maria $cat > notas >Joao >Marcia >Claudia >Ana >Crtl-C $cat notas Joao Marcia Claudia Ana 235-0011 9,0 8,0 8,7 9,2 9,0 8,0 8,7 9,2 pwd Exibe o diretório corrente cd [diretório] Muda o diretório corrente. Se não for especificado nenhum diretório, o diretório corrente passa a ser o diretório HOME do usuário. Exemplos: $pwd /home/root $cd /usr/bin $pwd /usr/bin $cd ../local $pwd /usr/local $cd $pwd /home/root mkdir diretórios Cria diretórios Exemplos: $mkdir pascal $mkdir /home/julio/java $mkdir programas dados cp [opções] origem destino Copia arquivos e diretótrios Opções: -b : Cria cópias de backups dos arquivos antes que os originais sejam sobrescritos -i : Exibe um prompt antes de sobrescrever arquivos de destino existentes -R : Copia diretórios recursivamente -f : Força a remoção dos de arquivos de destino existentes Exemplos: $ls programa aula1 aula2 aula3 lista1 lista2 lista3 prova1 prova2 prova3 Introdução ao UNIX 10 ASPER Sistemas Operacionais $cp ../turma982/aula1 . $ls programa aula1 aula1~ aula2 aula3 lista1 lista2 lista3 prova1 prova2 prova3 $cp -i ../turma982/aula1 . cp: overwrite ‘./aula1’ ? y $ mv origem destino Move e renomeia arquivos e diretórios Exemplos: $mv agenad agenda /* renomeia o arquivo $mv agenda /tmp /* move o arquivo agenda para o diretório /tmp rm [opções] [arquivos | diretórios] Exclui arquivos e diretórios Opções: -i : Pede confirmação da remoção ao usuário -f : Não pede confirmação antes da remoção -r, -R : Remove recursivamente o conteúdo de diretórios Exemplos: $rm aula1 $rm -i aula2 rm: remove ‘aula2’ ? y $ rmdir diretório Remove diretórios vazios OBS: Para remover diretórios não vazios, utilize o comando rm –r Exemplos: $ls turmas lixo $rmdir turmas rmdir: turmas: Directory not empty $rmdir lixo $ls turmas $rm –r turmas $ls $ wc [-clw] [arquivos] Conta o número de caracteres, linhas e palavras de documentos e exibe na tela Opções: -c : Exibe o número de caracteres dos arquivos -l : Exibe o número de linhas dos arquivos -w : Exibe o número de palavras dos arquivos Exemplos: $cat agenda Introdução ao UNIX 11 ASPER Sistemas Operacionais Joao 222-1122 Marcia 221-1009 Maria 235-0011 Ana 987-0087 Lis 224-2074 $wc –l agenda 5 $wc –w 10 head [-n] [arquivos] Apresenta as 10 primeiras linhas dos arquivos especificados. O usuário pode especificar quantas linhas ele deseja. Exemplos: (considere o arquivo agenda do exemplo anterior) $head -1 agenda Joao 222-1122 $head -2 agenda Joao 222-1122 Marcia 221-1009 tail [-n] [arquivos] Apresenta as 10 últimas linhas dos arquivos especificados. O usuário pode especificar quantas linhas ele deseja. Exemplos: $tail -1 agenda Lis 224-2074 $tail -2 agenda Ana 987-0087 Lis 224-2074 7 – Redirecionamento de entrada e saída Antes de começarmos a apresentar os comandos do UNIX, é necessário entendermos como funciona a entrada e saída dos comandos e como podemos alterá-las, ou seja, redirecioná-las. Cada comando ou programa executado no UNIX possui três arquivos associados a ele: Entrada padrão ( 0 ): geralmente é o teclado Saída padrão ( 1 ): geralmente é o vídeo Saída padrão de erro ( 2 ): geralmente é o vídeo. A forma mais comum de redirecionamento de E/S é através da utilização de pipe ( | ). O pipe serve para encadear comandos, de tal forma que a saída do primeiro é usada como a entrada do segundo, a saída do segundo é usada como entrada do terceiro, e assim por diante. Veja o exemplo a seguir com os comandos ls e more. ls: lista o conteúdo do diretório corrente more: exibe o conteúdo de um arquivo uma página por vez. Introdução ao UNIX 12 ASPER Sistemas Operacionais Comando ls | more Ação Lista o conteúdo do diretório corrente exibindo uma página por vez. Neste exemplo, estamos usando dois redirecionamentos, o primeiro é a saída padrão do comando ls, que deixou de ser o vídeo para ser a entrada do comando more; e o segundo é a entrada padrão do comando more, que deixou de ser o arquivo passado como parâmetro para ser a saída do comando ls. Para redirecionar a saída de um comando devemos usar os símbolos > ou >>. Veja os exemplos a seguir com o comando sort, que serve para ordenar o conteúdo do arquivo passado como parâmetro. Sintaxe: sort arquivo Comando sort medias_981 Ação Ordena o arquivo medias_981 e exibe o resultado no vídeo (saída padrão) Comando sort medias_981 > medias_981_ord Ação Ordena o arquivo medias_981 e coloca o resultado no arquivo medias_981_ord. Caso o arquivo medias_981_ord exista, ele seu conteúdo será perdido. Neste caso houve um redirecionamento da saída padrão, que deixou de ser o vídeo e passou a ser o arquivo medias_981_ord Comando sort medias_981 >> medias_geral Ação Ordena o arquivo medias_981 e anexa o resultado ao arquivo medias_geral. Caso o arquivo medias_geral não exista, ele será criado. Neste caso também houve um redirecionamento da saída padrão, que deixou de ser o vídeo e passou a ser o arquivo medias_geral. Para redirecionar a entrada de um comando devemos usar o símbolo < . Veja o exemplo a seguir com o comando mail, que serve para enviar uma mensagem eletrônica para os usuários passados como parâmetros. Sintaxe: mail usuarios Comando mail juliol Ação O sistema vai ler a entrada padrão, que neste caso é o teclado, até que seja digitada uma seqüência de finalização (Ctrl-C). E vai enviar uma mensagem para o usuário juliol, contendo as informações digitadas pelo usuário. Comando mail juliol < medias_981_ord Ação O sistema vai enviar o conteúdo do arquivo medias_981_ord como uma mensagem eletrônica para o usuário juliol. Veja que neste caso houve o redirecionamento da entrada padrão, que deixou de ser o teclado para ser o arquivo medias_981_ord. A marca de fim de arquivo serve como seqüência de finilização. Em algumas situações é necessário redirecionar a saída padrão de erros para que mensagens de erro não apareçam no vídeo, nestes casos, devemos usar: 2>. O exemplo a seguir ilustra o redirecionamento da saída padrão de erros do comando rm, que serve para remover arquivos do disco. Comando rm *.bkp Introdução ao UNIX 13 ASPER Sistemas Operacionais Ação O sistema removerá todos os arquivos terminados com .bkp. Caso não exista nenhum arquivo, será exibida no vídeo uma mensagem de erro. Comando rm *.bkp 2> /tmp/log_erro Ação O sistema removerá todos os arquivos terminados com .bkp. Caso não exista nenhum arquivo, uma mensagem de erro será gravada no arquivo /tmp/log_erro. Veja que a saída padrão de erros foi redirecionada, deixando de ser o vídeo para ser o arquivo /tmp/log_erro. O UNIX possui o arquivo /dev/null que funciona como um buraco negro, isto é, todas as informações gravadas nele são destruídas automaticamente. Desta forma, quando as saídas de um comando não nos interessam, podemos redirecioná-las para o arquivo /dev/null, para evitar a criação de arquivos temporários ou a sua exibição no vídeo. Veja o exemplo a seguir: $ls xyz ls: xyz: No such file or directory $ls xyz 2>/dev/null CUIDADO!!! Quando você digita um comando, antes que ele seja executado pelo kernel, o shell (interpretador de comandos) vai analizá-lo e resolver todos os redirecionamentos e as utilizações de curingas. Veja o exemplo a seguir: $cat agenda Joao 222-1122 Ana 221-1009 Maria 235-0011 $sort agenda Ana 221-1009 Joao 222-1122 Maria 235-0011 $sort agenda > agenda $cat agenda $ O comando sort agenda > agenda, que a princípio serviria para ordenar o conteúdo do arquivo agenda e gravar o conteúdo ordenado no próprio arquivo agenda, na realidade vai destruir as informações gravadas no arquivo agenda. Isto ocorre por que antes do kernel executar o comando de ordenação, o shell vai resolver o redirecionamento da saída, ou seja, vai tornar o arquivo agenda vazio. Assim, quando o kernel for executar a ordenação, o arquivo agenda estará vazio. 8 – Permissões de arquivos e diretórios O UNIX implementa boa parte de sua segurança através do controle de permissões de acesso a arquivos e diretórios. Para ver as permissões de um determinado arquivo ou diretório, devemos utilizar o comando ls com a opção –l (forma longa). Vejamos alguns exemplos: $ls -l /home/julio total 4 -rw-rw-r-1 -rw-rw-r-1 -rw-rw-r-1 Introdução ao UNIX julio suport julio suport julio suport 85 10 34 Sep 18 13:36 Sep 18 13:37 Sep 18 13:27 agenda agenda2 aula1 14 ASPER Sistemas Operacionais drwxrwxr-x -rw-rw-r-drwxrwxr-x -rw-rw-r-- 2 1 2 1 julio julio julio julio suport suport suport suport 1024 70 1024 30 1 2 3 4 5 1 – Permissões de acesso 2 – Número de ligações 3 – Dono 4 – Grupo ao qual pertence Sep 18 13:31 Sep 18 12:55 Sep 11 10:19 Sep 18 12:54 6 curso dados java readme 7 5 – Tamanho 6 – Data e hora da última atualização 7 – Nome No UNIX existem três tipos básicos de permissões: Leitura (r): quando aplicada a um arquivo, permite a leitura do seu conteúdo (ex: more arquivo). Já quando aplicada a um diretório, indica o poder de listar seu conteúdo, ou seja, seus arquivos e subdiretório (ex: ls diretório). Gravação (w): quando aplicada a um arquivo, permite a alteração do seu conteúdo. Se aplicada a um diretório, permite a criação ou remoção de arquivos e subdiretório no seu interior. Execução (x): quando aplicada a um arquivo, permite a sua execução, caso seja um arquivo executável. Se aplicada a um diretório, permite o acesso a ele (ex: cd diretório). Estas permissões são aplicadas a três classes de usuários do sistema: u – Usuário dono do arquivo ou diretório g – Usuários pertencentes ao grupo do arquivo ou diretório o – Demais usuário do sistema A permissão de acesso é formada por 10 (dez) caracteres, veja figura abaixo. O tipo do arquivo pode ser: (-) arquivo ordinário; (d) diretório; (c) arquivo especial referente a um dispositivo tipo caractere; (b) arquivo especial referente a um dispositivo tipo bloco; e (l) link ou atalho para outro arquivo. Para cada classe de usuários (u, g e o) são destinados três caracteres, que indicam a permissão de leitura, gravação e execução, respectivamente. Caso alguma permissão seja negada, na sua posição aparecerá um hífen (-). Introdução ao UNIX 15 ASPER Sistemas Operacionais Outra maneira de representar as permissões de um determinado arquivo ou diretório é a utilização do formato numérico. Neste formato, as permissões são representadas por três algarismos octais, ou seja, podem variar de 0 a 7. Sendo o primeiro para indicar os direitos do dono, o segundo do grupo e o terceiro dos outros usuários. Para cada tipo de permissão é associado um valor (r = 4, w = 2, x = 1). O algarismo referente aos direitos de uma classe (dono, grupo ou outros) é a soma das respectivas permissões da classe. Por exemplo, se uma classe possui as permissões r – x, então no formato numérico sua permissão seria 5 (r = 4 + x = 1). Vejamos alguns exemplos de permissões: 1) – r w – r – – r – – 2) – r – x – – x r – – Formato Numérico: 6 4 4 Formato Numérico: 5 1 4 Tipo: arquivo ordinário Dono: Leitura e gravação Grupo: Leitura Outros: Leitura Tipo: arquivo ordinário Dono: Leitura e execução Grupo: Execução Outros: Leitura 3) d r w x – – – – – – 4) – – w – – – x r – – Formato Numérico: 7 0 0 Formato Numérico: 2 1 4 Tipo: Diretório Dono: Leitura, gravação e execução Grupo: Nenhuma permissão Outros: Nenhuma permissão Tipo: arquivo ordinário Dono: Gravação Grupo: Execução Outros: Leitura O diagrama abaixo mostra como o UNIX checa as permissões antes de um acesso a um arquivo ou diretório. 8.1 – Comandos para alteração das permissões de arquivos O UNIX possui vários comandos que alteram as permissões de arquivos e diretórios. Listamos abaixo os mais importantes e freqüentemente utilizados. chmod [ugoa][+ - =][rwx] [arquivos] Introdução ao UNIX 16 ASPER Sistemas Operacionais Altera as permissões dos arquivos especificados. Apenas o dono do arquivo e o superusuário (root) podem alterar suas permissões. Exemplos: (logado como usuário juliol) $ls – l permissoes -rw-r--r-1 juliol admin 100 Feb 3 1998 permissoes $chmod u-w permissoes /* retira (-) a permissão de escrita (w) do dono (u) $ls – l permissoes -r--r--r-1 juliol admin 100 Feb 3 1998 permissoes $chmod g+x permissoes /* inclui (+) a permissão de execução (x) ao grupo (g) $ls – l permissoes -r--r-xr-1 juliol admin 100 Feb 3 1998 permissoes $chmod u+wx,g-rx,o+x permissoes $ls – l permissoes -rwx---r-x 1 juliol admin 100 Feb 3 1998 permissoes $chmod g=o permissoes $ls – l permissoes -rwxr-xr-x 1 juliol admin 100 Feb 3 1998 permissoes $chmod 700 permissoes $ls – l permissoes -rwx-----1 juliol admin 100 Feb 3 1998 permissoes $chmod 641 permissoes $ls – l permissoes -r-xr----x 1 juliol admin 100 Feb 3 1998 permissoes $chmod 644 permissoes $ls – l permissoes -rw-r--r-1 juliol admin 100 Feb 3 1998 permissoes chgrp grupo arquivos Altera o grupo dos arquivos especificados. Apenas o dono do arquivo e o superusuário (root) podem realizar esta tarefa, sendo que o dono do arquivo só pode alterar para um grupo ao qual pertença. Exemplos: (logado como usuário juliol) $ls – l permissoes -rw-r--r-1 juliol admin 100 Feb 3 1998 permissoes $chgrp suporte permissoes chgrp: you are not a member of group ‘suporte’: Operation not permitted $chgrp redes permissoes $ls – l permissoes -rw-r--r-1 juliol redes 100 Feb 3 1998 permissoes chown novo-dono arquivos Altera o usuário dono dos arquivos especificados. Em alguns sistemas UNIX apenas o superusuário (root) pode realizar esta operação. Entretanto, existem sistemas UNIX que permitem, além do root, o dono do arquivo. Exemplos: (logado como usuário root) $ls – l permissoes -rw-r--r-1 juliol admin $chown joaob permissoes Introdução ao UNIX 100 Feb 3 1998 permissoes 17 ASPER Sistemas Operacionais $ls – l permissoes -rw-r--r-1 joaob redes 100 Feb 3 1998 permissoes 9 – Editando textos com o vi O vi (Visual Editor) é um dos mais conhecidos e utilizados programas para edição de textos ASCII em ambientes UNIX. Embora não possua uma interface amigável, o grande atrativo do vi é que ele é nativo do UNIX, ou seja, em todo ambiente UNIX você o encontrará. O vi possui três modos de operação: Comandos: toda sessão de edição começa nesse modo de operação. Nele, podemos caminhar pelo texto e utilizar os comandos do vi para manipulação de textos. Inserção: somente neste modo podemos alterar o texto. Última linha: alguns comandos de edição devem ser digitados na última linha da tela. O caractere : é usado para indicar ao editor que vamos usar um comando de linha. Sempre que o : é digitado, ele aparece no início da última linha da tela A figura a seguir ilustra os três modos de operação do vi, bem como as possíveis mudanças de estados que podem ocorrer. Comandos de movimentação h, j, k, l ^ $ b w Ctrl-f Ctrl-b Ctrl-d Ctrl-u : Move o cursor para: esquerda, baixo, cima, direita : Vai para o início da linha : Vai para o fim da linha : Retorna uma palavra : Avança uma palavra : Avança uma tela : Retorna uma tela : Avança 1/2 tela : Retorna 1/2 tela Comandos de inserção i I : Insere a partir da posição atual do cursor : Insere no começo da linha Introdução ao UNIX 18 ASPER Sistemas Operacionais a : Insere depois da posição atual do cursor : Insere no final da linha : Insere uma linha abaixo da linha atual : Insere uma linha acima da linha atual : Substitui o caractere sob o cursos (apenas 1) : Substitui vários caracteres a partir da posição do cursor : Substitui a linha atual : Substitui até o fim da linha atual : Remove o caractere sob o cursor : Remove a linha atual : Copia a linha atual para o buffer (área de transferência) : Recupera o buffer após a linha atual : Desfaz a última operação A o O r R S C x dd yy p u Comandos da última linha para copiar, mover e remover linhas n $ x,y t z x,y m z x,y d : Posiciona o cursor no início da linha n : Posiciona o cursor no início da última linha do texto : Copia as linhas de x até y após da linha z : Move as linhas de x até y após da linha z : Remove as linhas de x até y Comandos da última linha para salvar alterações e sair do vi w wq ou x q! w arquivo : Salva o arquivo sendo editado : Salva o arquivo sendo editado e encerra a sessão do vi : Encerra a sessão do vi sem salvar o arquivo sendo editado : Salva o arquivo sendo editado com outro nome Comandos da última linha para pesquisa e substituição de strings /texto : Pesquisa no arquivo pela string texto n : Repete a última pesquisa realizada g/p1/s//p2/ : Substitui em cada linha a primeira ocorrência da string p1 pela string p2 g/p1/s//p2/g : Substitui em todo o arquivo todas as ocorrências da string p1 pela string p2 g/p1/s//p2/gc : Substitui em todo o arquivo todas as ocorrências da string p1 pela string p2, pedindo confirmação antes de cada substituição Existem várias formas de ativar o editor vi: $vi /* Ativa o vi para edição de um arquivo em branco $vi arquivo /* Ativa o vi para edição do arquivo especificado $vi +n arquivo /* Ativa o vi para edição do arquivo especificado e posiciona na linha n $vi +/string arquivo /* Ativa o vi para edição do arquivo especificado e posiciona na primeira ocorrência da string 10 – Programação Shell – Shell Script Introdução ao UNIX 19 ASPER Sistemas Operacionais Como vimos anteriormente, o SHELL , ou interpretador de comandos, serve de interface entre os usuários e o sistema operacional. Desta forma, quando queremos que o sistema operacional faça alguma tarefa, por exemplo, listar o conteúdo de um diretório, devemos solicitar isto ao SHELL, no caso, através do comando ls. Outra função importante do SHELL é o tratamento dos comandos, ele deve resolver todos os redirecionamentos de E/S e todos os caracteres curingas usados, antes de passar os comandos para o sistema operacional executar. Scripts são arquivos texto (ASCII) formados por comandos de um determinado SHELL, sua principal função é a automação de tarefas. Programação Shell nada mais é do que o desenvolvimento de scripts shell. Em ambientes UNIX, os Shells possuem uma linguagem de programação poderosa, isto permite a criação de scripts avançados que podem ser utilizados na automação de tarefas complexas. 10.1 – O uso de Aspas, Apóstrofos, Barra invertida e Crase Podemos indicar ao shell a forma de interpretação dos caracteres especiais em cada comando. Isto é feito através do uso das aspas, apóstrofos, barra invertida e crase. Vejamos a utilidade de cada um destes sinais: Aspas duplas: quando colocamos um caractere especial entre aspas, indicamos para o shell ignorá-lo, ou seja, tratá-lo como um caractere normal. Isto é válido para todos os caracteres especiais, exceto o cifrão ($), uma crase (`) ou uma barra invertida (\). Apóstrofos: o uso de apóstrofos faz com que o shell ignore TODOS os caracteres especiais, sem nenhuma exceção. Barra invertida: o shell ignorará o caractere que segue a barra invertida (apenas um caractere). Se colocada no final da linha, o shell interpretará a barra invertida como uma solicitação de continuação do comando na próxima linha. Crase: as crases são usadas para avisarmos ao shell que o que está entre elas é um comando e para darmos prioridade em sua execução. Exemplos: $ ls programas docs provas $ echo Isto eh um asterisco = * /* interpreta o asterisco e retorna os nomes dos arquivos Isto eh um asterisco = programas docs provas $ echo “Isto eh um asterisco = *” /* não interpreta o asterisco como caractere especial Isto e um asterisco = * $ echo “O preco total eh: 100 $s” /* interpreta o $ e retorno o valor da variável $s O preco total eh: 100 $ echo ‘O preco total eh: 100 $s’ /* não interpreta o $ O preco total eh: 100 $s $ echo Isto eh um asterisco =\ * /* não interpreta o asterisco Isto eh um asterisco = * $ echo O preco total eh: 100 \$s /* não interpreta o $, que segue a barra invertida O preco total eh: 100 $s $ echo “para continuar o comando na proxima linha digite \” >Ctrl-C $ echo “para exibir uma barra invertida digite \\” para exibir uma barra invertida digite \ Introdução ao UNIX 20 ASPER Sistemas Operacionais $ echo “Estou no diretorio: `pwd` ” Estou no diretorio: /home/turma981 $ echo “Meus arquivos sao: `ls` ” Meus arquivos sao: programas docs $ echo ‘Estou no diretorio: `pwd` ‘ /*Aspas não ignoram crases, então o pwd será executado /*Aspas não ignoram crases, então o ls será executado provas /* Apóstrofos ignoram crases, então pwd não será executado 10.2 – Localizando cadeias de caracteres O comando grep é utilizado para localizar cadeias de caracteres em uma determinada entrada, que pode ser: uma lista de arquivos, a saída de um comando recebida através do uso de pipes ( | ), ou a entrada padrão, se nenhuma outra for especificada. As cadeias podem ser especificadas com a utilização de metacaracteres (curingas). grep [-ncvil] cadeia [arquivos] Opções: -n : Precede cada linha que possui a cadeia com o número da linha -c : Exibe apenas a quantidade de linhas que possuem a cadeia -v : Exibe todas as linhas, exceto aquelas que possuem a cadeia -i : Ignora diferença de letras maiúsculas e minúsculas -l : Exibe apenas os nomes dos arquivos que possuem a cadeia Exemplos: $ cat agenda /*Mostra o conteúdo do arquivo UNIX Joao Maria (081) 222-1122 Marcia Ribeiro (083) 221-1009 Maria Jose (083) 235-0011 Ana Maria (083) 987-0087 Lis Leite (011) 224-2074 Jose Carlos (087) 234-9009 maria Alves (083) 223-8051 $ grep Maria agenda /* Pesquisa pela cadeia “Maria” dentro do arquivo agenda Joao Maria (081) 222-1122 Maria Jose (083) 235-0011 Ana Maria (083) 987-0087 $ grep –n Maria agenda /* Exibe a numeração das linhas que possuem a cadeia “Maria” 1 : Joao Maria (081) 222-1122 3 : Maria Jose (083) 235-0011 4 : Ana Maria (083) 987-0087 $ grep -i Maria agenda /* Ignora a diferença entre maiúsculas e minúsculas Joao Maria (081) 222-1122 Maria Jose (083) 235-0011 Ana Maria (083) 987-0087 maria alves (083) 223-8051 $ grep -c Jose agenda /* Conta quantas linhas possuem a cadeia “Jose” 2 $ grep –v Maria agenda /* Mostra apenas as linhas que não possuem a cadeia “Maria” Marcia Ribeiro (083) 221-1009 Lis Leite (011) 224-2074 Jose Carlos (087) 234-9009 maria Alves (083) 223-8051 Introdução ao UNIX 21 ASPER Sistemas Operacionais $ grep –l Joao * /* Mostra os arquivos do diretório corrente que possuem a cadeia “Joao” agenda : Joao Maria (081) 222-1122 notas: Joao Batista 8,5 agenda.old: Joao Silva (081) 222-9999 O comando grep permite a utilização de metacaracteres especiais para especificação da cadeia de caracteres a ser pesquisada. Alguns deles são: . : Substitui apenas um caractere, é semelhante ao curinga ? do UNIX .* : Substitui qualquer seqüência de caracteres, é semelhante ao curinga * do UNIX [ ] : Substitui por qualquer caracteres especificada no intervalo ^ : Indica que a cadeia especificada deve estar posicionada no início da linha Exemplos: $ grep ‘L.s’ agenda /* Uso do metacaractere (.) Lis Leite (011) 224-2074 $ grep ‘^Maria’ agenda /* Mostra as linhas que possuem a palavra “Maria” no início Maria Jose (083) 235-0011 $ grep ‘Mar.*’ agenda /* Mostra as linhas que possuem palavras começadas por “Mar” Joao Maria (081) 222-1122 Marcia Ribeiro (083) 221-1009 Maria Jose (083) 235-0011 Ana Maria (083) 987-0087 $ grep ‘^[JL]’ agenda /* Mostra as linhas que começam com a letra J ou L Joao Maria (081) 222-1122 Lis Leite (011) 224-2074 Jose Carlos (087) 234-9009 $ grep ‘^[^JM]’ agenda /* Mostra as linhas que não (^) começam com a letra J ou M Ana Maria (083) 987-0087 Lis Leite (011) 224-2074 maria Alves (083) 223-8051 $ ls –l | grep ‘^d’ /* Lista no formato longo apenas os subdiretórios do diretório corrente drwxrwxr-x 2 julio suport 1024 Sep 18 13:31 curso drwxrwxr-x 2 julio suport 1024 Sep 11 10:19 java drw-rw-r-9 julio suport 1024 Sep 18 12:54 provas 10.3 – Extraindo colunas O comando cut é utilizado para extrair colunas (campos) de um arquivo, da saída padrão de outro comando ou da entrada padrão. cut -c<Faixa-de-Caracteres> arquivo Onde <Faixa-de-Caracteres> pode ser: x : Retorna o caractere da posição x de cada linha do arquivo Introdução ao UNIX 22 ASPER Sistemas Operacionais x-y : Retorna os caracteres das posições de x até y de cada linha do arquivo x- : Retorna os caracteres a partir da posição x de cada linha do arquivo -x : Retorna os caracteres do início até a posição x de cada linha do arquivo Exemplos: $ cat agenda /*Mostra o conteúdo do arquivo UNIX Joao Maria (081) 222-1122 Maria Jose (083) 235-0011 Ana Maria (083) 987-0087 Lis Leite (011) 224-2074 $ cut -c1 agenda /*Extrai a primeira letra de cada linha do arquivo agenda J M A L $ cut -c1-3 agenda /* Extrai as 3 primeiras letras de cada linha do arquivo agenda Joa Mar Ana Lis $ ls –l | grep ‘^d’ | cut –c2-10 /* Lista as permissões apenas dos subdiretórios do diretório corrente rwxrwxr-x rwxrwxr-x rw-rw-r-As sintaxes e os exemplos apresentados acima, mostram como o comando cut funciona para extração de campos com posições predefinidas dentro do arquivo. Em muitas situações este tipo de extração não resolve os problemas, pois há a necessidade de extrair determinados campos que nem sempre ocorrem nas mesmas posições do arquivo. Nestas situações, devemos usar as opções –f e –d do comando cut. A opção –f indica quais os campos a serem extraídos, enquanto a opção –d especifica o caractere que servirá de delimitador dos campos. cut -f<Faixa-de-Campos> -d “delimitador” Cada linha do arquivo é tratada como uma seqüência de campos, sendo estes separados pelo caractere “delimitador” especificado na opção –d. Onde <Faixa-de-Campos> pode ser: x : Retorna o campo da posição x de cada linha do arquivo x-y : Retorna os campos das posições de x até y de cada linha do arquivo x- : Retorna os campos a partir da posição x de cada linha do arquivo -x : Retorna os campos do início até a posição x de cada linha do arquivo Exemplos: $ cat /dados/funcionarios /*Lista o conteúdo do arquivo de funcionários 325:Joao Batista:Administrativo:12/10/1974:224-4356:Joao Pessoa – Pb 127:Maria de Fatima:Contabilidade:20/06/1969:221-2134:Patos – Pb 450:Ana Maria Lins:Informatica:01/02/1970:214-5252:Salvador – Ba 981:Francisco Almeida:Financeiro:10/01/1963:235-2087:Fortaleza – Ce $ cut –f1 –d”:” /dados/funcionarios /*Extrai o1º campo do arquivo, tendo como delimitador (:) Introdução ao UNIX 23 ASPER Sistemas Operacionais 325 127 450 981 $ cut –f1-2 –d”:” /dados/funcionarios 325:Joao Batista 127:Maria de Fatima 450:Ana Maria Lins 981:Francisco Almeida /*Lista os campos 1 e 2 10.4 – Criando e executando Scripts Shell Como dito anteriormente, um script shell é um arquivo do tipo texto que contém uma seqüência de comandos de um determinado Shell. Para ilustrar este conceito, vamos criar um script bem simples, que exibe uma mensagem dizendo em qual diretório o usuário se encontra no momento e em seguida lista o conteúdo deste diretório. Através de um editor de textos (vi ou pico) vamos criar o arquivo Lista.sh com o seguinte conteúdo: 1 2 3 4 5 6 7 8 9 10 #! /bin/ksh # Script: Lista.sh # 1 – Limpa a tela # 2 – Exibe o diretório atual # 3 – Lista o conteúdo do diretório atual echo O diretorio atual e: `pwd` echo Seu conteudo e: ls Na primeira linha, o usuário deve especificar qual SHELL deverá executar os comandos contidos no script. Se nenhum for especificado, o sistema utilizará o SHELL padrão do usuário. As linhas 3-6 são de comentários (iniciadas por #) e não são interpretadas pelo SHELL. E, finalmente, nas linhas 8-11 estão os comandos propriamente ditos que executam as tarefas do script. Agora que o script está pronto vamos executá-lo. $Lista.sh ksh: Lista.sh: cannot execute $ O que aconteceu? Como vimos na seção de permissões de arquivos, para que um determinado usuário possa executar um programa, ou script, ele precisar ter a permissão de execução (x) mesmo que ele seja o dono. Vejamos quais são as permissões do arquivo Lista.sh: $ ls –l Lista.sh -rw-r--r-1 julio suport 85 Sep 18 13:36 Lista.sh Veja que o dono do script Lista.sh não possui a permissão x, logo não poderá executá-lo. Então devemos antes de executar o script incluir a permissão x. $ chmod +x Lista.sh $ ls –l Lista.sh -rwxr-xr-x 1 julio suport Introdução ao UNIX 85 Sep 18 13:36 Lista.sh 24 ASPER Sistemas Operacionais Vamos tentar executar o script Lista.sh novamente, já que temos permissão para isto. $Lista.sh ksh: Lista.sh: cannot execute $ O que aconteceu desta vez? Todas as vezes que solicitamos para o SHELL executar algum programa ou script, ele vai procurar em todos os diretório especificados na variável de ambiente PATH para tentar encontrar o programa ou script. Como o diretório atual, onde se encontra o script Lista.sh, não está no PATH, o SHELL retornará uma mensagem de erro. Veja o conteúdo da variável PATH: $echo $PATH /bin: /usr/bin: /usr/local/bin $ Para resolver o problema temos duas alternativas. A primeira é indicar para o SHELL que o script Lista.sh está no diretório atual: $./Lista.sh O diretorio atual e: /usr/julio/scripts Seu conteudo e: Lista.sh Script1.sh Script5.sh Script6.sh $ Script2.sh Script3.sh Script4.sh A outra forma de resolver o problema é fazer com que o SHELL procure pelo script também no diretório atual, ou seja, incluir na variável de ambiente PATH o diretório atual, que para o UNIX é representado por um . (ponto). Veja os comandos a seguir: $echo $PATH /bin: /usr/bin: /usr/local/bin $PATH=$PATH:. $echo $PATH /bin: /usr/bin: /usr/local/bin:. $Lista.sh O diretorio atual e: /usr/julio/scripts Seu conteudo e: Lista.sh Script1.sh Script5.sh Script6.sh $ Script2.sh Script3.sh Script4.sh Agora que já sabemos como fazer um script e como executá-lo, vamos apresentar a linguagem de programação que pode ser utilizada para a construção de scripts mais avançados. 10.5 – Usando variáveis em Scripts Shell Introdução ao UNIX 25 ASPER Sistemas Operacionais O SHELL, como qualquer outra linguagem de programação, trabalha com variáveis. Veja os exemplos no script Var.sh. $cat Var.sh #! /bin/ksh # # Declarando Variaveis # Nome=”Ana Maria” Matricula=981899899 Contador=1 Dir_Atual=`pwd` #podemos atribuir o resultado de um comando a uma variavel Var_Nula= # # Referenciando Variaveis # echo Valor da variavel Nome: $Nome echo Matricula: $Matricula echo Contador: $Contador echo O diretorio atual e: $Dir_Atual echo Valor da variavel Var_Nula: $Var_Nula $./Var.sh Valor da variavel Nome: Ana Maria Matricula: 981899899 Contador: 1 Valor da variavel Var_Nula: $ OBS: Nas declarações de variáveis não deve existir espaços antes ou depois do sinal de igual (=). 10.6 – Trabalhando com Parâmetros Os parâmetros são valores passados para os scripts no momento da solicitação de execução, e devem ser separados por pelo menos um espaço em branco. Por exemplo, no comando: cp /etc/hosts /tmp/hosts.old, estamos executando o comando cp e passando dois parâmetros para sua execução. O primeiro é o arquivo a ser copiado e o segundo é o arquivo de destino. Esta passagem de parâmetros funciona de maneira análoga na execução de scripts shell, sendo que neste caso, dentro dos scripts os parâmetros são referenciados pelas seguintes variáveis: $0 : armazena o nome do script que está sendo executado $1-$9 : armazena os nove primeiros parâmetros passados para o script. Sendo que o primeiro deve ser referenciado por $1, o segundo por $2 e assim por diante até o nono parâmetro. $# : contém a quantidade de parâmetros passados para o script $* : contém o conjunto de todos os parâmetros passados para o script. Introdução ao UNIX 26 ASPER Sistemas Operacionais Veja os exemplos a seguir: $cat Par.sh #! /bin/ksh echo O nome do script e: $0 echo A quantidade de parametros passados foi: $# echo O conjunto de parametros passados foi: $* echo O primeiro parametro e: $1 echo O segundo parametro e: $2 echo O terceiro parametro e: $3 $./Par.sh /* executando o script sem passar nenhum parâmetro O nome do script e: Par.sh A quantidade de parametros passados foi: 0 O conjunto de parametros passados foi: O primeiro parametro e: O segundo parametro e: O terceiro parametro e: $./Par.sh “Ana Maria” 10 Paraiba /* executando o script passando três parâmetros O nome do script e: Par.sh A quantidade de parametros passados foi: 3 O conjunto de parametros passados foi: Ana Maria 10 Paraiba O primeiro parametro e: Ana Maria O segundo parametro e: 10 O terceiro parametro e: Paraiba Para aplicar o uso de parâmetros de uma maneira mais prática, vamos construir alguns scripts que realizam operação sobre um arquivo que serve como uma agenda telefônica. A estrutura do arquivo Agenda.dat é: Nome <TAB> Telefone. O script List.sh serve para listar o conteúdo da Agenda eletrônica de forma paginada. Seu código é: $cat List.sh #! /bin/ksh more Agenda.dat O script Inc.sh serve para incluir uma pessoa na agenda. Ele recebe dois parâmetros: o nome e o telefone da pessoa a ser incluída. Seu código é: $cat Inc.sh #! /bin/ksh # # Inclui o novo registro no arquivo Agenda.dat # Estamos usando o caractere <tab> como delimitador dos campos # Introdução ao UNIX 27 ASPER Sistemas Operacionais echo “$1 $2” >> Agenda.dat sort –o Aganda.dat Aganda.dat O script Con.sh serve para pesquisar um telefone de uma determinada pessoa. Ele recebe como parâmetro o nome da pessoa a ser pesquisada. Seu código é: $cat Con.sh #! /bin/ksh # # Pesquisa pelo nome recebido como parametro dentro do arquivo Agenda.dat # grep “^$1” Agenda.dat O script Exc.sh serve para excluir uma determinada pessoa da agenda. Ele recebe como parâmetro o nome da pessoa a ser removida. Seu código é: $cat Exc.sh #! /bin/ksh # # Remove as pessoas do arquivo Agenda.dat # grep –v “^$1” Agenda.dat > /tmp/Agenda.tmp mv /tmp/Agenda.tmp Aganda.dat Agora que os scripts foram descritos vamos utilizá-los para manipular a agenda eletrônica. $List.sh /* Aganda está vazia $Inc.sh “Julio Cesar” 222-9090 $Inc.sh “Ana Maria” 226-9154 $Inc.sh Joao 222-9090 $List.sh Ana Maria 226-9154 Joao 222-9090 Julio Cesar 222-9090 $Con.sh Ana Ana Maria 226-9154 $Exc.sh Julio $List.sh Ana Maria 226-9154 Joao 222-9090 $ 10.7 – Lendo valores do teclado Introdução ao UNIX 28 ASPER Sistemas Operacionais Como vimos, o uso de parâmetros permite ao usuário passar informações ao script que será executado. Outra forma de receber informações do usuário é através da utilização do comando read. Sua sintaxe é: read [var1] [var2] [var3] ... [varn] Outro comando importante que serve para auxiliar a entrada de dados é: tput cup lin col. Sua função é posicionar o cursor na linha e coluna especificadas. Vamos fazer uma nova versão do script Inc.sh, agora usando os comandos read e tput cup. Veja o novo código: $cat Inc2.sh #! /bin/ksh clear # Limpa a tela tput cup 10 15 # posiciona o cursor na linha 10 e na coluna 15 echo –n “Entre com o nome: “ read Nome tput cup 11 15 # posiciona o cursor na linha 11 e na coluna 15 echo –n “Entre com o telefone: “ read Fone echo “$Nome $Fone” >> Agenda.dat sort –o Aganda.dat Aganda.dat 10.8 – Execução condicional Comando IF if <comando> then bloco 1 else bloco 2 fi Se o <comando> foi executado com sucesso, então os comandos do bloco 1 serão executados. Caso contrário, os comandos do bloco 2 serão executados. Veja a nova versão do script Con.sh. $cat Con2.sh #! /bin/ksh # # Pesquisa pelo nome recebido como parametro dentro do arquivo Agenda.dat # if registro=`grep “^$1” Agenda.dat` > /dev/null 2> /dev/null then Introdução ao UNIX 29 ASPER Sistemas Operacionais echo $registro else echo $1 não esta cadastrado fi Neste caso, atribuímos o resultado do comando grep à variável registro. Caso o nome passado como parâmetro não exista no arquivo Agenda.dat, o comando grep gerará um erro e o bloco a ser executado será o do else. Se o nome existir, o script exibirá o conteúdo da variável registro, que contém o resultado da consulta. O comando if no formato acima serve para testar se a execução de um determinado comando gerou algum erro. Podemos também usar o comando test, ou [ ], para testar outros tipos de condições. Veja algumas possibilidades: -r arquivo -w arquivo -x arquivo -f string -d string -s arquivo Operações para Arquivos e Diretórios Testa se o usuário tem permissão de leitura no arquivo especificado Testa se o usuário tem permissão de escrita no arquivo especificado Testa se o usuário tem permissão de execução no arquivo especificado Testa se a string é um nome de um arquivo Testa se a string é um nome de um diretório Testa se o tamanho do arquivo especificado é maior que zero -z string -n string str1 = str2 string Operações para Cadeias de caracteres Testa se o tamanho da string é zero Testa se o tamanho da string é diferente de zero Testa se str1 e str2 são idênticas Testa se a string é não nula x x x x x x Operações para Números inteiros Testa se x é igual a y Testa se x é diferente de y Testa se x é maior que a y Testa se x é maior ou igual a y Testa se x é menor que a y Testa se x é menor ou igual a y –eq y –ne y –gt y –ge y –lt y –le y O script a seguir tem como objetivo receber dois arquivos distintos como parâmetros e verificar se o usuário possui as permissões de execução em cada um deles. Caso os arquivos não sejam passados ou não sejam distintos, uma mensagem de erro deve ser exibida para o usuário. $cat TestaIf.sh #! /bin/ksh # Testa se o script recebeu dois parametros if [ $# -ne 2 ] then echo “Erro de sintaxe. Uso correto eh: $0 <arquivo1> <arquivo2>” exit 1 fi Introdução ao UNIX 30 ASPER Sistemas Operacionais #Testa se o primeiro parametro e um arquivo if [ ! –f $1 ] then echo “Erro: Arquivo $1 nao encontrado” exit 2 fi #Testa se o segundo parametro e um arquivo if [ ! –f $2 ] then echo “Erro: Arquivo $2 nao encontrado” exit 2 fi #Testa se os arquivos recebidos sao distintos if [ “$1” = “$2” ] then echo “Erro: Os Arquivos informados sao iguais” exit 3 fi # Testa se o usuario possui permissao de execucao no primeiro arquivo if [ -x $1 ] then echo “O usuario pode executar o arquivo $1” exit 0 fi # Testa se o usuario possui permissao de execucao no segundo arquivo if [ -x $2 ] then echo “O usuario pode executar o arquivo $2” exit 0 fi Como em qualquer outra linguagem de programação, na programação SHELL podemos especificar condições compostas, através dos operadores lógicos: -a (e) e -o (ou). Veja o exemplos. $cat AndOr.sh #! /bin/ksh # Testa se o numero de parametros recebidos e igual a 2 ou 4 if [ $# -eq 2 –o $# -eq 4 ] then echo “O script recebeu 2 ou 4 parametros” exit 0 fi # Testa se o numero de parametros recebidos esta entre 5 e 9, inclusive Introdução ao UNIX 31 ASPER Sistemas Operacionais if [ $# -ge 5 –a $# -le 9 ] then echo “O script recebeu entre 5 e 9 parametros” exit 0 fi Comando CASE case var in padrão1 ) bloco1 ;; padrão2 ) bloco2 ;; ... padrãon ) blocon ;; esac O comando case deve ser utilizado quando queremos executar um dentre vários blocos de comandos dependendo do valor ou padrão assumido por uma determinada variável. Seu uso evita a utilização de comandos ifs sucessivos, isto agiliza a execução do script além de deixá-lo mais legível. O script a seguir recebe um caracter como parâmetro e verifica se ele é uma letra maiúscula, minúscula, um algarismo ou outro caracter qualquer. $cat TestaChar.sh #! /bin/ksh # Testa se o script recebeu apenas um parametros if [ $# -ne 1 ] then echo “Erro de sintaxe. Uso correto eh: $0 <caracter>” exit 1 fi #Testa se o parametro recebido e um caracter case $1 in ? ) ;; #se tiver so um caracter não faz nada * ) echo “Erro: $1 não e um caracter” exit 2 ;; esac # Testa a classe do caracter recebido Introdução ao UNIX 32 ASPER Sistemas Operacionais case $1 in [a-z] ) echo “$1 e uma letra minuscula” ;; [A-Z] ) echo “$1 e uma letra maiuscula” ;; [0-9] ) echo “$1 e um algarismo decimal” ;; * ) echo “$1 e uma caracter especial” ;; esac O script a seguir exibe um menu e lê uma opção digitada pelo usuário. Dependendo da opção ele executará outro script apropriado. $cat TestaChar.sh #! /bin/ksh clear echo “ OPCAO DESCRICAO” echo “ ====== ======================” echo “ 1 Incluir Registro” echo “ 2 Consultar Registro” echo “ 3 Excluir Registro” echo “ 0 ou q Sair” echo “Escolha uma opcao: “ read opcao case $opcao in 1 ) Inc.sh ;; 2 ) Con.sh ;; 3 ) Exc.sh ;; 0 | q | Q ) exit 0 ;; * ) echo “Opcao invalida” ;; esac #Testa se e 0 ou q ou Q OBS: 1) Todos os blocos de comandos, referentes a cada um dos padrões, devem ser seguidos de ;; que representa o fim do bloco. 2) padrão * deve ser sempre o último a ser testado, visto que combina com qualquer valor da variável especificada no comando case. Introdução ao UNIX 33 ASPER Introdução ao UNIX Sistemas Operacionais 34