Baixe o app para aproveitar ainda mais
Prévia do material em texto
137 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA Unidade IV 7 SISTEMA OPERACIONAL LINUX O Linux é um clone UNIX de distribuição livre para PCs baseados em processadores 386/486/Pentium. Ele é uma implementação independente da especificação POSIX, com a qual todas as versões do UNIX padrão (true UNIX) estão convencionadas. Primeiramente, o Linux foi desenvolvido para PCs baseados em 386/486/Pentium, mas, hoje em dia, também roda em computadores Alpha da DEC, Sparcs da SUN, máquinas M68000 (semelhantes a Atari e Amiga), MIPS e PowerPCs. Ele foi escrito inteiramente do nada, não há código proprietário em seu interior, e está disponível na forma de código objeto, bem como em código fonte. Pode ser livremente distribuído nos termos da GNU General Public License. Observação Consideramos software livre qualquer programa de computador que contenha o seu código aberto para modificações dos seus usuários de acordo com as suas necessidades, podendo ou não serem redistribuidos. O Linux possui todas as características que você pode esperar de um UNIX moderno, incluindo: • multitarefa real; • memória virtual; • biblioteca compartilhada; • demand loading; • gerenciamento de memória próprio; • executáveis copy‑on‑write compartilhados; • rede TCP/IP (incluindo SLIP/PPP/ISDN); • X Windows. 138 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV A maioria dos programas que rodam em Linux são freeware genéricos para UNIX, muitos provenientes do projeto GNU, projeto este que determina os critérios para a definição se um determinado software se qualifica dentro da categoria de software livre. O Linux está disponível através da internet por meio de centenas de sites FTP. Hoje em dia, ele é usado por várias pessoas pelo mundo para o desenvolvimento de softwares, networking (intraoffice e internet) e como plataforma de usuário final. O Linux tem se tornado uma alternativa efetiva de custo em relação aos caros sistemas UNIX existentes. Observação Existem diversas empresas de software que implementaram funcionalidades a versões do Linux e devido a esses investimentos não disponibilizam de forma gratuita para os demias usuários. Essas versões deixam de ser caracterizadas como software livre, passando a ser comercializadas como os demais sistemas operacionais dessa concepção. Um exemplo de pacote mais popular de distribuição do Linux, a versão LINUX Developer’s Resource CD‑ROM, contém 6 CD‑ROMs. De forma sucinta, ela possui: • versão Red Hat 4.0 (instalando kernel 2.0.18); • versão Slackware 3.1 (Slackware 96 – instalando kernel 2.0); • versão Debian GNU/Linux 1.2; • X‑Windows – Xfree86 version 3.2; • arquivos Linux de tsx‑11.mit.edu e sunsite.unc.edu; • arquivos GNU de prep.ai.mit.edu; • documentação completa on‑line & HOWTO’s (Guia de Instalação e Guia do Administrador da Rede, em inglês); • softwares demonstração comerciais como: BRU, dbMan, StarOffice, Cockpit, Flagship, Smartware, GP Modula‑2, Pathfinder, Scriptum etc. Lembrete Cada versão do Linux possui as suas particularidades e muitas vezes diferenças significativas em suas funcionalidades, como, por exemplo, as 139 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA próprias interfaces gráficas que variam muito de uma versão para outra. A escolha adequada de cada versão deve analisar essas particularidades, a fim de atender às expectativas dos usuários. 7.1 Histórico O kernel do Linux foi, originalmente, escrito por Linus Torvalds, do Departamento de Ciência da Computação da Universidade de Helsinque, na Finlândia, com a ajuda de vários programadores voluntários através da internet. Linus Torvalds iniciou cortando (hacking) o kernel como um projeto particular, inspirado em seu interesse no Minix, um pequeno sistema UNIX desenvolvido por Andy Tannenbaum. Depois de algum tempo de trabalho em seu projeto, sozinho, ele divulgava a mensagem de que todos os homens, para se sentirem livres, deveriam ter condições de elaborar os próprios dispositivos e integrá‑los nos sistemas operacionais de acordo com as suas necessidades. Desenvolveu e disponibilizou uma versão do sistema Minix, não completa, com código aberto na internet para que colaboradores pudessem aprimorar o seu código e compartilhar as suas versões com todo o mundo. No dia 5 de outubro de 1991, Linus Torvalds anunciou a primeira versão oficial (a 0.02) do Linux. Desde então, muitos programadores têm respondido ao seu chamado e têm ajudado a fazer do Linux o sistema operacional que é hoje. 7.2 Gerenciamento de processos 7.2.1 Considerações iniciais Para explicar como o Linux gerência processos, serão feitas considerações iniciais sobre o código fonte do kernel do Linux (onde é encontrada a implementação da gerência de processos) e a inicialização boot do sistema. Será elucidado, de maneira ordenada, o código fonte do Linux, onde ele está situado e como as características mais relevantes do UNIX foram implementadas. O objetivo é a familiarização com o projeto geral do Linux. Este procedimento terá início com o sistema de boot do Linux. É necessário um bom entendimento da linguagem C para compreender este material, assim como familiaridade com conceitos de UNIX e arquitetura dos PCs. Qualquer referência pathname a arquivos tem como ponto de partida a árvore principal de fontes utilizada no sistema Linux, usualmente /usr/src/linux. As informações reportadas aqui têm como referência o código fonte do Linux na versão 1.0, podendo aparecer algumas referências a versões mais atuais. 140 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV 7.2.2 Inicialização do sistema Quando o PC é ligado, o processador 80x86 encontra‑se em modo real e executa o código contido no endereço 0xFFFF0, que corresponde a um endereço ROM‑BIOS. O BIOS do PC realiza alguns testes no sistema e inicializa o vetor de interrupções no endereço físico 0. Depois disso, ele carrega o primeiro setor do device bootavel em 0x7C00 e passa a execução para este endereço. O device é, usualmente, o disquete ou o disco rígido. A descrição anterior é um tanto simplificada, mas é tudo que se necessita para entender o trabalho inicial do kernel. A primeiríssima parte do kernel Linux está escrito em linguagem assembly 8086 (boot/bootsect.S), e, a seguir, temos um exemplo de código em linguagem assembly. Quando é executado, ele se move para o endereço absoluto 0x90000, carrega os próximos 2 kbytes de código do device de boot até o endereço 0x90200, e o resto do kernel para o endereço 0x10000. A mensagem “Loading...” é apresentada durante o carregamento do sistema. O controle é, então, passado para o código contido em boot/Setup.S, outro código assembly de modo real. A parte de setup identifica algumas características do sistema (hardware) e o tipo da placa VGA. Se requerido, pede ao usuário para escolher o modo do vídeo do console e, então, move todo o sistema do endereço 0x10000 para o endereço 0x1000, passa para o modo protegido e passa o controle para o resto do sistema (endereço 0x1000). O próximo passo é a descompressão do kernel. O código em 0x1000 vem de zBoot/head.S, que inicializa os registradores e invoca decompress_kernel(), o qual é composto por zBoot/inflate.c, zBoot/ unzip.c e zBoot/misc.c. O dado descompresso vai para o endereço 0x100000 (1 Mega) e esta é a principal razão do porquê o Linux não pode rodar com menos de 2 megas de RAM. O encapsulamento do kernelem um arquivo gzip é realizado por makefile e utilitários no diretório zBoot. São arquivos interessantes para se dar uma olhada. A versão 1.1.75 moveu os diretórios boot e zBoot para arch/i386/boot. Esta modificação pretendeu possibilitar a construção de um kernel verdadeiro para diferentes arquiteturas. O código descompresso é executado a partir do endereço 0x1010000, onde todo o setup 32‑bit está lotado: IDT, GDT e LDT são carregados, o processador e o coprocessador são identificados, a rotina start_kernel é invocada. Os arquivos fonte das operações anteriores estão em boot/head.S. Este, talvez, seja o código mais difícil em todo o kernel do Linux. Note que se algum erro ocorrer durante alguns dos passos precedentes, o computador irá travar. O sistema operacional não pode manipular erros enquanto não estiver totalmente operante. A função start_kernel() reside em init/main.c. Consideremos que a partir de agora todo o sistema está codificado em linguagem C, com excessão de algumas funções relativas ao gerenciamento de interrupções e determinadas chamadas a outros sistemas que continuam codificadas em linguagem assembly, porém embutidas em macros utilizadas pelo código em C. 141 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA Depois dos procedimentos com todas as questões iniciais, start_kernel() inicializa todas as partes do kernel, especificamente: • a memória e chama paging_init(); • os traps, canais IRQ e scheduling; • se requerido, aloja um profiling buffer; • todos os device drives e buffers de discos, bem como outras partes menores; • regula o delay loop (calcula o número BogoMips); • checa se a interrupção 16 está trabalhando com o coprocessador. Finalmente, o kernel está pronto para move_to_user_mode(); em seguida, fork (bifurca) o processo de inicialização, cujos códigos estão no mesmo arquivo fonte. E o processo número 0, também chamado idle task (tarefa preguiçosa), se mantém rodando em um loop infinito. O processo de inicialização tenta executar /etc/init, ou /bin/init, ou /sbin/init. Se nenhum deles tem sucesso, o código se desvia para /bin/sh /etc/rc e cria um root shell no primeiro terminal (console). Este código é remanescente do Linux 0.01, quando o S.O. era feito para um kernel stand‑alone e não havia processo de login. Depois de exec() o programa de inicialização de um dos lugares padrão (deve haver um deles), o kernel não tem controle direto sobre o fluxo do programa. Sua função, de agora em diante, é prover processos através de chamadas ao sistema (system calls), assim como prover eventos para serviços assíncronos (como uma interrupção do hardware). A multitarefa está inicializada e inicializará o gerenciamento de acesso a multiusuários através do fork() e processos de login. Estando o kernel carregado e provendo serviço, a sequência será verificar os system calls. 7.3 Gerenciamento de processos pelo kernel Do ponto de vista do kernel, um processo é uma entrada na tabela de processos. Nada mais. Assim, a tabela de processos é uma das mais importantes estruturas de dados no sistema, conjuntamente com a tabela de gerenciamento de memória e o buffer cache. O item individual na tabela de processos é a estrutura task_struct, definida em include/linux/sched.h. Com a task_struct, tanto informações de baixo quanto de alto nível são mantidas, variando da cópia de alguns registradores de hardware até o inode do diretório de trabalho para o processo. A tabela de processos é tanto um array quanto uma lista duplamente ligada, como uma árvore. A implementação física é um array estático de ponteiros, cujo tamanho é NR_TASKS, uma constante definida em include/linux/tasks.h, e cada estrutura reside em uma página de memória reservada. A 142 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV estrutura da lista está entre os ponteiros next_task e prev_task. A estrutura em árvore é um tanto complexa e não será descrita aqui. O programador pode desejar mudar NR_TASKS do seu valor default (que é 128), mas haverão dependências e será necessário recompilar todos os arquivos fonte envolvidos. Depois do boot, o kernel está sempre trabalhando em um dos processos, e a variável global current, um ponteiro para um item da task_struct, é usada para guardar o processo que está rodando. A variável current só é mudada pelo scheduler, em kernel/sched.c. Quando, porém, todos os processos necessitarem estar looked, a macro for_each_task é usada. Isto é, consideravelmente, mais rápido que uma procura sequencial no array. Um processo está sempre rodando em modo usuário ou em modo kernel. O corpo principal de um programa de usuário é executado em modo usuário e chamadas ao sistema são executadas em modo kernel. A pilha usada pelos processos nestes dois modos de execução é diferente – um seguimento de pilha convencional é usado para o modo usuário, enquanto uma pilha de tamanho fixo (uma página, cujo processo é dono) é usada no modo kernel. A página de pilha para o modo kernel nunca é swapped out, porque ela pode estar disponível sempre que um system call é introduzido. Chamadas a sistema (system calls), no kernel do Linux, são como funções da linguagem C. Seu nome oficial está prefixado por “sys_”. Uma chamada a sistema de nome, por exemplo, burnout invoca a função de kernel sys_burnout(). 7.3.1 Criando e destruindo processos Um sistema UNIX cria um processo através da chamada a sistema fork(), e o seu término é executado por exit(). Para eles, a implementação do Linux reside em kernel/fork.c e kernel/exit.c. Executar o forking é fácil, fork.c é curto e de fácil leitura. Sua principal tarefa é suprir a estrutura de dados para o novo processo. Passos relevantes nesse processo são: • criar uma página livre para dar suporte à task_struct; • encontrar um process slot livre (find_empty_process()); • criar uma outra página livre para o kernel_stack_page; • copiar a LTD do processo pai para o processo filho; • duplicar o mmap (memory map – memória virtual) do processo pai. A função sys_fork() também gerencia descritores de arquivos e inodes. A versão 1.0 do kernel possui algum vestígio de suporte ao threading (trabalho ou processo em paralelo), e a chamada a sistema fork() apresenta algumas alusões a ele. A morte de um processo é difícil, porque o processo pai necessita ser notificado sobre quaisquer filhos que existam (ou deixem de existir). Além disso, um processo pode ser morto (kill()) por outro 143 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA processo (isto é um aspecto do UNIX). O arquivo exit.c é, portanto, a casa do sys_kill() e de variados aspectos de sys_wait(), em acréscimo a sys_exit(). O código pertencente a exit.c não é descrito aqui – ele não é tão interessante. Ele trabalha com uma quantidade de detalhes para manter o sistema em um estado consistente. O POSIX standard, por conseguinte, é dependente de sinais (flags) e tinha que trabalhar com eles. 7.3.2 Executando processos Depois de executar o fork(), duas cópias do mesmo programa estão rodando. Uma delas usualmente executa – exec() – outro programa. A chamada a sistema exec() deve localizar a imagem binária do arquivo executável, carregá‑lo e executá‑lo. Carregá‑lo não significa, necessariamente, copiar na memória a imagem binária do arquivo, para que, assim, o Linux possa atender à demanda de programas a serem executados. A implementação Linux do exec() suporta formatos binários diferentes. Isto é dotado através da estrutura linux_binfmt, a qual embute dois ponteiros para funções – um paracarregar o executável e o outro para carregar a library associada. Cada formato binário deve conter, portanto, o executável e sua library. O sistema UNIX prove ao programador seis formas para a função exec(). Quase todos podem ser implementados como uma library de funções, e o kernel do Linux implementa sys_execve() independentemente das providas pelo UNIX. Ele executa uma única tarefa: carregar o cabeçalho do executável e tenta executá‑lo. Se os dois primeiros bytes são “#!”, então a primeira linha é ignorada e um interpretador é invocado; caso contrário, o formato binário, registrado, é executado sequencialmente. O formato nativo do Linux é suportado diretamente por fs/exec.c, e as funções relevantes são load_ aout_binary e load_aout_library. Assim como para os binários, a função de carregamento “a.out” é invocada, e a função mmap() (memory map – memória virtual ) aloca espaço em disco (no caso da memória real estar cheia) para o processo, ou invoca read_exec(), caso haja espaço em memória. A partir da versão 1.1 do kernel, o Linux embutiu um sistema de arquivos (filesystem) revisado do msdos, que suporta mmap(). Além disso, a estrutura linux_binfmt é uma “lista ligada”, e não um array, para permitir carregar um novo formato binário como um módulo do kernel. Finalmente, a estrutura, por si mesma, foi estendida para acessar rotinas com o formato relativo a core‑dump. Lembrete Pode‑se encontrar funções implementadas de formas diferentes em versões distintas do Linux, já que diferentes desenvolvedores as implementaram nas respectivas versões. Pode ocorrer também de uma determinada função existir em uma versão e não existir em outra. O usuário deve ficar atento a isso e verificar o que melhor lhe atende dentre as versões disponíveis. 144 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV 7.4 Sistema de arquivos 7.4.1 Conceitos fundamentais 7.4.1.1 Arquivos Conceitualmente, arquivos são mecanismos de abstração que fornecem uma maneira de armazenar e recuperar informações em disco. A característica mais importante de qualquer mecanismo de abstração é a forma de identificar os objetos com os quais o mecanismo trata. Quando um processo cria um arquivo, é preciso que tal arquivo receba um nome, normalmente dado pelo processo. Quando tal processo termina sua execução, o arquivo continua a existir, podendo ser acessado por outros processos, usando, para tanto, o nome atribuído ao arquivo. O Linux faz distinção entre nomes maiúsculos e minúsculos. Normalmente, um nome de arquivo é composto de nome e uma extensão, separada por ponto no Linux. O tamanho da extensão, se houver, fica a critério do usuário, e um arquivo pode até ter duas ou mais extensões, por exemplo: prog.c.Z. Não há limite de números de caracteres utilizados para dar nome a arquivos. O sistema operacional Linux olha o arquivo como uma sequência de byte, sem nenhuma estrutura, e isso dá uma flexibilidade espantosa ao sistema de arquivo. Os programas de usuários podem colocar o que desejarem nos arquivos e identificá‑los da forma que lhe for mais conveniente, o UNIX não influencia em nada neste processo de identificação. 7.4.1.2 Diretórios Para tratar dos arquivos, o sistema operacional normalmente lança mão dos diretórios. No caso do Linux, o diretório hierárquico, que pode ser visto na figura a seguir. Os diretórios são um tipo de arquivo. mozilla prof spoolItsp func loggtk bin dev etc lib home / mnt proc usr var aluno Figura 27 – Estrutura de diretórios 145 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA No Linux, todos os arquivos fazem parte de um diretório, assim eles são mantidos e organizados. Os diretórios são meios de oferecer endereços dos arquivos, de maneira que o sistema operacional possa acessá‑los rapidamente e facilmente. Ao entrar pela primeira vez em sua conta, o usuário estará em um subdiretório denominado entrada. Observação Uma das estruturas que é respeitada na grande maioria das versões disponíveis do Linux é a sua estrtura de arquivos e diretórios. O usuário pode contar com essa estrutura sem se preocupar com mudanças nesse sentido. 7.4.1.3 Co É uma senha que é aberta pelo administrador do sistema (denominado root), onde o usuário identifica‑se para o computador, que então dá acesso ao seu diretório de entrada, onde poderão ser executados os comandos permitidos à sua senha. Nos sistemas operacionais UNIX, a conta é obrigatória para todos, como pode ser visto a seguir no exemplo do código de abertura de conta no Linux. Saiba mais Assita ao filme: REVOLUTION OS. Dir. J. T. S. Moore. EUA: J. T. S. Moore, 2001. 85 min. O filme é um documentário que retrata a história de programadores de computadores e hackers que criaram o sistema operacional de código aberto Linux e como isso influenciou na evolução do movimento em favor do código livre. 7.4.1.4 Tipos de arquivos O Linux suporta arquivos regulares, de diretório, especiais de caracteres e especiais blocados. Os arquivos regulares são aqueles que contêm informações de usuários, por exemplos, tipo ASCII. Arquivos diretórios são arquivos usados na manutenção do sistema de arquivo. Arquivos especiais de caracteres estão diretamente ligados à entrada/saída e são usados para dispositivos seriais de entrada/saída, tais como terminais, impressoras e rede. Os arquivos especiais blocados são usados modelar dispositivos. No quadro a seguir são apontados os tipos de arquivos utilizados no Linux. 146 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Quadro 19 – Tipos de arquivos utilizados no Linux carvalho:/usr$ ls X11@ etc/ lib/ spool@ X11R6/ games/ local/ src/ X386@ i486‑linux/ man/ tclX/ adm@ i486‑linuxaout/ openwin/ tkX/ bin/ i486‑sesv4/ préerve@ tmp@ dict/ include/ sbin/ doc/ info/ share/ ftpusers mtools.conf sesog.conf carvalho:/usr$ 7.4.1.5 Acesso a arquivos O sistema operacional Linux, bem como os demais SO, trata o acesso a arquivos de forma randômica, ou seja, seus bytes ou registros podem ser lidos em qualquer ordem. 7.4.1.6 Atributos dos arquivos Cada arquivo tem necessariamente um nome e um conjunto dados. Além disso, o sistema operacional associa a cada arquivo algumas outras informações que serão chamadas de atributos de arquivos. O quadro a seguir mostra alguns dos atributos dos arquivos. Quadro 20 – Atributos de arquivos carvalho:/etc$ ls ‑l total 11 lrwxrwxrwx 1 root root 9 Dec 9 14:01 rmt ‑> /sbin/rmt* ‑rw‑r‑‑r‑‑ 1 root root 743 Jul 31 1994 rpc ‑rw‑r‑‑r‑‑ 1 root root 86 Jan 28 1994 securette ‑rw‑r‑‑r‑‑ 1 root root 21394 Dec 9 14:22 sendmail.000 ‑rw‑r‑‑r‑‑ 1 root root 23580 Jan 6 12:28 sendmail.cf drwxr‑xr‑x 2 root root 1024 Dec 9 13:59 skel/ ‑rw‑r‑‑r‑‑ 1 root root 314 Jan 9 1995 slip.hosts ‑rw‑r‑‑r‑‑ 1 root root 342 Jan 9 1995 slip.login lrwxrwxrwx 1 root root 13 Dec 9 13:59 utmp ‑> /var/og/utmp lrwxrwxrwx 1 root root 13 Dec 9 13:59 wtmp ‑> /var/og/wtmp ‑rw‑r‑‑r‑‑ 1 root root 76 Mae 8 1995 e p.conf.example 147 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA Como vimos no quadro anterior, o Sistema de Arquivo do Linux permiterestringir o acesso aos arquivos e diretórios, possibilitando que somente determinados usuários possam acessá‑los. A cada arquivo e diretório é associado um conjunto de permissões que determinam quais usuários podem ler, escrever ou alterar um arquivo, e no caso de arquivos executáveis, como programas, quais usuários podem executá‑lo. Se um usuário tem permissão de execução de um diretório, significa que ele pode realizar buscas dentro daquele diretório, e não executar como se fosse programa. A partir deste momento será explanada a codificação. É escolhido, aleatoriamente, o sétimo arquivo skel/ do quadro a seguir: Quadro 21 d r w x r ‑ x r ‑ x nome do arquivo 1 2 3 4 5 6 7 8 9 10 skel/ Obs: o que está em negrito, caixa maior, corresponde à posição do arquivo skel/ 1 – Informa o tipo de arquivo (d‑> diretório, l ‑> limk, – ‑> demais arquivo) 2 – Permissões do proprietário (r ‑> leitura, , – não permitida leitura) 3 – Permissões do proprietário (w ‑> escrita, – não permitida escrita) 4 – Permissões do proprietário (x ‑> execução, – não permitida execução) 5 – Permissões de grupo (r ‑> leitura, , – não permitida leitura) 6 – Permissões de grupo (w ‑> escrita, – não permitida escrita) 7 – Permissões de grupo (x ‑> execução, – não permitida execução) 8 – Permissões do sistema (r ‑> leitura, , – não permitida leitura) 9 – Permissões do sistema (w ‑> escrita, – não permitida escrita) 10 – Permissões do sistema (x ‑> execução, – não permitida execução) 7.4.2 Operações sobre arquivos Os arquivos existem para armazenar informações e permitir a sua recuperação. As chamadas de sistemas mais comum relacionadas ao sistema de arquivo Linux são chamadas que operam sobre arquivos individuais ou envolvendo diretórios e sistema de arquivos como um todo. A chamada CREAT não só cria um arquivo, mas também abre este arquivo para escrita, independentemente do modo de proteção especificado para ele. O descritor de arquivo que a chama retorna fd e pode ser usado para escrever no arquivo. Se a chamada CREAT for executada sobre um arquivo existente, este arquivo será truncado para o comprimento 0, desde que os direitos dos arquivos assim o permitam. Para que um arquivo existente possa ser lido ou escrito, é necessário que ele seja primeiramente aberto e se ele está aberto para leitura, escrita ou para ambas as operações. Várias opções podem ser especificadas. O descritor de arquivo que a chamada retorna pode então ser usado para leitura ou escrita. Posteriormente, o arquivo deve ser fechado através da chamada CLOSE, cuja execução torna o descritor de arquivo disponível para ser novamente utilizado numa chamada CREAT ou OPEN subsequente. 148 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV A chamada READ é utilizada para ler o arquivo. Os bytes lidos vêm em posição corrente de leitura. O processo que faz a chamada deve indicar a quantidade de informação a ser lida e providenciar um buffer para possibilitar a leitura. Na chamada WRITE, os dados são escritos no arquivo, geralmente a partir da posição corrente. Se tal posição for a de final de arquivo, o tamanho dele cresce. Se a posição corrente no momento da escrita estiver no meio do arquivo, os dados existentes nesta posição estarão perdidos para sempre, pois a operação de write escreve os novos dados em cima dos antigos. Apesar da maioria dos programas ler e escrever arquivos sequencialmente, em algumas aplicações os programas devem ser capazes de acessar randomicamente qualquer parte do arquivo. Associado a cada arquivo existe um ponteiro que indica a posição corrente do arquivo. Quando a leitura ou escrita for sequencial, em geral, ele aponta para o próximo byte a ser lido ou a ser escrito. A chamada LSEEK tem três parâmetros: o primeiro do descritor de área para o arquivo; o segundo é a posição do arquivo; e o terceiro informa se a posição é relativa ao início do arquivo, à posição corrente ou final do arquivo. O valor que o LSEEK retorna é a posição absoluta no arquivo após a mudança no ponteiro. Para cada arquivo o Linux mantém o modo do arquivo (regular, diretório ou arquivo especial), seu tamanho, o instante da última modificação e outras informações pertinentes. Os programas podem verificar essas informações usando a chamada stat. Seu primeiro parâmetro é o nome do arquivo. O segundo é um ponteiro para a estrutura onde a informação solicitada deve ser colocada. As chamadas do sistema devem ser relacionadas com os diretórios ou com o sistema de arquivo como um todo, em vez de um arquivo específico. Os diretórios são criados utilizando as chamadas MKDIR e RMDIR, respectivamente. Um diretório pode ser removido se estiver vazio. A ligação de um arquivo cria uma nova entrada no diretório que aponta para um arquivo existente. A chamada LINK cria esta ligação. Os seus parâmetros especificam os nomes originais e novo, respectivamente. As entradas dos diretórios são removidas via UNLINK. Quando a última ligação para um arquivo é removida, é automaticamente apagada. Para um arquivo que nunca foi ligado, o primeiro UNLINK faz com que ele desapareça. A função CHDIR permite a alteração do diretório corrente de execução para um outro devidamente especificado. A função CHMOD permite a alteração do nível de operação de um determinado arquivo ou diretório alterando por exemplo do nível de permissão de somente leitura para permissão de escrita, ou seja, o comando realiza a mudança dos bits de proteção. Temos que nos atentar ao fato que somente usuários com permissão podem realizar esse tipo de mudança. 149 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA 7.4.2.1 Arquivos compartilhados Quando vários usuários estão trabalhando juntos em um projeto, eles comumente precisam compartilhar arquivos. Em decorrência disso, muitas vezes é conveniente que um arquivo compartilhado apareça simultaneamente em diretórios diferentes que pertençam a diferentes usuários. A conexão entre um diretório e um arquivo compartilhado é chamada de ligação (link). O próprio sistema de arquivo é um gráfico acíclico dirigido, ou dag, em vez de árvore. No Linux, os blocos do disco não são listados no diretório, mas numa estrutura de dados associada ao próprio arquivo. Esta estrutura é chamada nó‑i, sendo a forma como o Linux implementa o compartilhamento do arquivo. Principais comandos do sistema UNIX Comandos em UNIX possuem algumas características particulares. Eles podem ser controlados por opções e devem ser digitados em letras minúsculas. • cat: oficialmente usado para concatenar arquivos. Também é utilizado para exibir todo o conteúdo de um arquivo de uma só vez, sem pausa. Sintaxe: cat < arquivo1 > < arquivo2 >... < arquivo n >, onde (arquivo1) até (arquivo n) são os arquivos a serem mostrados. O cat lê cada arquivo em sequência e exibe‑o na saída padrão. Desse modo, a linha de comando: cat < arquivo > exibirá o arquivo em seu terminal e a linha de comando concatenará arquivo1 e arquivo2 e escreverá o resultado na tela do sistema. O símbolo “>”, usado para redirecionar a saída para um arquivo, tem caráter destrutivo; em outras palavras, o comando anteriormente descrito escreverá por cima do conteúdo doe < arquivo3 >. Se, ao invés disso, você redirecionar com o símbolo “>>”, a saída será adicionada a <arquivo3 >, ao invés de escrever por cima de seu conteúdo. • cd: muda o diretório de trabalho corrente. Sintaxe : cd <diretório> Onde (diretório) é o nome do diretório para o qual você deseja mudar. O símbolo (.) refere‑se ao diretório corrente e o símbolo (..) refere‑se ao diretório pai. Para mover para um diretório pai, ou seja, um diretório acimado que você está, use o comando: cd .. (note o espaço entre “cd” e “..” ) 150 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Você também pode usar nomes de caminho (pathnames) como argumento para o comando cd. Por exemplo: cd /diretorio1/diretorio2 o posicionará diretamente em “diretório2”. O uso de “cd” sem nenhum argumento fará com que você retorne para o seu home‑directory. • chgrp: modifica o grupo de um arquivo ou diretório. Sintaxe: chgrp [‑f] [‑h] [‑R] gid nome‑do‑arquivo O chgrp modifica o identificador de grupo (“group ID” , gid) dos arquivos passados como argumentos. O gid pode ser um número decimal especificando o group id, ou um nome de grupo encontrado no arquivo /etc/group. Você deve ser o proprietário do arquivo, ou o superusuário, para que possa utilizar este comando. Opções: Saída ‑f Esta opção não reporta erros ‑h Se o arquivo for um link simbólico, esta opção modifica o grupo do link simbólico. Sem ela, o grupo do arquivo referenciado pelo link simbólico é modificado. ‑ R Esta opção é recursiva. O chgrp percorre o diretório e os subdiretórios, modificando o GID à medida em que prossegue. • chmod: modifica as permissões de um arquivo ou diretório. Você deve ser o proprietário de um arquivo ou diretório, ou ter acesso ao root, para modificar as suas permissões. Sintaxe: chmod permissões nome_do_arquivo onde: permissões – indica as permissões a serem modificadas; 151 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA nome – indica o nome do arquivo ou diretório cujas permissões serão afetadas. As permissões podem ser especificadas de várias maneiras. Aqui está uma das formas mais simples de realizarmos esta operação: • use uma ou mais letras indicando os usuários envolvidos: — . u (para o usuário); — . g (para o grupo); — . o (para “outros”); — . a (para todas as categorias). • indique se as permissões serão adicionadas (+) ou removidas (‑); • use uma ou mais letras indicando as permissões envolvidas: — . r (para “read”) (ler); — . w (para “write”) (escrever); — . x (para “execute”) (executar). No exemplo a seguir, a permissão de escrita (“write”) é adicionada ao diretório dir1 para usuários pertencentes ao mesmo grupo (portanto, o argumento permissões é g+w e o argumento nome é dir1). $ ls ‑l dir1 drwxr‑xr‑x 3 dir1 1024 Feb 10 11:15 dir1 $ chmod g+w dir1 $ ls ‑l drwxrwxr‑x 3 dir1 1024 Feb 10 11:17 dir1 $ Como você pôde verificar, o hífen (‑) no conjunto de caracteres para grupo foi modificado para w como resultado deste comando. 152 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Quando você cria um novo arquivo ou diretório, o sistema associa permissões automaticamente. Geralmente, a configuração default (assumida) para os novos arquivos é: ‑ r w – r – ‑ r – ‑ e para novos diretórios é: d r w x r – x r – x • chown: modifica o proprietário de um arquivo ou diretório. Sintaxe: chown [‑fhR] (proprietário) (nome‑do‑arquivo) O argumento proprietário especifica o novo proprietário do arquivo. Este argumento deve ser ou um número decimal especificando o userid do usuário ou um login name encontrado no arquivo /etc/passwd. Somente o proprietário do arquivo (ou o superusuário) pode modificar o proprietário deste arquivo. Opções Saída ‑ f Esta opção não reporta erros. ‑ h Se o arquivo for um link simbólico, esta opção modifica o proprietário do link simbólico. Sem essa opção, o proprietário do arquivo referenciado pelo link simbólico é modificado. ‑ R Esta opção é recursiva. O chown percorre o diretório e os subdiretórios, modificando as propriedades à medida em que prossegue. • cp: copia arquivos para um outro arquivo ou diretório. Sintaxe: cp (arquivo1) (arquivo2) ... (arquivo n) (destino) Onde (arquivo1) até (arquivo n) são os arquivos a serem copiados e (destino) é o arquivo ou o diretório para onde os arquivos serão copiados. O(s) arquivo(s) fonte(s) e o (destino) não podem ter o mesmo nome. Se o arquivo‑destino não existe, cp criará um arquivo com o nome especificado no 153 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA caminho especificado. Se o arquivo‑destino já existia antes e não for um diretório, cp escreverá o novo conteúdo por cima do antigo. Exemplo: $ cp ‑r temp temp1 Este comando copia todos os arquivos e subdiretórios dentro do diretório temp para um novo diretório temp1. Esta é uma cópia recursiva, como designado pela opção ‑r. Se você tentar copiar um diretório sem utilizar está opção, verá uma mensagem de erro. • du: exibe o espaço ocupado de um diretório e de todos os seus subdiretórios, em blocos de 512 bytes; isto é, unidades de 512 bytes ou caracteres. O du mostra a utilização do disco em cada subdiretório. • date: exibe a data configurada no sistema. O comando date, em nível de usuário, exibe na tela a data configurada no sistema. Ele pode ser usado com opções que mostram a data local ou data universal GMT – Greenwich Mean Time. A configuração dos dados deste comando só pode ser realizada pelo superusuário. Para exibir a data local, basta executar date. Caso queira a data GMT, utilize a opção ‑u. Veja: %date Wed Jan 8 12:05:57 EDT 1997 Aqui a data é exibida em seis campos que representam o dia da semana abreviado, o mês do ano abreviado, o dia do mês, a hora disposta em horas/minutos/segundos, a zona horária e o ano. • file: exibe o tipo de um arquivo. Alguns arquivos, tais como os binários e executáveis, não podem ser visualizados na tela. O comando file pode ser útil se não há certeza sobre o tipo do arquivo. O uso do comando permitirá a visualização do tipo do arquivo. Exemplo: $file copyfile copyfile: ascii text • grep: exibe todas as linhas dos arquivos especificados, que contém um certo padrão. O comando grep exibe todas as linhas dos arquivos nomeados que são iguais ao padrão especificado. 154 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Sintaxe: grep [padrão] <arquivo_1> <arquivo_2> ... <arquivo_n> onde [padrão] é uma expressão regular e arquivo_1 até arquivo_n são os arquivos nos quais a procura será feita. Por exemplo, o comando grep trabalho /trabalho/unix/grep.html mostrará todas as linhas no arquivo /trabalho/unix/grep.html que contém o padrão trabalho. • 11 – ls: exibe informações sobre arquivos nomeados e diretórios. É usado para visualizar o conteúdo de um diretório. Sintaxe: ls (diretório)[opções] Quando executado sem qualquer parâmetro, mostra o conteúdo do diretório corrente. Assim, a linha de comando: $ ls mostra o conteúdo do diretório corrente naquele momento. Como na maioria dos comandos UNIX, ls pode ser controlado por opções que começam com um hífen (‑). Deve se ter sempre o cuidado de deixar um espaço antes do hífen. Uma opção bastante útil é ‑a (que vem do inglês all, que quer dizer tudo), que irá mostrar detalhes que você nunca imaginou sobre o seu diretório. Por exemplo: $ cd $ ls ‑a Ao digitar estes comandos em sequência, o sistema vai para o seu home directory através do comando cd e, em seguida, mostra o conteúdo do mesmo, que será exibido da seguinte forma: . .bacshrc .fvwmrc .. .emacs.xinitrc .bash_history .exrc Aqui, o ponto simples refere‑se ao diretório corrente, e o ponto duplo refere‑se ao diretório imediatamente acima dele. Mas o que são estes outros arquivos que se iniciam com um ponto? Eles 155 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA são chamados arquivos escondidos. A colocação do ponto na frente de seus nomes os impede de serem mostrados durante um comando ls normal. Outra opção bastante utilizada é ‑l (que vem do inglês long). Ela mosta informação extra sobre os arquivos. Assim, o comando: $ ls ‑l exibe, além do conteúdo do diretório, todos os detalhes sobre cada arquivo pertencente a ele. Por exemplo, suponha que você tenha executado este comando e na tela apareceu algo assim: ‑rw‑r‑‑r‑‑ 1 xyz users 2321 Mar 15 1994 Fontmap ‑rw‑r‑‑r‑‑ 1 xyz users 14567 Feb 3 1995 file003 drwxr‑xr‑x 2 xyz users 1024 Apr 23 1995 Programs drwxr‑xr‑x 3 xyz users 1024 Apr 30 1995 bitmaps Lendo da esquerda para direita, este primeiro caractere indica se o arquivo é um diretório (d) ou um arquivo comum (‑). Em seguida, tem‑se as permissões de acesso ao arquivo, sendo as três primeiras referentes ao proprietário, as seguintes ao grupo e, por último, aos demais usuários. A segunda coluna desta listagem mostra o número de links que o arquivo possui. A terceira coluna mostra o proprietário do referido arquivo; neste caso, o usuário cujo user name é xyz. Na próxima coluna é mostrado o grupo ao qual pertence o proprietário do arquivo (no exemplo, temos o grupo users). Na quinta coluna temos o tamanho do arquivo em bytes. Por fim, na sexta e sétima colunas, temos a data da última modificação feita no arquivo e o nome do mesmo, respectivamente. Vale lembrar que várias opções podem ser usadas de forma composta. Por exemplo, podemos executar o comando: $ ls ‑la e este mostrará todos os detalhes que as opções ‑l e ‑a dispõem. • man: exibe uma página do manual interno do UNIX para um dado comando ou ou recurso (isto é, qualquer utilitário do sistema que não seja comando, por exemplo, uma função de biblioteca). É como um help interno ao sistema. 156 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Sintaxe: man <comando> Onde comando é o nome do comando ou recurso que se deseja obter a ajuda. • mkdir: cria usado para a criação de novos diretórios. Sintaxe: mkdir (diretório 1) (diretório 2) ...(diretório n) Onde (diretório 1) até (diretório n) são os diretórios a serem criados. As entradas padrão em um diretório (por exemplo, os arquivos (.), para o próprio diretório, e (..) para o diretório pai) são criadas automaticamente. A criação de um diretório requer permissão de escrita no diretório pai. O identificador de proprietário (owner id), e o identificador de grupo (group id) dos novos diretórios são configurados para os identificadores de proprietário e de grupo do usuário efetivo, respectivamente. * Opções: ‑m (mode) Esta opção permite aos usuários especificar o modo a ser usado para os novos diretórios. ‑p Com esta opção, mkdir cria o nome do diretório através da criação de todos os diretórios pai não existentes primeiro. Exemplo: mkdir ‑p diretório 1/diretório 2/diretório 3 Cria a estrutura de subdiretórios diretório 1/diretório 2/diretório 3. • more: exibe o conteúdo de arquivos nomeados, fazendo pausas a cada tela cheia. Ele exibe um arquivo, uma tela cheia de cada vez, fazendo normalmente uma pausa após cada tela cheia, quando exibe ‑‑More‑‑ na parte de baixo da tela. Ao teclar‑se (Enter), more irá exibir uma linha a mais; ele mostrará outra tela cheia ao teclar‑se o caractere espaço. O caractere b faz com que more exiba a tela anterior. O caractere q provoca a parada de execução do comando more. 157 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA Sintaxe: more (arquivo 1) (arquivo 2) ... (arquivo n) Onde (arquivo 1) até (arquivo n) são os arquivos a serem exibidos. Pode‑se procurar por uma palavra (ou uma cadeia de caracteres) em um arquivo. Para isso, pressione o caracter “/”, digite a palavra (ou a cadeia de caracteres) e tecle (Enter). * Opções: ‑c Limpa a tela antes de exibir o conteúdo do arquivo. Esta opção é ignorada se o terminal não tem a habilidade para limpar até o final de uma linha. • mv: move arquivos para um outro arquivo ou diretório. O comando mv é utilizado para mover arquivo(s) para outro arquivo ou diretório. Este comando faz o equivalente a uma cópia seguida pela eliminação do arquivo original. Pode ser usado para renomear arquivos. Sintaxe: mv (arquivo 1) (arquivo 2) ... (arquivo n) (destino) Onde (arquivo 1) até (arquivo n) são os arquivos a serem movidos, e (destino) é o arquivo ou o diretório para onde os arquivos serão movidos. Se (destino) não for um diretório, somente um arquivo deverá ser especificado como fonte. Se for um diretório, mais de um arquivo poderá ser especificado. Se (destino) não existir, mv criará um arquivo com o nome especificado. Se (destino) existir e não for um diretório, seu conteúdo será apagado e o novo conteúdo será escrito no lugar do antigo. Se (destino) for um diretório, o(s) arquivo(s) será(ão) movido(s) para este diretório. Os arquivos fonte e destino não precisam compartilhar o mesmo diretório pai. *Opções: ‑i Com esta opção, mv irá perguntar a você se é permitido escrever por cima do conteúdo de um arquivo destino existente. Uma resposta y (yes = sim) significa que a operação poderá ser executada. Qualquer outra resposta impedirá que mv escreva por cima do conteúdo de um arquivo já existente. Por exemplo: 158 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Exemplo: $ pwd /home/usuário1/temp $ ls teste $ mv teste ../temp1 $ ls ../temp1 teste Neste exemplo, o diretório teste foi movido de temp para temp1 com o comando mv. • passwd: modifica a senha pessoal. Para garantir a segurança do sistema, o sistema UNIX requer o uso de uma senha. Se você achar que alguém utilizou sua conta sem permissão, mude sua senha imediatamente. Algumas dicas para a escolha da senha: • escolha uma senha que você possa se lembrar sem a necessidade de escrever; • o seu password deve ter ao menos seis caracteres e deve conter pelo menos um número; • não use seu próprio nome ou suas iniciais; • não use nomes de animais ou objetos relacionados ao seu interesse; • se você tem mais de uma conta, não use a mesma senha para todas elas. O comando passwd é utilizado para modificar a senha pessoal. A seguir estão os passos que acontecem quando passwd é utilizado: $ passwd Changing password for (nome‑do‑usuário) Old password: New password: Retype new password: $ • Quando o sistema pedir Old Password:, digite sua senha atual. Se nenhuma senha estiver associada à sua conta, o sistema irá omitir este prompt. Note que o sistema não mostra a senha que você digita na tela. Isto previne que outros usuários a descubram sua senha. 159 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA • Quando o sistema pedir New Password:, digite sua nova senha. • O último prompt, Retype new password, pede que você digite a nova senha novamente. Se você não digitar a senha da mesma maneira que digitou da primeira vez, o sistema se recusaa modificar a senha e exibe a mensagem Sorry. • pwd: exibe o diretório corrente. Este comando é utilizado para exibir o seu diretório corrente no sistema de arquivos. • rm: este comando é utilizado para apagar arquivos. É importante lembrar que, no sistema UNIX, quando os arquivos são apagados, é impossível recuperá‑los. Sintaxe: rm (arquivo 1) (arquivo 2) ... (arquivo n) onde (arquivo 1) até (arquivo n) são os arquivos a serem apagados. Se um arquivo não possuir permissão de escrita e a saída‑padrão for um terminal, todo o conjunto de permissões do arquivo será exibido, seguido por um ponto de interrogação. É um pedido de confirmação. Se a resposta começar com y (yes = sim), o arquivo será apagado; caso contrário, ele será mantido no sistema. Quando se apaga um arquivo com o comando rm, apaga‑se somente um link (ligação ou entrada) para um arquivo. Um arquivo somente será apagado verdadeiramente do sistema quando ele não possuir mais nenhuma ligação para ele, isto é, nenhum link referenciando‑o. Geralmente, arquivos possuem somente um link, portanto, o uso do comando rm irá apagar o(s) arquivo(s). No entanto, se um arquivo possuir muitos links, o uso de rm irá apagar somente uma ligação; neste caso, para apagar o arquivo, é necessário que você apague todos os links para este arquivo. O número de links que um arquivo possui pode ser verificado utilizando o comando ls, com a opção ‑l. *Opções: ‑f Remove todos os arquivos (mesmo se estiverem com proteção de escrita) em um diretório sem pedir confirmação do usuário. ‑i Esta opção pedirá uma confirmação do usuário antes de apagar o(s) arquivo(s) especificado(s). 160 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV ‑r Opção recursiva para remover um diretório e todo o seu conteúdo, incluindo quaisquer subdiretórios e seus arquivos. É necessário tomar cuidado, pois diretórios e seus conteúdos removidos com o comando rm ‑r não podem ser recuperados. • rmdir: é utilizado para apagar diretórios vazios. Sintaxe: rmdir (diretório 1) (diretório 2) ... (diretório n) onde (diretório 1) até (diretório n) são os diretórios a serem apagados. O comando rmdir se recusa a apagar um diretório inexistente, exibindo a mensagem: rmdir: (nome‑do‑diretório) : No such file or directory Quando usar rmdir, lembre‑se que o seu diretório de trabalho corrente não pode estar contido no(s) diretório(s) a ser(em) apagado(s). Se você tentar remover seu próprio diretório corrente, será exibida a seguinte mensagem: rmdir: . : Operation not permited Se o diretório a ser removido não estiver vazio, utilize o comando cd para acessar os arquivos dentro do diretório e então remova estes arquivos utilizando o comando rm. Opções: ‑p Permite aos usuários remover o diretório e seu diretório pai, o qual se torna vazio. Uma mensagem será exibida na saída padrão informando se o caminho (path) inteiro foi removido ou se parte do caminho persiste por algum motivo. É necessário tomar cuidado, pois diretórios removidos com o comando rmdir não podem ser recuperados. • touch: atualiza o último tempo de acesso e/ou modificação de um arquivo. Um arquivo vazio será criado se o nome especificado ainda não existir. Sintaxe: touch [opcões] [mmddhhMM[yy]] nome‑do‑arquivo 161 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA sendo: mm mês dd dia hh hora MM minuto yy ano (últimos dois dígitos) Se não for especificada nenhuma data, a data atual será utilizada. Opções: ‑a Atualiza somente o tempo de acesso respectivo. ‑m Atualiza somente o tempo de modificação. ‑c Previne a criação de um arquivo se ele não existia anteriormente. As opções default são : ‑am. 7.5 Introdução ao script shell do Linux 7.5.1 Script e script shell O shell é um interpretador de comandos que possui uma linguagem utilizada por diversas pessoas para facilitar a realização de inúmeras tarefas administrativas no Linux (como efetuar backup regularmente, procurar textos, criar formatações), e até mesmo para criar programas um pouco mais elaborados. A linguagem shell é interpretada, não havendo necessidade de compilar para gerar um arquivo executável. Um script shell, ou simplesmente script, é um arquivo contendo uma sequência de um ou mais comandos. Este arquivo é diretamente executável quando chamado pelo nome. 162 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV O shell foi escrito em diferentes versões. Dos vários programas shell existentes, o Bourne Shell, o Korn Shell e o C Shell se destacam por serem os mais utilizados e conhecidos. O Bourne Shell é conhecido como Shell padrão, sendo o mais utilizado e estando na maioria dos sistemas UNIX like. O Korn Shell é uma versão melhorada do Bourne Shell. O C Shell possui uma estrutura bastante parecida com a linguagem C e é também uma versão modificada do Bourne Shell. Além desses, há um shell padrão do Linux, chamado Bourne‑Again Shell. Este pode ser considerado o mais completo, sendo compatível com todos os shells citados anteriormente. Mas qualquer programador pode fazer o seu shell. Estes shells tornaram‑se conhecidos, pois já vinham com o sistema, exceto o Korn, que tinha que ser adquirido separadamente. O Bourne Shell vinha com o System V e o C Shell com o BSD. Algumas características: Shell Prompt Representação Bourn Shell ‑> $ sh Bourn‑Again Shell ‑> $ bash Korn Shell ‑> $ ksh C Shell ‑> % csh 7.5.2 Execução de programas Um programa pode ser escrito em um editor de sua preferência como vi, kWrite, KEdit entre outros. O arquivo é salvo como texto comum. No ínicio do arquivo deve vir escrito: #!/bin/bash Os caracteres especiais #! (denominados hash‑bang) informam ao kernel que o próximo argumento é o programa utilizado para executar este arquivo. No caso, /bin/bash é o shell que utilizamos. O kernel lê o hash‑bang no início da linha, então ele continua lendo os caracteres seguintes e inicia o bash. Quando o shell lê o hash‑bang, ele o interpreta como uma linha de comentário e a ignora, iniciando a execução do programa. É preciso mudar a permissão do arquivo para executável para ele funcionar. Isso é feito pelo comando chmod. Para que o programa seja executável de qualquer parte do sistema, é necessário salvá‑lo em 163 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA algum diretório que esteja no PATH (variável do sistema que contém a lista de diretórios onde o shell procura pelo comando digitado). Entretanto, é permitido salvá‑lo em um diretório qualquer (como o diretório home do usuário), porém na hora de executá‑lo pelo prompt, é necessário que seja indicado todo o caminho desde a raiz ou, estando no mesmo diretório do arquivo, digitar no prompt: ./nomearquivo. Também é possível modicar o PATH para incluir um diretório de sua escolha. Por exemplo: vamos supôr que o usuário criou uma pasta em seu diretório para salvar seus scripts com o nome de scripts. Para tornar esse diretório como parte do PATH, faça o seguinte: Digite no prompt: $ echo $PATH Esse é seu PATH atual. Em seguida digite: $ PATH=$HOME/scripts:$PATH e $ echo $PATH Esse é seu novo PATH, com seu diretório de exemplos incluído. Agora seus scripts podem ser executados de qualquer diretório. Porém, dessa forma, a mudança da variável PATH só vale enquanto o shell corrente estiver aberto. Se for aberto outro shell, a mudança não terá efeito.Existem arquivos que são inicializados assim que o shell é aberto: /etc/profile : Tem as confgurações básicas do sistema e vale para todos os usuários. Somente o root tem permissão para modicar esse arquivo. .bash_profile ou .bash_login ou .profile ou .bashrc : Estes arquivos ficam no diretório home do usuário. As modifcações feitas nesse arquivo só valem para o próprio usuário. Podemos, então, abrir o arquivo .bashrc e colocar nele o novo PATH. Além disso, podemos incluir também aliases. Por exemplo: se tivéssemos um diretório chamado scripts e quiséssemos colocá‑lo no PATH, bastaria acrescentar a linha abaixo ao arquivo .bashrc. Também foram colocados alguns aliases. PATH=$PATH:~/scripts alias c=’clear’ alias montar=’mount /dev/fd0’ A seguir, um exemplo passo a passo para criar e executar um programa. Escreva em seu editor de texto o programa na sequência e salve como um.sh. #!/bin/bash echo “Programa UM!” 164 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Agora, no prompt, mude as permissões do arquivo. $ chmod a+x um.sh Então é só chamar o programa no prompt. $ sh um.sh Neste caso, o arquivo estava no mesmo diretório de trabalho. E se o arquivo estivesse em um diretório diferente? Lembre‑se de mudar o PATH! Saiba mais Segue referência bibliográfica para consulta a aplicações de shell no sistema operacional Linux: NEVES, J. C. Programação shell linux. 7. ed. São Paulo: Brasport, 2008. 7.5.2.1 Impressão na tela O comando echo permite mostrar na tela seus argumentos. Exemplo: $echo Escrevendo seu argumento Escrevendo seu argumento Existem caracteres especiais que são interpretados pelo comando echo. Em algumas versões do Linux deve ser usado o parâmetro opcional ‑e. Esta opção habilita a interpretação dos caracteres de escape listados a seguir. \\ – Barra invertida (backslash). \nnn – Escreve o caracter cujo octal é nnn. \xHH – Escreve o caractere cujo hexadecimal é HH. \a – Caractere de alerta sonoro (beep). \b – Backspace. 165 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA \c – Suprime newline, forçando a continuação na mesma linha. \f – Alimentação de formulário. \n – Inicia uma nova linha. \r – Carriege return. Retorna ao início da linha. \t – Equivale a um espaço de tabulação horizontal. \v – Equivale a um espaço de tabulação vertical. Exemplo: $ echo ‑e “Este exemplo mostra o uso de alguns dos caracteres mostrados: > Começando pela contra‑barra \\ > Caracter hexadecimal \100 > Usando backspace\b > iniciando \n nova linha > apagando o que foi \r escrito anteriormente na linha > e tabulando \t horizontalmente e \v verticalmente.” Este exemplo mostra o uso de alguns dos caracteres mostrados: Começando pela contra‑barra \ Caractere hexadecimal @ Usando backspace Iniciando nova linha escrito anteriormente na linha e tabulando horizontalmente e verticalmente. Para saber a representação octal e hexadecinal correspondente ao caracter desejado, consulte a tabela ASCII no manual: man ascii. Quando o usuário não desejar que a saída do comando echo pule de linha, deve usar a opção ‑n. 166 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV 7.6 Manipulação de variáveis Variável é uma posição nomeada de memória, usada para guardar dados que podem ser manipulados pelo programa. Em shell não é necessário declarar a variável como em outras linguagens de programação. 7.6.1 Palavras reservadas Palavras reservadas são aquelas que possuem um significado especial para o shell. O shell possui comandos próprios (intrínsecos) como: ! case do done elif else esac fi for function if in select then until while { } time [[ ]] Além disso, o UNIX possui outros comandos, vistos nos capítulos anteriores. Em programação, geralmente trabalhamos com manipulação de variáveis. Dessa forma, é importante lembrar que o uso dessas palavras deve ser evitado, tanto no nome dado às variáveis quanto no nome dado ao script. 7.6.2 Criação de variáveis Uma variável é criada da seguinte forma: $ nomevar=valor Uma variável é reconhecida pelo shell quando vem precedida pelo símbolo $. Quando este símbolo é encontrado, o shell substitui a variável pelo seu conteúdo. O nome da variável é nomevar e valor é o conteúdo que será atribuído à variável. É importante assegurar que não haja espaço antes e depois do sinal “=” para evitar possíveis erros de interpretação. No exemplo anterior foi criada uma variável local. Para criar uma variável global, é usado o comando export $ export nomevar ou $ export nomevar=valor Por exemplo: será atribuído um valor à variável chamada var e, em seguida, este valor será mostrado pelo comando echo. $ var=Pensamento $ echo “O conteúdo é o $var” O conteúdo é o pensamento Vale lembrar algumas regras para a nomenclatura de variáveis que se aplicam às linguagens de programação: 167 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA • o nome da variável só pode começar com letras ou underline; • são permitidos caracteres alfanuméricos; • não devem haver espaços em branco nem acentos. A seguir, veja o uso de aspas simples, duplas e crases com variáveis: $ variavel=”Meu login é: $user” $ echo $variavel Meu login é: ze $ variavel=’Meu hostname é: $HOSTNAME’ $ echo $variavel Meu hostname é: $HOSTNAME $ variavel=”O diretorio de trabalho é: ‘pwd’” $ echo $variavel O diretório de trabalho é: /home/ze Quando vamos executar um script ou comando, um outro shell é chamado, executa os comandos e então retorna ao shell original onde foi feita a chamada. Por isso é importante lembrar de exportar suas variáveis para que elas sejam reconhecidas pelo shell filho. Exemplo: $ cat dir.sh #!/bin/bash echo “Veja que o diretório vai mudar” echo “Inicialmente o diretório era: $PWD” # neste ponto o diretorio mudou cd /usr/bin echo “Agora o diretório atual é $PWD” echo “Mas terminado o programa parece que nada aconteceu. O diretório continua sendo o inicial.” $ sh dir.sh Veja que o diretório vai mudar: Inicialmente, o diretório era: /home/kurumin/scripts Agora, o diretório atual é /usr/bin No entanto, terminado o programa, parece que nada aconteceu. 168 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV O diretório continua sendo o inicial. $ 7.7 Controle de fluxo Para as linguagens de programação, uma das mais importantes estruturas é o controle de fluxo. Com o shell não é diferente. Com ele, a execução do programa pode ser alterada de forma que diferentes comandos podem ser executados ou ter sua ordem alterada de acordo com as decisões tomadas. São realizados saltos, desvios ou repetições. Nas próximas seções serão explicadas cada tipo de estrutura. 7.7.1 Decisão simples A estrutura de decisão simples é aquela que realiza desvios no fluxo de controle, tomando como base o teste de uma condição dada, uma opção entre duas que podem ser escolhidas. Uma decisão simples é uma construção com os comandos if/then. Isso representa se condição então realiza determinado comando. Sintaxe: if[expressão]; then comando fi Este programa bem simples mostra o uso do if. Há um arquivo chamado livro.txt, cujo conteúdo está a seguir: #LIVRO #EXEMPLARES ########################### eletromagnetismo 5 redes 4 cálculo8 física 6 eletrônica 7 169 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA O programa na sequência mostra o número de exemplares de um determinado assunto. Mas, primeiro, é verificado se o livro está na lista. #!/bin/bash echo ‑n “Qual livro você deseja?” read Livro if grep $Livro livro.txt>>/dev/null then echo “O livro $Livro possui ‘grep $Livro livro.txt|cut ‑f2’ exemplares.” else echo “Este livro não está na lista” fi O diretório /dev/null é um lugar para onde redirecionamos a saída de um comando quando não é desejável que ela apareça no prompt. 7.7.2 Decisão múltipla Este tipo de estrutura engloba, além dos comandos vistos anteriormente, os comandos elif e else. Neste caso, se a condição dada não for satisfeita, há outro caminho a ser seguido, dado pelo elif, que seria a combinação de else com if (senão se...). A diferença entre o uso de elif e else if é que, se fosse usado o último, seria necessário usar o fi. Sintaxe: if [expressão]; then comando elif [expressão]; then comando elif [expressão]; then comando ... else comando fi 7.7.3 O comando case Outra forma de fazer desvios múltiplos é pelo uso do comando case. Ele é semelhante ao if, pois representa a tomada de decisão, mas permite múltiplas opções. Esta estrutura é bastante usada quando é necessário testar um valor em relação a outros valores preestabelecidos, onde cada um desses valores tem um bloco de comando associado. O exemplo a seguir dá o estado de acordo com o DDD digitado. echo “Insira o código DDD: “ read cod case $cod in 170 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV 21) echo “Rio de Janeiro”;; 11) echo “São Paulo”;; 3[0‑8]) echo “Minas Gerais”;; *) Echo “Insira outro código”;; esac Decisão com && e ||. Esses caracteres permitem a tomada de decisões de uma forma mais reduzida. Sintaxe: comando1 && comando2 comando1 || comando2 O && faz com que o comando2 só seja executado se comando1 retornar 0, ou seja, se comando1 retornar verdadeiro, o comando2 é executado para testar se a condição toda é verdadeira. O || executa o comando2 somente se o comando1 retornar um valor diferente de 0, ou seja, somente se o comando1 retornar falso é que comando2 será executado para testar se a condição toda é verdadeira. Por exemplo: Se o arquivo livro.txt realmente existir, será impresso na tela: O arquivo existe. [ ‑e livro.txt ] && echo “Arquivo Existe” Se o diretório NovoDir não existir, é criado um diretório com o mesmo nome. cd NovoDir 2> /dev/null || mkdir NovoDir 7.8 Comandos de repetição Existem três tipos de estruturas de loop que serão vistas a seguir. Esse tipo de estrutura é usado quando é preciso executar um bloco de comandos várias vezes. 7.8.1 WHILE Nesta estrutura é feito o teste da condição; em seguida, ocorre a execução dos comandos. A repetição acontece enquanto a condição for verdadeira. while <condição> do <comandos> Done A condição pode ser um teste, uma avaliação ou um comando. Por exemplo: 171 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA Exemplo: #!/bin/bash echo “Tabela de Multiplicação do 7: “ i=7; n=0; while [ $n ‑le 10 ] do echo $i x $n = $(($i * $n)) let n++ done 7.8.2 UNTIL Neste caso, a repetição ocorre enquanto a condição for falsa. Ou seja, primeiramente, a condição é testada, se o código de retorno for diferente de zero, os comandos são executados. Caso contrário, a execução do programa continua após o loop. until <condição> do <comandos> Done A condição pode ser um teste, uma avaliação ou um comando. O exemplo a seguir é semelhante ao exemplo anterior do comando while. O que mudou foi a condição de teste. #!/bin/bash echo “Tabela de Multiplicação do 7: “ i=7; n=10; until [ $n ‑eq 0 ] do echo $i x $n = $(($i * $n)) let n‑‑ done 7.8.3 FOR A sintaxe da estrutura for é a seguinte: for variavel in lista do <comandos> Done 172 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Seu funcionamento segue o princípio: variável assume os valores que estão dentro da lista durante os loops de execução dos comandos. As listas podem ser valores passados como parâmetros, dados de algum arquivo ou o resultado da execução de algum comando. Com o exemplo a seguir fica mais fácil de entender isso. Este programa cria diretórios com o nome do diretório sendo composto pelo número que vai de 1 a 5 sendo incrementado de 1. #!/bin/bash for i in ‘seq 1 5’ do mkdir diretorio$i done O comando seq NumInicial NumFinal faz uma contagem sequencial do número inicial dado até o número final. Para estes três tipos de construção de loops, existem dois comandos que permitem alterar a rotina de sua execução. São eles: • break [n] – Este comando aborta a execução do loop e salta para a próxima instrução após o loop. • continue [n] – Este comando faz com que o fluxo de execução do programa volte para o início do loop antes de completá‑lo. O exemplo a seguir ilustra o uso de break e do continue: #!/bin/bash echo “Tente acertar o número “ echo “Dica: Ele está entre 10 e 50. “ i=1 while true do echo “Digite o Número: “ read num if [ $num != 30 ] then echo “Você errou. Tente outra vez” let i++ continue fi if [ $num == 30 ‑a $i == 1 ] 173 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA then echo Você acertou de primeira. Parabéns! break fi if [ $num == 30 ] then echo Você acertou após $i tentativas. break fi done 8 PROGRAMAS DE EXEMPLO 8.1 Programa “ALO” #!/bin/bash # Este programa diz alo echo “Alo $LOGNAME, tenha um bom dia!” Execute o programa: $ ./alo bash: ./alo: Permission denied $ bash alo Alo Maria, tenha um bom dia! $ chmod a+x alo $ ./alo Alo Maria, tenha um bom dia! $ PATH=$PATH:. $ alo Alo Maria, tenha um bom dia! 8.2 Entrada – saída básica A saída é feita basicamente na saída de outros comandos que estão no script. Se precisar de um print, usa‑se o comando echo. A leitura de informação da entrada padrão é feita com o comando do shell “read”. $ cat testaread #!/bin/bash read x echo Voce falou $x 174 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV $ cat lenome #!/bin/bash echo ‑n “Favor digitar seu nome: “ read nome echo “Seu nome eh $nome” 8.3 Solução para um problema Neste item, vamos dar um exemplo que pode representar uma situação real em que um administrador se depara com um problema de pirataria de conteúdo inadequado dentro de uma empresa. Você acabou de ser nomeado administrador de sistema numa empresa. O administrador anterior saiu correndo quando descobriu que um servidor principal da empresa estava sendo usado para guardar arquivos inadequados, warez (software pirata) e instruções para a fabricação de artefatos proibidos por lei. Suspeita‑se que várias pessoas da empresa, além do ex‑administrador de sistema, estavam envolvidas com a captação dessa informação. Pediu‑se que você fizesse um programa para identificar pessoas que acessam sites indesejáveis e avisá‑los da política de empresa acerca do uso apropriado da internet com recursos da empresa. Idealmente, você deve produzir um relatório informando quem acessou quais sites restritos e quantas visitas foram feitas.A informação a ser analisada está num arquivo netwatch que contém uma lista das pessoas e dos acessos que elas fizeram: ARQUIVO: netwatch jamiesob mucus.slime.com tonsloye xboys.funnet.com.fr tonsloye sweet.dreams.com root sniffer.gov.au jamiesob marvin.ls.tc.hk jamiesob never.land.nz jamiesob guppy.pond.cqu.edu.au tonsloye xboys.funnet.com.fr tonsloye www.sony.com 175 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 LINGUAGEM DE PROGRAMAÇÃO APLICADA janesk horseland.org.uk root www.nasa.gov tonsloye warez.under.gr tonsloye mucus.slime.com root ftp.ns.gov.au tonsloye xboys.funnet.com.fr root linx.fare.com root crackz.city.bmr.au janesk smurf.city.gov.au jamiesob mucus.slime.com jamiesob mucus.slime.com Os sites proibidos estão contidos num arquivo netproib: ARQUIVO: netproib mucus.slime.com xboys.funnet.com.fr warez.under.gr crackz.city.bmr.au www.hotwarez.com.br Resumo Nesta unidade apresentamos os principais conceitos e caracteristicas do sistema operacional Linux, sistema este classificado como software livre onde a comunidade pode alterá‑lo de acordo com as necessidades de cada usuário. 176 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Unidade IV Conhecemos a origem do sistema Linux e os recursos que foram utlizados para o desenvolvimento inicial desse sistema operacional de grande utilização nos dias atuais. Foram apresentados como funcionam os processos de inicialização do sistema e como o kernel realiza o gerenciamento dos diversos recursos disponibilizados pelo sistema operacional. Foram demonstradas a estrutura de tratamento de arquivos e diretórios, bem como o gerenciamento de contas de usuário. Foi mostrado também como se utilizam os scripts para gerenciamento do sistema através do shell, janela de comandos do Linux e como os programas podem ser executados. 177 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 REFERÊNCIAS Audiovisuais HACKER. Dir. Michael Mann. EUA: Legendary Pictures, 2015. 133 min. UMA MENTE brilhante. Dir. Ron Howard. EUA: Universal Pictures, 2001. 135 min. PIRATAS do Vale do Silício. Dir. Martyn Burke. EUA: Warner Bros, 1999. 95 min. REVOLUTION OS. Dir. J. T. S. Moore. EUA: J. T. S. Moore, 2001. 85 min. Textuais BARBIERI FILHO, P.; HETEM JUNIOR, A. Lógica para computação. São Paulo: LTC, 2012. COSTA, D. G. Administração de redes com scripts: bash script, python e VBScript. 1. ed. São Paulo: Brasport, 2007. DE MAIO, W. Fundamentos de matemática: espaços vetoriais, aplicações lineares e bilineares. São Paulo: LTC, 2007. HEGENBERG, L. Lógica: o calculo sentencial, cálculo de predicados. Cálculo com igualdade. 3. ed. São Paulo: EPU, 2012. NEVES, J. C. Programação shell linux. 7. ed. São Paulo: Brasport, 2008. REYNOLDS, J. J.; HARSHBARGER, R. J. Matemática aplicada. São Paulo: McGraw Hill, 2006. Site <http://xlogo.tuxfamily.org/pt/>. 178 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 179 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 180 Re vi sã o: F ab ríc ia - D ia gr am aç ão : J ef fe rs on - 0 7/ 06 /1 7 Informações: www.sepi.unip.br ou 0800 010 9000
Compartilhar