Introdução ao Sistema Operativo Unix
e Desenvolvimento de Programas em C
Fernando Mira da Silva
[email protected]
Departamento de Engenharia Electrotécnica
Instituto Superior Técnico
Setembro de 2000
Índice
1
Introdução
1
2
Unix, GNU/Linux e outros acrónimos
3
2.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.2
Sistemas operativos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.3
Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.3.1
A génese do Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.3.2
Divulgação do Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
Computadores pessoais e estações de trabalho . . . . . . . . . . . . . . . . . . .
7
2.4.1
Microprocessadores . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.4.2
Microcomputadores . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
2.4.3
IBM-PC e compatı́veis . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.4.4
Interfaces gráficas . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.4.5
Estações de trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.5
Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.6
Cópia e distribuição de software: aspectos legais e acrónimos importantes . . . .
19
2.6.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
2.6.2
Código binário e código fonte . . . . . . . . . . . . . . . . . . . . . . .
19
2.6.3
Software proprietário . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.4
II
ÍNDICE
2.7
3
4
2.6.4
Software livre, domı́nio público e GPL . . . . . . . . . . . . . . . . . .
21
2.6.5
Freeware e shareware . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
O projecto GNU e o sistema GNU/Linux . . . . . . . . . . . . . . . . . . . . . .
23
Ambiente de trabalho em Unix
25
3.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.2
Acesso ao sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.2.1
Conta de utilizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.2.2
Login e Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.3
O sistema de janelas X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
3.4
Modo interactivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
3.4.1
Hierarquia de directórios . . . . . . . . . . . . . . . . . . . . . . . . . .
28
3.4.2
Pathnames Absolutos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
3.4.3
Pathnames relativos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
3.5
Comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
3.6
Dispositivos de entrada e saı́da . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
3.7
Redireccionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
3.8
Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
Desenvolvimento de programas
37
4.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
4.2
Assembly e Linguagens de alto nı́vel . . . . . . . . . . . . . . . . . . . . . . . .
37
4.3
Ciclo de desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
4.3.1
Compilação e “linkagem” . . . . . . . . . . . . . . . . . . . . . . . . .
39
4.3.2
Erros sintáticos e semânticos . . . . . . . . . . . . . . . . . . . . . . . .
42
4.3.3
Depuração: gdb e ddd . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
ÍNDICE III
5
4.4
Compilação em módulos separados . . . . . . . . . . . . . . . . . . . . . . . . .
50
4.5
Bibliotecas estáticas e dinâmicas . . . . . . . . . . . . . . . . . . . . . . . . . .
52
4.6
O utilitário make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
Editores de texto
57
5.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
5.2
O editor emacs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
5.2.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
5.2.2
Modos de edição e de comando . . . . . . . . . . . . . . . . . . . . . .
58
5.2.3
Leitura de ficheiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
5.2.4
Formatação automática . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
5.2.5
Compilação e localização de erros . . . . . . . . . . . . . . . . . . . . .
59
O editor vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
5.3.1
Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
5.3.2
Modo de edição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
5.3.3
Movimentação do cursor . . . . . . . . . . . . . . . . . . . . . . . . . .
60
5.3.4
Inserir texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
5.3.5
Apagar texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
5.3.6
Mudar texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
5.3.7
Procurar texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
5.3.8
Substituir texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63
5.3.9
Cortar, copiar e mover texto . . . . . . . . . . . . . . . . . . . . . . . .
63
5.3.10 Outros comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
5.3.11 Saı́r . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
Os editores pico e joe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
5.3
5.4
IV
ÍNDICE
6
Textos e manuais complementares
67
6.1
Sistema Operativo Unix e Linux . . . . . . . . . . . . . . . . . . . . . . . . . .
68
6.2
Ambiente de trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
6.3
Programação e depuração de programas em C . . . . . . . . . . . . . . . . . . .
69
Bibliografia
71
Capı́tulo 1
Introdução
Pretende-se com este texto introduzir alguns tópicos que facilitem um primeiro contacto com o
sistema operativo Unix e ferramentas essenciais ao desenvolvivemento, teste e depuração (debug)
de programas em C. Pelo seu carácter introdutório e sumário, este texto não deve ser confundido
com um manual do sistema operativo Unix: para este efeito, remete-se o leitor para o capı́tulo 6,
onde são listadas diversas referências bibliográficas que aprofundam os tópicos aqui abordados.
Para além de funcionar como um manual introdutório ao Unix, são referidos neste texto aspectos históricos e funcionais deste sistema operativo que se espera que contribuam para uma melhor
compreensão do posicionamento do Unix no panorama informático actual e, complementarmente,
para a introdução de terminologia frequentemente utilizada informática.
No capı́tulo 2, apresenta-se uma breve história do sistemas operativo Unix, articulando o seu
desenvolvimento com diversos marcos relevantes da história da informática das últimas décadas.
No capı́tulo 3 faz-se uma introdução ao ambiente de trabalho em Unix, descrevendo os mecanismos essenciais do sistema de ficheiros, execução de comandos e redireccionamento. No capı́tulo 4
introduz-se a noção de ciclo de desenvolvimento de programas em C e introduzem-se os comandos
de compilação em sistemas GNU/Linux. São ainda introduzidos os utilitários gdb, ddd e make.
No capı́tulo 5 faz-se uma breve introdução de alguns dos editores de texto disponı́veis em Unix.
Finalmente, no capı́tulo 6, são listados textos e bibliografia que aprofundam cada um dos temas
abordados.
Capı́tulo 2
Unix, GNU/Linux e outros acrónimos
2.1
Introdução
Uma introdução ao Unix não implica necessariamente conhecer todos os detalhes da história
deste sistema operativo. Mas alguns destes detalhes, além de informativos, são importantes para
compreender o posicionamento actual deste sistema operativo. Assim, apresenta-se neste capı́tulo
uma breve sı́ntese da evolução do Unix e a sua articulação com outros marcos relevantes da história
da informática nas últimas décadas. Esta exposição permitirá também introduzir, de uma forma
progressiva, conceitos, terminologia e acrónimos frequentes em informática mas cujo significado
é, muitas vezes, mal conhecido.
2.2
Sistemas operativos
Não é fácil definir sistema operativo de uma forma rigorosa e abrangente. Numa primeira
aproximação, o sistema operativo de um computador pode ser definidido como o conjunto de
programas responsáveis pela gestão dos dispositivos e recursos fı́sicos da máquina (hardware) e
pelo acesso das aplicações a esses recursos.
Considere-se, por exemplo, um programa de processamento de texto desenvolvido para o
sistema operativo Windows. Este programa funciona independentemente das caracterı́sticas especı́ficas da máquina em que é executado: em particular, não precisa de conhecer a memória
disponı́vel, o tipo especı́fico dos discos utilizados ou o tipo e marca da placa gráfica ligada ao monitor. Com efeito, sempre que é preciso, por exemplo, guardar um ficheiro em disco, o processador
de texto limita-se a apresentar este pedido ao sistema operativo, o qual é responsável por o traduzir na sequência de comandos apropriada para o tipo de discos instalados. Complementarmente,
é o sistema operativo que permite a execução simultânea de vários programas (por exemplo, um
4 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
processador de texto e uma folha de cálculo), dividindo o tempo de processador disponı́vel pelas
duas aplicações.
Durante os últimos 50 anos, a evolução dos computadores e da informática foi acompanhada
pelo aperfeiçoamento de diversas gerações de sistemas operativos. Pela sua maior divulgação, o
MS-DOS, o Windows, o Unix e o Linux (a versão livre1 do Unix) são provavelmente os nomes
mais conhecidos de entre os muitos sistemas operativos existentes.
2.3
2.3.1
Unix
A génese do Unix
“...the number of Unix installations has grown to 10, with more expected...”
–Dennis Ritchie e Ken Thompson, autores do Unix, em Junho de 1972.
O sistema operativo Unix surge na sequência de um projecto iniciado nos anos 60 nos Bell
Labs da AT&T para desenvolver um sistema de operativo de tempo partilhado. Numa época
em que os computadores eram máquinas de grande porte e extremamente caras, era da maior
importância desenvolver sistemas operativos que permitissem a diversos utilizadores acederem
simultaneamente a um mesmo computador e, desta forma, rentabilizar os elevados custos de
exploração.
Em 1965, os Bell Labs iniciaram um projecto conjunto com a General Electric e o MIT para
desenvolver um sistema operativo de tempo partilhado designado Multics. No entanto, pouco depois do seu inı́cio, os Bell Labs consideraram que o projecto estava mal encaminhado e decidiram
abandonar o consórcio. Dada a necessidade de ser encontrada uma alternativa ao Multics para
uso interno, Kenneth Thompson, um dos investigadores dos Bell Labs, iniciou um projecto de
desenvolvimento próprio que conduziu, em 1969, à primeira versão do sistema operativo Unix.
Um das inovações do sistema Unix relativamente a outros sistemas operativos da época é o
conceito de que muitos dos comandos associados à gestão da máquina devem ser executados por
pequenos programas independentes, funcionando de forma cooperativa. Esta estratégia permitiu
simplificar significativamente as tarefas associadas ao núcleo2 do sistema operativo, aumentando
simultaneamente a sua robustez e modularidade.
Uma outra caracterı́stica inovadora do Unix é a sua portabilidade. Até à década de 70, a maioria dos sistemas operativos dependiam fortemente do hardware para que eram desenvolvidos. De
1
Na secção 2.6 discute-se o sentido que “livre” deve ter neste contexto
O bloco central do sistema operativo, responsável pela gestão do tempo de processador e partilha de recursos
disponı́veis, designado por kernel na terminologia anglo-saxónica.
2
U NIX 5
um modo geral, cada fabricante desenvolvia um sistema operativo especı́fico para os seus computador, o qual era geralmente escrito em assembler (o código binário entendido pelo processador).
Frequentemente, uma alteração ou evolução do processador implicava a re-escrita ou a revisão
do código de todo o sistema operativo. Ao contrário desta tendência geral, não sendo os Bell
Labs fabricantes de computadores, o Unix foi desenvolvido com base numa arquitectura de hardware muito genérica, não se baseando em hipóteses restritivas relativemnte ao tipo de processador
utilizado.
Assim, embora inicialmente escrito em assembler para um mini-computador PDP-11/20 da
Digital, o desenvolvimento da linguagem de programação C por Dennis Ritchie (Kernighan e
Ritchie, 1978) em 1973 permitiu a re-escrita de mais 90% do código do sistema operativo nesta
linguagem de alto nı́vel. A partir deste momento, a adaptação do sistema operativo a novos processadores é substancialmente simplificada: em vez da re-escrita completa do código binário dos
programas que formam o sistema operativo, é suficiente re-escrever o compilador (o programa
responsável pela tradução da linguagem C para o código binário do processador), tarefa esta substancialmente mais simples. Após este passo, a adaptação do sistema operativo ao novo processador
apenas exige a compilação (tradução automática) dos programas escritos em C.
Foram sobretudo as caracterı́sticas de modularidade e portabilidade, aliadas uma boa
concepção de raı́z, que permitiram a evolução contı́nua do Unix ao longo de trinta anos e a sua
permanente adaptação a múltiplas gerações de hardware e dispositivos periféricos. Neste sentido, o Unix é um caso único de longevidade na área dos sistemas operativos mantendo, ainda
hoje, muitas caracterı́sticas avançadas relativamente a a sistemas operativos mais recentes. Por
outro lado, em consequência da sua longevidade, é um sistema que ganhou uma fiabilidade elevada, sendo habitual um servidor de Unix estar operacional durante vários meses seguidos, sem
qualquer interrupção ou falha do sistema.
2.3.2
Divulgação do Unix
Até 1975, o Unix estave confinado internamente aos Bell Labs e só a partir desta data é
disponibilizado comercialmente para o exterior. Tendo sido inicialmente concebido para utilização
em ambientes relativamente abertos, onde a confidencialidade dos dados não era crı́tica, o sistema
Unix foi inicialmente adoptado, sobretudo, por universidades e instituições de investigação. O seu
baixo custo e o facto de ser disponibilizado com o código fonte (ou seja, o programa em formato de
texto) era especialmente apelativo para as instituições de ensino, já que permitia que os estudantes
e investigadores compreendessem e analizassem o seu modo de funcionamento e, adicionalmente,
contribuissem com extensões e modificações da versão original. Uma das contribuições mais
importantes durante a fase inicial do Unix foi o desenvolvimento, pela Universidade de Berkeley,
6 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
de uma versão para máquinas Vax que incluia suporte para memória virtual3 .
Durante o final da década de 70 e a primeira metade da década de 80, a evolução do Unix
originou múltiplas variantes. De entre estas, duas tiveram um impacto significativo na evolução
seguinte do sistema operativo.
A primeira, resultante da investigação e densenvolvimento dentro dos próprios laboratórios
Bell, inclui já em 1979 (Unix 7a edição) um mecanismo eficiente de comunicação entre computadores. Este mecanismo, designado UUCP, (Unix to Unix CoPy), será amplamente utilizado até ao
aparecimento do protocolo TCP/IP (o principal protcolo actualmente utilizado na Internet). Esta
evolução dá origem em 1983 ao designado Unix Sistema V. Em 1991 é formado o USL (Unix
System Laboratory, uma companhia maioritariamente detida pela AT&T), que passa a deter os
direitos sobre o Unix. Em 1993 a USL é adquirida pela Novell, a qual, por sua vez, passará mais
tarde os direitos sobre a marca Unix para o consórcio X/Open.
Paralelamente, a Universidade de Berkeley desenvolve uma evolução do sistema Unix que
recebe a designação BSD que inclui, como principal inovação, um eficaz sistema de comunicação
entre processos (programas), baseado na noção de sockets. Este modelo é suficientemente genérico
para permitir não apenas a comunicação entre programas residentes no mesmo computador, como
também a comunicação entre programas executados em computadores diferentes e ligados pelo
protocolo TCP/IP. Este mecanismo, que virá mais tarde a ser adoptado também por outros sistemas
operativos, é ainda hoje a base da maioria das comunicações estabelecidas na internet, como seja
a ligação entre um browser (como por exemplo o Netscape ou o Internet Explorer) e uma máquina
remota (server) que disponibiliza a informação.
Durante a década de 80 e inı́cio da década de 90, os principais fabricantes de computadores apercebem-se da importância crescente do Unix. De modo a adaptarem-se a esta realidade,
diversos fabricantes licenciam o código fonte da AT&T e, com base neste, desenvolvem versões
proprietárias do Unix. É assim que a Digital lança o Ultrix, a HP o HP-UX, a Sun o SunOS, e a
IBM o AIX, entre outros. Trata-se de um perı́odo de grande expansão e popularidade das diversas
variantes do sistema operativo Unix, sobretudo nos meios académicos.
Enquanto a divulgação do Unix aumenta, um outro projecto que terá amplas repercussões na
área da informática conhece também avanços importantes. Em 1973, o departamento de Defesa
Americano tinha iniciado o Defense Advanced Research Projects Agency (DARPA). O objectivo
era desenvolver uma arquitectura de rede com uma gestão distribuı́da, tal que o funcionamento no
seu conjunto não fosse afectado pela inoperacionalidade de qualquer dos seus nós. Este objectivo
era justificado pela Guerra Fria, então no seu auge, e pelos cenários estabelecidos pelos estrategas
3
A possibilidade, hoje comum, de um sistema utilizar mais memória do que a RAM efectivamente disponı́vel através
de um sistema de armazenamento e automático em disco de zonas da memória menos usadas, e a sua posterior leitura
quando necessário.
C OMPUTADORES PESSOAIS E ESTAÇ ÕES DE TRABALHO 7
militares em caso de guerra nuclear. O projecto incluı́a o desenvolvimento de protocolos4 que permitissem uma comunicação transparente entre dois computadores ligados em rede, mesmo quando
uma mensagem tivesse que atravessar diversas máquinas entre a origem e o destino. Este projecto
foi designado de Internetting, e o sistema de computadores interligado que emergiu deste trabalho
foi designado pelo então obscuro nome de Internet. Os protocolos que foram desenvolvidos no
âmbito deste projecto vieram a ser conhecidos por TCP/IP: Transmission Control Protocol (TCP)
e Internet Protocol (IP). Em 1986 a National Science Foundation inicia o desenvolvimento da
NFSNET, financiando a criação de um amplo sistema de nós interligados no Estados Unidos que
formam o esqueleto inicial da Internet.
Até 1993, data de aparecimento dos primeiros broswer, a Internet é sobretudo utilizada pelos
meios académicos e de investigação. No processo de crescimento da Internet, o sistema operativo
Unix tem também um papel fundamental, pelas suas caracterı́sticas de interoperabilidade e pelo
suporte principais protocolos de comunicação baseados no TCP/IP então usados na rede: o SMTP
(Simple Mail Transfer Protocol), utilizado pelo correio electrónico e o FTP (File Transfer Protocol). O facto de muitos dos nós da rede serem baseados em máquinas Unix contribuı́u também
significativamente para o crescimento e popularidade de um sistema operativo que, progressivamente, extravasou os meios académicos e começou a afirmar-se como uma alternativa viável em
certos contextos empresariais.
Entratanto, no inı́cio da década de 80, tinham entrado em cena os chamados computadores
pessoais. Originalmente muito limitados na sua capacidade computacional, concebidos como
postos de trabalho individuais e com sistemas operativos muito simples, era difı́cil imaginar que
alguma vez viessem a concorrer com os computadores de médio e grande porte, onde pontificavam
os sistemas operativos multi-tarefa e multi-utilizador, entre os quais se encontrava o Unix. O tempo
veio, no entanto, a provar o contrário.
2.4
2.4.1
Computadores pessoais e estações de trabalho
Microprocessadores
Até à década de 60, a unidade central de processamento de um computador ocupava diversas
placas electrónicas, povoadas por transistores, condensadores e resistências. Acomodar todo este
equipamento exigia um espaço fı́sico relativamente amplo. Embora com diversas variantes consoante a capacidade de cálculo, os mais pequenos computadores desta geração dificilmente podiam
ser arrumados no canto do escritório.
O primeiro sinal de mudança surge em 1971, quando a Intel anuncia o desenvolvimento do
4
A linguagem ou diálogos de entendimento utilizados na comunicação entre computadores.
8 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
primeiro microprocessador, um circuito integrado que inclui num único chip a maioria dos componentes normalmente encontrados na unidade central de processamento de um computador. Apesar
do Intel 4004 ser um processador de apenas 4 bits, constitui um marco decisivo na história do
hardware. No ano seguinte, enquanto Nolan Bushnell, da Atari, cria o primeiro jogo de vı́deo, a
Intel lança o 8008, um microprocessador de 8 bits, cuja evolução origina, em 1973, o 8080.
Inicialmente, os microprocessadores são utilizados apenas como dispositivos de controlo industrial. Em 1974, a Scelbi Computer Consulting utiliza o 8080 como base de um pequeno computador pessoal, de divulgação muito restrita. Nascem assim os microcomputadores, designação
que deriva da sua unidade central de processamento ser um microprocessador. No mesmo ano
surge o Mark 8, um microcomputador em kit que só os entusiastas de electrónica mais persistentes
conseguem pôr a funcionar.
No entanto, estes primeiros microcomputadores têm uma divulgação muito restrita. Para o
público em geral, o microprocessador é uma entidade desconhecida, e apenas o aparecimento e
rápida divulgação das máquinas de calcular de bolso indicia que algo está a mudar ao nı́vel da
miniaturização e integração da electrónica digital.
2.4.2
Microcomputadores
Em Dezembro de 1974, surge o primeiro computador pessoal com alguma divulgação comercial: o Altair 8800, produzido pela MITS, que tinha também por base o microprocessador 8080,
e que dispunha da uma descomunal memória de 256 bytes (não, não falta o K, estamos a falar de
duzentos e cinquenta e seis bytes, ou seja, 1/4 de Kbyte) e era vendido por cerca de 500 dólares.
Quando o Altair foi pela primeira vez anunciado na revista Popular Electronics, os fabricantes
receberam 400 encomendas na primeira tarde.
Pelos parâmetros actuais, o Altair dificilmente poderia ser considerado um verdadeiro computador: a introdução de dados era realizada em código binário por um conjunto de interruptores que
substituia o teclado. Os resultados das operações eram apresentados, também em código binário,
num conjunto de pequenas lampadas (leds) da caixa. Nesta versão inicial, o Altair não era mais
que um dispositivo onde se podiam programar, muito trabalhosamente, sequências elaboradas de
operações lógicas. Embora revolucionário para os interessados em electrónica digital, o Altair
original tinha um interesse prático limitado.
Entre os leitores do anúncio do Altair na Popular Electronics estavam dois estudantes de
Harvard, com um forte interesse em informática: Paul Allen e William Gates(Williams, 1993).
Rapidamente os dois estudantes anteciparam o potencial do Altair, desde que dotado com software
apropriado. Em particular tiveram a intuição de que o hardware do Altair era suficiente para
suportar um interpretador de uma linguagem de alto nı́vel, desde que fosse ligado a uma simples
C OMPUTADORES PESSOAIS E ESTAÇ ÕES DE TRABALHO 9
teleimpressora5 .
Não é possı́vel estabelecer com rigor os detalhes da história que se segue, já que o tempo leva
a que a realidade e o mito por vezes se confundam. Consta que Bill Gates, então com 19 anos,
telefona à MITS e afirma dispôr de um interpretador de Basic adequado ao Altair. A MITS mostrase interessada em testar o interpretador. Aparentemente Bill Gates não tinha uma única linha de
programa escrita quando prometeu o Basic à MITS, o que faz deste um dos primeiros componentes de vaporware6 do mercado informático. Dado que Allen e Gates não dispunham de um
Altair para desenvolver o seu interpretador de Basic, Allen desenvolveu um simulador de um microprocessador 8080 no PDP-10 de Harvard7 enquanto que Gates se dedicou ao desenvolvimento
do interpretador de Basic. Oito semanas depois, Allen deslocou-se à MITS com a missão de testar
o interpretador. Foi o seu primeiro contacto real com o Altair e, aparentemente a demonstração
de Allen impressionou positivamente a MITS.8 Em 1976, após um ano de comercialização bem
sucedida do Basic para o Altair, Bill Gates funda a Microsoft.
Praticamente ao mesmo tempo, também em 1975, um técnico da HP em Palo Alto, Steve
Wozniak, fazia planos para construir o seu próprio computador pessoal. Em vez do microprocessador 8080 da Intel, Wozniak preferiu adoptar o processador 6800 da Motorola, apenas por este ser
mais barato. Wozniak planeou de raı́z a sua máquina para incluir um teclado e uma interface para
televisão (obviamente a preto e branco), de forma a ultrapassar as limitações iniciais do Altair. O
computador de Wozniak evoluiu com a colaboração activa de um colega de 21 anos chamado Steve
Jobs. Ao fim de algum tempo, este sugeriu a Wozniak a comercialização do sistema desenvolvido.
Em Abril de 1976, Wozniak e Jobs fundam a Apple Computer Company.
Em Julho de 1976, é comercializado o Apple I. A primeira vez que o Apple I foi apresentado
numa reunião da Association of Computer Machinery, muitos dos presentes pensaram que se tratava de um terminal ligado telefonicamente a um computador de grande porte, já que era difı́cil, na
altura, acreditar que as potencialidades demonstradas pela máquina tivessem origem na pequena
caixa visı́vel ao público. O Apple II, lançado em 1977, é o primeiro sucesso comercial da Apple.
5
Máquina de escrever electromecânica com uma porta série.
Na gı́ria informática, vaporware designa um programa anunciado por um fabricante muito antes da sua produção
e, frequentemente, com especificações prometidas difı́ceis ou impossı́veis de cumprir.
7
Anos mais tarde, o conhecimento da utilização dos recursos de Harvard para este efeito deu origem a alguma
polémica.
8
Segundo a versão oficial da Microsoft, o interpretador de Basic funcionou em pleno no primeiro teste real. Face
às difı́ceis condições de desenvolvimento, esta afirmação deve ser encarada com algum cepticismo, sem que este facto
retire qualquer mérito ao excelente trabalho de Allen e Gates.
6
10 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
2.4.3
IBM-PC e compatı́veis
Nos anos seguintes, os modelos dos chamados computadores pessoais multiplicam-se, embora o seu preço confine a sua utilização às empresas.
A IBM, à data o maior fabricante mundial de computadores de grande porte, olhara incialmente este mercado emergente com alguma sobranceria. O sucesso do Apple II leva a IBM a
aperceber-se finalmente das potencialidades desta classe de produtos e a iniciar o desenvolvimento
do seu próprio modelo de computador pessoal, com o nome de código de Acorn. Trata-se de um
projecto que decorre em moldes pouco ortodoxos para os hábitos da empresa. De forma a reduzir
o custo final da máquina, o projecto Acorn é baseado em componentes disponı́veis no mercado, em
vez de seguir a polı́tica habitual na IBM de desenvolver componentes proprietários. Em particular,
é decidido adoptar o processador 8088 da Intel para unidade central de processamento (CPU) do
Acorn. Como se verá, esta decisão terá amplas repercussões no seguimento.
Entretanto, a Microsoft continuava a crescer, centrando a sua actividade no desenvolvimento
de software, sobretudo interpretadores e compiladores. Em 1980, numa tentativa para diversificar a sua actividade, a Microsoft tenta entrar na área dos sistemas operativos e anuncia o inı́cio
do projecto Xenix, um sistema operativo baseado no Unix que seria suportado em diversos processadores. Aproximadamente nesta altura, a IBM necessita de dotar o Acorn com um sistema
operativo simples e eficiente e, mais uma vez, resolve recorrer ao mercado em vez de utilizar os
seus próprios recursos. É assim que têm inı́cio os contactos entre a IBM e a Microsoft, dada a
experiência desta última no desenvolvimento de software para os microprocessadores de 8 bits da
Intel.
Apesar do anúnico do projecto Xenix, este encontrava-se em fase embrionária e a Microsoft
não dispunha de experiência real em sistemas operativos. O melhor sistema operativo para microprocessadores disponı́vel à época era o CP/M (Control Program for Minicomputers), desenvolvido
por Gary Kindall, da Digital Research. Tim Paterson, um programador da Seattle Computer Products, tinha desenvolvido um protótipo de sistema operativo para um computador 8086 que retinha
alguns aspectos do funcionamento do CP/M, mas que era suficientemente diferente deste para não
infringir as regras de copyright. Patterson designou o seu sistema operativo de QDOS, acrónimo
de Quick Disk Operating System, mas que os mais crı́ticos não hesitam a identificar como Quick
and Dirty Operating System. A Microsoft, sem referir o acordo que tinha com a IBM, comprou
os direitos do QDOS à Seattle Computer Products por uma importância irrisória e, após algumas
modificações, surgia a primeira versão do MS-DOS, o sistema operativo de que a IBM necessitava. Bill Gates licencia o MS-DOS à IBM, mas consegue que a Microsoft retenha o direito de
comercialização do MS-DOS. Anos mais tarde, Tim Paterson ingressará na Microsoft.
Em Agosto de 1981 a IBM anuncia públicamente o resultado do projecto Acron sob a
designação de IBM-PC, uma máquina baseado num processador 8088 a 4.77Mhz, uma memória
C OMPUTADORES PESSOAIS E ESTAÇ ÕES DE TRABALHO 11
de 16Kbytes, expansı́vel até 256Kb, e com uma ou duas unidades de diskettes. Este modelo, cuja
evolução deu origem aos actuais PCs9 , tem um sucesso que ultrapassa largamente as expectativas da própria IBM. Além da aura da marca, a arquitectura aberta do sistema permitia o fácil
desenvolvimento de software e hardware por parte de outras empresas. O modelo evolui e, em
1983, quando a IBM lança o IBM-XT, este lidera largamente o mercado dos computadores pessoais. A oferta de software para nova máquina cresce e a introdução da folha de cálculo Lotus faz
o interesse pela máquina por parte das empresas subir em flecha. Também fabricantes de hardware contribuem para este sucesso, com o desenvolvimento de placas gráficas melhoradas e outros
periféricos.
A arquitectura aberta do IBM-PC, e o seu successo comercial, leva a que construtores independentes comecem a tentar desenvolver máquinas equivalentes. Rapidamente são encontados
circuitos de substituição para os poucos componentes do IBM-PC que são proprietários da IBM.
Surgem assim os chamados PC-compativeı́s ou clones, máquinas de menor custo que as comercializadas pela IBM, mas que são capazes de correr o mesmo software. Esta possibilidade é facilitada
pelo facto da IBM não deter o exclusivo do sistema operativo MS-DOS, o qual é vendido pela Microsoft a qualquer fabricante ou utilizador que o pretenda. Como é evidente, o aparecimento de
clones é mal recebida pela IBM, mas revela-se um negócio extremamente lucrativo para a Microsoft, que vê as suas vendas aumentarem significativamente.
A década de 80 é um perı́odo de crescimento e grande divulgação da microinformática. Enquanto os IBM-PC e compatı́veis10 se afirmam sobretudo como postos de trabalho individuais nas
empresas, surge em 1982 o ZX-Spectrum, um pequeno computador baseado no processador Z80
da Zilog, de custo muito reduzido (o Spectrum não dispunha de diskettes mem de monitor, e o seu
funcionamento exigia a ligação de uma televisão e de um gravador de cassetes para a gravação e
leitura de dados), que dominará o mercado doméstico e de jogos até 1987. Outras marcas surgem
na altura com os seus próprios modelos, alguns com grande sucesso no mercado, como a Commodore Amiga e a Compaq. Mas o único concorrente sério ao domı́nio absoluto dos IBM-PC e
compatı́veis irá surgir da Apple, pela mão de Steve Jobs.
2.4.4
Interfaces gráficas
Desde o aparecimento dos primeiros computadores na década de 40 e até meados da década de
80, a comunicação com os computadores era fundamentalmente realizada em modo de texto, como
sucede no modo MS-DOS do Windows. O utilizador digitava um comando escrito e o computador
executava-o, eventualmente enviando para o dispositivo de saı́da uma resposta sob a forma de uma
sequência de linhas de texto.
9
De facto, qualquer PC actual é ainda capaz de executar o software desenvolvido para o IBM-PC original.
De aqui adiante, seguindo uma terminologia hoje muito generalizada, designar-se-á os IBM-PC e compatı́veis
simplesmente por PCs, mantendo no entanto presente que a designação é algo abusiva relativamente a outros fabricantes.
10
12 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
No inı́cio da década de 60, Ivan Sutherland, então um estudante de Doutoramento do MIT,
tinha desenvolvido um sistema que permitia a elaboração de desenhos em computador sobre um
tubo de raios catódicos. Os desenhos assim desenvolvidos podiam ser escalados, apagados e copiados. Embora o sistema tivesse uma estrutura primitiva pelos parâmetros actuais, a tese de Doutoramento de Sutherland, entitulada ”Sketchpad: A Man-machine Graphical Communications System”, discutia pela primeira vez a importância de sistemas gráficos de interacção homem-máquina,
que virão mais tarde a ser conhecidos sob a sigla GUI, de Graphical User Interface. Durante a
década de 70, a Xerox cria um grupo de investigação nos laboratórios PARC (Palo Alto Research
Center) dedicado à análise e estudo da interacção homem-máquina. A equipa inclui não apenas
engenheiros, mas também psicólogos que investigam mecanismos essenciais da aprendizagem
humana. O trabalho desenvolvido no Xerox PARC inventa ou aprofunda muitos conceitos hoje
correntes na interacção com computadores: a representação de ficheiros e comandos num écran
sob a forma de ı́cones, a utilização de dispositivos apontadores (ratos ou canetas) para manipular
estes objectos, a co-existência num mesmo écran de diversas janelas com informação referente à
execução de diferentes programas. Em particular, é desenvolvido o conceito WYSIWYG (What
You See Is What You Get) em editores gráficos e de texto, baseado no princı́pio de visualização
directa e interactiva no monitor do resultado final do processamento.
No inı́cio da década de 80, apesar do sucesso comercial dos Apple II e Apple III, a Apple tinha começado a perder terreno devido ao recém chegado IBM-PC. Steve Jobs, que tinha visitado o
Xerox PARC e ficado impressionado com o trabalho ali desenvolvido, apercebe-se que as interfaces gráficas podem ser a resposta adequada ao progressivo domı́nio da IBM no mercado. É assim
que a Apple dá inicio a um projecto de investigação em interfaces gráficas para o qual são contratados muitos dos investigadores do Xerox PARC. A Apple aprofunda e melhora os conceitos ali
desenvolvidos, os quais serão implementados numa versão primitiva no modelo Lisa da Apple, em
1982. A evolução deste modelo conduz à apresentação em 1984 do Macintosh o qual, equipado
com o sistema operativo MacOS, é a primeira implementação comercial de uma interface gráfica
simultaneamente eficiente e intuitiva.
A introdução do Macintosh traz uma revolução à área dos computadores pessoais e o seu sucesso comercial é enorme. No entanto, dois factores contribuem para a limitar este sucesso: o
preço muito mais elevado dos Macintosh e a arquitectura aberta do IBM-PC. Esta última tinha
permitido o contı́nuo crescimento dos fabricantes de compatı́veis, arrastando atrás de si fornecedores de hardware e software e, consequentemente, uma redução contı́nua de preços. A Apple,
em contrapartida, baseava-se num modelo de hardware e sistema operativo proprietários, o que lhe
permitia uma maior margem de manobra e o controlo do produto mas, simultaneamente colocava
fortes limitações às contribuições externas.
Apesar de manter o domı́nio comercial, a IBM apercebe-se do potencial da interface gráfica
do Macintosh. No entanto, por limitações do hardware, a implementação de um sistema com-
C OMPUTADORES PESSOAIS E ESTAÇ ÕES DE TRABALHO 13
parável nos IBM-PC não era viável a curto prazo. O hardware do Macintosh tinha sido concebido
de raı́z incluindo processadores de sinal e primitivas gráficas sofisticados. Também o sistema operativo MacOS era incomparavelmente mais sofisticado que o MS-DOS, o que dava à Apple um
confortável avanço em matéria de interfaces gráficas e multimédia.
Em 1985, a IBM e a Microsoft dão origem a um projecto conjunto para desenvolvimento de
um Sistema Operativo com interface gráfica designado OS/2. Apesar deste projecto comum ser
publicamente anunciado e conduzir, em 1987, à primeira versão do OS/2, a Microsoft continua
a dedicar recursos significativos ao desenvolvimento de um sistema gráfico próprio, designado
Windows. Depois de duas versões pouco apelativas, a Microsoft apresenta em 1990 o Windows
3.0, o primeiro concorrente sério, pela qualidade da interface gráfica, ao MacOS apresentado seis
anos antes. A Apple abre um processo contra a Microsoft protestando pela cópia da interface do
MacOS e pela infracção de direitos de autor. A Microsoft argumenta com a autoria original das
interfaces gráficas, que atribui ao trabalho desenvolvido no Xerox PARC, dando origem a um dos
mais complexos processos judiciais da história da informática. Este só terminará em 1997, com
um acordo entre as duas empresas conduzido respectivamente por Bill Gates e Steve Jobs.
Este acordo tem como pano de fundo o lançamento em 1995 do Windows 95, cujo domı́nio
comercial tinha colocado em fortes dificuldades a Apple. Outra vı́tima do sucesso do Windows e
da Microsoft foi o OS/2, cujo desenvolvimento nunca tinha sido abandonado pela IBM e que tinha
conduzido a um sistema operativo que, em meados da década de 90, era amplamente reconhecido
como superior ao Windows em termos de eficiência e robustez. A falta de software que explorasse
as suas caracterı́sticas é no entanto penalizador e nem o derradeiro esforço da IBM em 1995/96,
perı́odo em que procedeu uma distribuição massiva e frequentemente gratuita do OS/2, permitiu
que este obtivesse uma quota de mercado significativa.
2.4.5
Estações de trabalho
Durante a década de 80, enquanto os microcomputadores marcavam a sua presença no mercado das máquinas de gama baixa, os utilizadores especializados continuavam a necessitar de
máquinas mais potentes, com sistemas operativos multi-tarefa e multi-utilizador. Os sistemas de
grande porte (mainframes), normalmente associados so suporte de transacções em bases de dados
de grande dimensão, eram dominados por empresas como a IBM, Univac ou a Honeywell. Entre
estas e os computadores pessoais situavam-se os chamados minicomputadores, máquinas muito
mais pequenas do que as anteriores mas, ainda assim, consideravelmente mais potentes que os
PCs. Os minicomputadores eram geralmente disponibilizados com sistemas operativos multitarefa e multiutilizador, e tinham a dimensão apropriada para suprir as necessidades de um grupo de
investigação ou de um departamento de uma empresas (por exemplo, uma agência bancária).
Originalmente, o acesso quer aos computadores de grande porte quer aos minicomputado-
14 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
res era realizado apenas por meio de terminais alfanuméricos, ligados por uma linha série. A
ligação era lenta e, obviamente, só possı́vel em modo de texto. Apesar de terem velocidades de
processamento muito inferiores, os computadores pessoais tinham a vantagem de poder aceder
directamente à memória de vı́deo da máquina, permitindo a manipulação e alteração das imagens
no écran de forma muito rápida. É por este motivo que aplicações como a folha de cálculo11 ou
os jogos, aplicações que exigem uma forte interacção entre o software e a imagem gráfica, surgem
de facto primeiro nos computadores pessoais do que em máquinas mais potentes.
A associação de minicomputadores a monitores gráficos, permitindo a que os processadores acedam directamente à memória de vı́deo, deu origem às chamadas estações de trabalho ou
workstations. Inicialmente, as estações de trabalho têm um preço elevado, sendo apenas adoptadas em aplicações especializadas que requerem computação gráfica intensiva, sobretudo na área
da engenharia. Em 1984, o MIT inicia o desenvolvimento do sistema de janelas X para estações
de trabalho com sistemas operativos Unix. O X Windows é um sistema consideravelmente mais
complexo que os sistemas gráficos dos computadores pessoais. Nestes últimos, a gestão do écran
é efectuada directamente pelos programas ou pelo sistema operativo. De acordo com a filosofia
modular do sistema Unix, o sistema gráfico X Windows não faz parte do sistema operativo, sendo
constituido por um conjunto de programas autónomos responsáveis apenas pela gestão do sistema
gráfico. O modo de funcionamento do protocolo X segue o chamado modelo cliente-servidor.
Assim, uma única aplicação (o servidor) é responsável pela gestão directa do écran e hardware
gráfico. As aplicações que necessitam de usar o écran como, por exemplo, um browser de internet
ou um editor gráfico, constituem os chamados programas clientes, que se limitam a enviar pedidos
de manipulação de imagens para o servidor. Uma das grandes vantagens deste modelo é o facto
de um programa cliente poder ser executado numa máquina diferente daquela em que se encontra fisicamente instalado o hardware gráfico e o programa servidor, desde que as duas máquinas
estejam ligadas em rede: como já referido anteriormente, o modelo de comunicação entre programas ou processos em Unix é idêntico quer estes se encontrem no mesmo computador ou em
computadores diferentes ligados em rede.
A evolução do X Windows, que conhece grande divulgação sobretudo a partir da versão X11,
aliada à progressiva redução dos preços dos minicomputadores, permitiu que as estações de trabalho, originalmente utilizadas apenas em ambientes que necessitavam de computação gráfica
avançada, se generalizassem como a interface preferencial para máquinas Unix. As estações de
trabalho baseadas em minicomputadores tiveram o seu perı́odo de maior divulgação no final dos
anos 80 e inı́cio dos anos 90. Durante este perı́odo, o hardware dos minicomputadores sofreu
também uma evolução significativa, com a generalização dos chamados processadores RISC (Reduced Instruction Set Computers), com os quais se obtiveram aumentos significativos na velocidade de processamento.
11
A folha de cálculo foi inventada por Dan Bricklin, tendo sido originalmente desenvolvida num Apple II e comercializada sob o nome de VisiCalc em 1979.
L INUX 15
Apesar de serem adoptadas em múltiplas áreas da investigação e da engenharia, as estações
de trabalho ficaram sobretudo conhecidas pelo seu papel em trabalhos de animação por computador e na colorização e recuperação de filmes, áreas em que, ainda hoje, têm uma importância
significativa.
2.5
Linux
“Linux is obsolete. (...) Be thankful you are not my student. You would not get an high grade
(...)”
E-mail do Prof. Tanenbaum a Linus Torvalds, em 1992, criticando a arquitectura
monolı́tica do Linux e profetizando o seu desaparecimento a curto prazo.
No inı́cio dos anos 90, o panorama da Informática era dominado pelo crescimento da Internet,
a qual, embora ainda estranha às empresas, conhecia progressiva divulgação nos meios académicos
e de investigação. Como já se referiu, o mercado era dominado, nos postos de trabalho individuais
pelos compatı́veis dotados com o MS-DOS/Windows, embora o Macintosh tivessem uma fracção
importante do mercado, sobretudo em áreas editorias. As estações de trabalho Unix com X11
dominavam em ambientes especializados e, tipicamente, apresentavam velocidades de processamento dez vezes superiores às dos computadores pessoais, embora à custa de um preço também
várias vezes superior. Em redes locais de média dimensão, as máquinas Unix eram também frequentemente adoptadas como servidores de rede, gerindo serviços centralizados como o correio
electrónico, sistemas de backup, impressoras, áreas de disco partilhadas, servidores de web e
interligação à internet.12 No topo, os mainframes completavam o quadro, normalmente ao serviço
de grandes bases de dados.
Nesta altura, o hardware dos PCs tinha também já conhecido uma evolução significativa. Os
processadores 386 e 486 da Intel, predecessores dos Pentium, tinham já suporte para os mesmos
mecanismos avançados de computação disponı́veis nos minicomputadores e, embora mais lentos,
dispunham de uma arquitectura de 32 bits, suporte para memória virtual e funcionamento em
modo protegido. Estas potencialidades constratavam com as arquitecturas muito simplificadas
do DOS/Windows, as quais só funcionavam modo de 16 bits e praticamente não exploravam as
potencialidade dos novos processadores. Embora este facto fosse em parte ditado pela exigência
do mercado em manter a compatibilidade total dos PCs com a enorme quantodade de software
desenvolvido para o DOS original, tratava-se sem dúvida de um subaproveitamento significativo
do hardware disponı́vel.
Para além do DOS/Windows, praticamente não existiam nesta altura sistemas operativos al12
Por oposição à designação de servidor (server), os postos de trabalho individuais são frequentemente designados
por clientes, no sentido em que são consumidores dos serviços disponibilizados pelo servidor.
16 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
ternativos para os PC’s. O projecto OS/2 tinha pouca divulgação. A Microsoft tinha já iniciado
internamente o projecto do Windows NT, um sistema operativo com núcleo multitarefa que viria
a preencher a oferta da Microsoft no mercado de servidores, mas que só seria anunciado em 1993.
Nesta altura, muitos utilizadores de Unix em empresas e instituições de ensino dispunham de
PC’s em casa com DOS/Windows. No entanto, a possibilidade de usar os PCs domésticos para
desenvolver software Unix era limitada. O Xenix, a variante de Unix da Microsoft, desenvolvido
a partir de código licenciado pela ATT, estava disponı́vel desde meados dos anos 80. No entanto,
o Xenix tinha tido a sua origem com os processadores Intel 80286, que não dispunham ainda de
suporte para memória virtual. Tratava-se, portanto, de uma implementação limitada de Unix e
pouco compatı́vel com o software disponı́vel nas estações de trabalho Unix de gama média.
Em 1987, Andrew S. Tanenbaum, um Professor de Sistemas Operativos em Berkeley, tinha
desenvolvido o Minix, um sistema operativo baseado numa arquitectura designada por microkernel. Relativamente ao modelo do Unix (designado monolı́tico), as arquitecturas de microkernel
simplificam ainda mais as funções do núcleo, isolando as tarefas de gestão de memória e de gestão
de ficheiros do núcleo propriamente dito. O Minix tinha uma arquitectura elegante e avançada, era
compatı́vel com diversas plataformas de hardware e, ao nı́vel do utilizador, tinha uma interface
similar aos sistemas Unix.
Tanembaum tinha desenvolvido o Minix como um hobby e, sobretudo, como uma ferramenta
de ensino. O Minix teve um sucesso razoável junto de estudantes e investigadores de sistemas
operativos, tendo dado origem a um grupo de discussão na internet com cerca de 40,000 pessoas.
No entanto, apesar das suas potencialidades, a filosofia de microkernel do Minix tinha também
várias limitações de ordem prática. Apesar da forte dinâmica do grupo de discussão, com utilizadores constantemente a solicitar, sugerir ou a enviar alterações e adições, Tanenbaum mostrava-se,
na maioria dos casos, extremamente relutante em incorporar estas contribuições no seu kernel.
Na maioria dos casos, Tanenbaum considerava as alterações sugeridas como desnecessárias e
ameaçadoras da simplicidade e caracterı́sticas pedagógicas do seu microkernel. Esta opção limitava, no entanto, o nı́vel de utilização do Minix. Adicionalmente, Tanenbaum tinha decidido
manter o código propritetário, sendo a licença comercializada, embora a preço reduzido, através
da Prentice-Hall.
Da comunidade de utilizadores e estudantes de Minix fazia parte um estudante finlandês, de
20 anos, da Universidade de Helsinquia chamado Linus Torvalds. Em 1991 Linus tinha adquirido um PC com um processador Intel 80386 e, tal como muitos outros elementos da comunidade
Minix, pretendia que este evoluisse de modo a poder executar o enorme manancial de software
disponı́vel para sistemas Unix. Linus tinha apenas cerca de um ano de experiência na linguagem
de programação C quando decidiu começar a implementar um kernel próprio para teste de alguns
aspectos do sistema Unix. A estratégia seguida por Linus partiu da modificação e extensão do
Minix de modo a este implementar o modelo Unix. É provável que, para este processo, tenha
L INUX 17
contribuı́do o recém publicado livro de M. Bach, Design of the Unix Operating System (Bach,
1986), o qual descrevia de forma pedagógica e clara muitos detalhes do sistema Unix. Em 1991,
Linus envia uma mensagem para o grupo de discussão de Minix na Internet anunciando que estava a desenvolver um pequeno kernel de Unix para PC’s gratuito e que aceitava sugestões para
e e colaboração. Para muitos analistas, o inı́cio do projecto só terá sido possı́vel pela relativa
ingenuidade de Linus relativamente à complexidade que este apresentava.
Na especificação inicial do Linux encontrava-se a adesão ao standard POSIX, que descrevia
um conjunto de normas de comunicação entre aplicações e o sistema operativo que facilitava a
portabilidade de programas entre diferentes sistemas operativos. O POSIX, embora inspirado em
muitas interfaces de sistema do Unix, foi definido de forma a ser adoptado por outros sistemas
operativos. Este facto favorecia a compatibilidade do Linux com novas aplicações. Pouco tempo
depois, a maioria da comunidade Minix aderia ao Linux,13 e começaram a chegar a Linus inúmeras
sugestões, correcções, contribuições e drivers para suporte de vários dispositivos.
Independentemente do inegável mérito pessoal do trabalho de Linus Torvalds, diversos factores contribuı́ram para o sucesso do Linux. O mais decisivo foi, sem dúvida, a rapidez com que a
primeira versão utilizável foi disponibilizada na internet, cobrindo uma lacuna existente na área
dos sistemas operativos para PCs e ultrapassando outros projectos então em fase de preparação.
Com efeito, a GNU (ver secção 2.7) tinha desde a sua criação um projecto de desenvolvimento
de um sistema operativo, mas este nunca ultrapassou a fase de especificação. Também a Universidade de Berkeley desenvolvia na altura o 386BSD, que evoluı́u mais tarde para FreeBDS, uma
versão de Unix por muitos considerada superior ao Linux,14 mas a sua divulgação foi atrasada por
problemas legais derivados da reutilização de partes do código original do Unix da ATT, além de
Berkeley ter adoptado uma polı́tica de distribuição mais restritiva que a seguida por Linus.
Outro factor decisivo para o sucesso do Linux foi o seu aparecimento na altura em que a
internet interligava, pela primeira vez, as principais instituições universitárias e de investigação de
todo o mundo. Este facto foi fundamental para o desenvolvimento um projecto de programação
fundamentalmente cooperativo. De facto, embora o código de Linus tenha formado a base do
núcleo do Linux, foi a sua arquitectura aberta e as contribuições de centenas de programadores
que despoletaram o crescimento e divulgação do Linux a partir de 1992. Destacam-se, entre
outros, Alan Cox, provavelmente o maior contribuidor individual para o núcleo do Linux e até
agora responsável pela organização e distribuição do código do núcleo.
Durante o final da década de 90, o aumento da capacidade de processamento dos processa13
Facto que não foi facilmente aceite por Tanenbaum, que considerava a arquitectura do Linux obsoleta e inaceitável,
tendo dado origem a um hoje célebre debate na internet entre os defensores do Minix e Linux (Tanenbaum e outros,
1993). Em defesa deste último surgiu, entre muitos outros, Ken Thompson.
14
Anos mais tarde, Linus afirmou que o projecto Linux não teria tido inı́cio caso o BSD tivesse surgido algum tempo
antes.
18 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
dores Intel conduziu a uma redução significativa do fosso que separava os PCs das Workstations
baseadas em processadores RISC em termos de desempenho. Equipados com Linux e podendo
agora correr as mesmas aplicações anteriormente só disponı́veis em máquinas de gama média,
por uma fracção do mesmo preço, os PCs ocuparam progressivamente o espaço das estações de
trabalho Unix, as quais se viram progressivamente remetidas para nichos de mercado cada vez
mais especializadas. Actualmente, a expressão estação de trabalho perdeu o seu significado original, sendo aplicada indistintamente a qualquer computador utilizado como posto de trabalho
individual. A partir de 1996, marcas como a Intel, HP, IBM, Compaq e Novell compreendem as
oportunidades oferecidas pelo Linux e investem no suporte deste sistema operativo, o que corresponde a uma certificação implı́cita da qualidade e fiabilidade atingidas pelo Linux.
Actualmente (Agosto 2000) o Linux é, depois do Windows, o sistema operativo com maior
número de utilizadores a nı́vel mundial e a mais forte alternativa aos sistemas operativos Windows
e Windows NT, que dominam largamente o mercado. No entanto, apesar da sua maior fiabilidade
e flexibilidade relativamente sistemas da Microsoft, é reconhecido que estes últimos apresentam
uma interface com o utilizador mais simples que a apresentada pelo Linux. Apesar do esforço
que tem sido feito para dotar o Linux de ferramentas semelhantes às existentes no Windows, a sua
penetração tem vindo a ter lugar sobretudo no mercado de servidores, onde a fiabilidade é essencial e onde o utilizador/configurador directo é habitualmente um especialista em informática. De
acordo com um estudo da IDC(csn, 2000) o Linux representa (números de 1999) apenas cerca de
2% a 4% do mercado dos postos de trabalho individuais, segmento de mercado que o Windows
domina de forma esmagadora. A situação é distinta no mercado dos servidores, onde o Linux
representou, em 1999, cerca de 25% do mercado, contra 38% do Windows NT da Microsoft. O
restante mercado de servidores é repartido pelo NetWare da Novell (19%), outros Unix (15%) e
outros sistemas (3%). Os números revelam também que o Linux tem sido o sistema operativo com
maior crescimento no mercado dos servidores nos últimos anos, embora os ganhos observados se
tenham vindo a verificar sobretudo à custa dos servidores Novell e Unix, enquanto que o Windows
NT tem mantido uma fracção constante do mercado. Adicionalmente, tem-se assistido nos últimos
anos à adopção do Linux em segmentos menos habituais, incluindo em controladores e dispositivos integrados (por exemplo, gravadores digitais de vı́deo) em que o núcelo do Linux é adoptado
como base do sofwtare do sistema, embora a sua presença seja transparente para o utilizador.
Apesar de uma relativa euforia que rodeia o sucesso do Linux nos últimos anos, poucos se
arriscam a fazer previsões. Linus Torvalds mantem, ainda hoje, o controlo apertado do desenvolvimento do núcleo. Este é uma garantia de consistência exigida pelo mercado, mas os mais
cépticos apontam para a dificuldade de Linus compatibilizar o papel cada vez mais mediático que
tem vindo a assumir na divulgação do Linux com o tempo requerido pela crescente complexidade e dimensão do kernel. Por outro lado, à medida que o mercado cresce, aumenta também a
pressão dos fabricantes para a adopção de caracterı́sticas e facilidades especı́ficas. Esta pressão
comercial, além de representar uma variável nova no desenvolvimento do Linux, é olhada com
C ÓPIA E DISTRIBUIÇ ÃO DE SOFTWARE : ASPECTOS LEGAIS E ACR ÓNIMOS IMPORTANTES 19
desconfiança por parte da comunidade de “linuxiana” que, durante anos, contribuı́u gratuitamente
para o desenvolvimento do sistema operativo, receando-se que possa desmotivar alguns dos programadores mais activos. A possibilidade de grandes distribuidores de software e fabricantes de
hardware poderem vir a dominar o desenvolvimento de um produto Open Source (V. secção 2.6)
é um fenómeno novo e as suas consequências dificilmente previsı́veis.
2.6
Cópia e distribuição de software:
aspectos legais e
acrónimos importantes
2.6.1
Introdução
Open source, free software, freeware, shareware, public domain e GPL são designações e
acrónimos frequentes em informática, mas frequentemente mal entendidos.
Nesta secção, introduzem-se alguns conceitos relativos às condições de cópia, distribuição e
comercialização de software. Sublinhe-se que o tratamento rigoroso deste tema envolve aspectos
complexos do ponto de vista legal e, frequentemente, polémicos. A abordagem que aqui se faz
é meramente introdutória e, por este motivo, as definições aqui apresentadas não são completas
do ponto de vista formal. Ao leitor mais interessado recomenda-se a consulta dos doscumentos
disponı́veis sobre este tema http://www.gnu.org/.
2.6.2
Código binário e código fonte
O código de um programa designa o conjunto de instruções que definem a sequência de
operações a realizar pelo programa. Para a sequência, é no entanto importante entender a diferença
entre código fonte e código objecto.
O Código fonte de um programa designa o conjunto de ficheiros com instruções tal como
escritos originalmente pelo programador. Estes ficheiros, escritos numa dada linguagem de
programação, apresentam-se sob a forma de texto, de modo a que o seu conteúdo seja humanamente legı́vel. Desejávelmente, o código fonte de um programa inclui não apenas a sequência
formal de instruções a executar, mas também anotações do programador (comentários), escritas
em linguagem natural, que, embora não fazendo parte do programa, facilitam a sua compreensão
e explicam aspectos particulares do seu funcionamento.
O código fonte de um programa, embora sendo um formato conveniente para o programador humano, não é directamente executável pelo processador. Este só entende o chamdo código
binário, um formato codificado em que as instruções são traduzidas em sequências de bits co-
20 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
nhecidas pelo processador e que, de um modo geral, diferem de fabricante para fabricante. Por
exemplo, todos os ficheiros de DOS/Windows que contêm as extensões .com e .exe correspondem a programas em código binário, enquanto que ficheiros com a extensão .vbe correspondem a
programas fonte escritos em Visual Basic.
A transformação de código fonte para código binário é feita por um programa tradutor designado compilador, interpretador ou assemblador, consoante o caso. Este tópico será aprofundado
na secção 4.2.
Um programa disponibilizado em código fonte pode ser facilmente modificado por outro programador. O mesmo não sucede com o código binário, cuja alteração é geralmente muito mais
complexa.15
2.6.3
Software proprietário
Até à década de 1980, praticamente todo o software disponı́vel era produzido por fabricantes
de hardware e software com fins comerciais. Este software, designado como proprietário, implica
o pagamento de uma licença para ser utilizado e a cópia só é permitida para a criação de cópias de
segurança (backup).
A maioria do software proprietário é distribuı́da sob a forma closed source, ou seja, apenas em
formato binário. Embora seja possı́vel para alguém experiente entender o código binário de programas simples, a mesma tarefa afigura-se extremamente difı́cil em programas de complexidade
elevada. Por este motivo, a maioria das empresas que vendem código proprietário disponibilizamno em formato binário ou closed source, garantindo assim a exclusividade do domı́nio dos aspectos
técnicos do programa. Deste modo, apenas a empresa vendedora do software detém a informação
necessária para o corrigir e alterar, caso tal seja necessário.
A maioria do software oriundo de companhias comerciais como a Microsoft, a Novell ou
fabricantes de jogos é proprietário e, quase sempre, distribuı́do sob a forma closed source. A
duplicação e cópia deste software sem autorização das empresas proprietárias dos dieitos é quase
sempre ilegal, mesmo para uso doméstico e particular. Exceptuam-se situações particulares previstas nas próprias licenças, tal como a realização de cópias para efeitos de segurança (backup).
Por outro lado, a aquisição de uma licença de um determinado programa apenas permite a sua
instalação num único computador de cada vez. A instalação num segundo computador é geralmente legal desde que seja apagado do computador original.
No caso de grandes empresas ou instituições de ensino, existem por vezes as chamada licenças
de rede ou colectivas. Consoante as cláusulas particulares da licença, o detentor de uma destas
15
Embora tal não seja impossı́vel: a estratégia de propagação de muitos vı́rus inclui frequentemente a modificação
de ficheiros binários.
C ÓPIA E DISTRIBUIÇ ÃO DE SOFTWARE : ASPECTOS LEGAIS E ACR ÓNIMOS IMPORTANTES 21
licenças pode adquirir autorização para instalar um número ilimitado de cópias ou, alternativamente, para gerir de uma forma relativamente flexı́vel as licenças e cópias dentro da insituição.
Noutra variante das licenças de rede, a instituição pode ter um número ilimtado de cópias instaladas, mas apenas um determinado número máximo de programas pode ser executado simultaneamente. Neste último caso, o número máximo de cópias em execução simultânea é monitorizado
e autorizado por um programa especial, fornecida pelo fabricante, que supervisiona a rede de
computadores da instituição.
2.6.4
Software livre, domı́nio público e GPL
Em 1983, Richard Stallman, um investigador do MIT, inicia um movimento em defesa do
free software ou software livre. Este movimento é concretizado no projecto GNU (ver secção
2.7), o qual tinha por objectivo o desenvolvimento de um sistema operativo compatı́vel com Unix,
baseado exclusivamente em software livre. Por software livre entende-se software que se encontra
publicamente disponı́vel em código fonte e que pode ser copiado, distribuı́do e alterado livremente.
Além da defesa de um princı́pio essencial que Stallman designa por liberdade de
programação16 , a principal motivação do projecto GNU foi a de fomentar a crı́tica, cooperação
e intercâmbio entre a comunidade de programadores como forma de estimular a criação de mais
e melhor sofwtare. Mais, porque a possibilidade de reutilizar livremente parte de programas já
desenvolvidos e testados permite o densenvolvimento mais rápido de novas aplicações. Melhor,
porque a possibilidade de qualquer programador consultar e modificar o código fonte permite que
os erros detectados sejam mais rapidamente identificados e corrigidos.
Apesar do seu nome, sofwtare livre não significa necessariamente software grátis. Uma empresa pode cobrar uma dada quantia por organizar e distribuir um CD-ROM com software livre,
prestando eventualmente serviços complementares de assistência técnica. É, por exemplo, o caso
da RedHat, actualmente a maior companhia de distribuição do sistema operativo Linux. O software distribuı́do nestas condições deverá, no entanto, manter-se livre, no sentido em que qualquer
utilizador tem o direito de duplicar o CD e de modificar o código ali incluı́do.
O conceito de software livre é frequentemente confundido com a noção de software de
domı́nio público ou (public domain). Os dois referem, no entanto, situações legais diferentes.
Quando alguém coloca um programa (ou produto) no domı́nio público, não retém qualquer
direito de autor (copyright) sobre o material publicado. Tal significa que qualquer indivı́duo ou
empresa tem o direito de modificar o software e eventualmente comercializá-lo sob a forma de
programa proprietário. O autor original do programa nada pode fazer porque, ao colocar o produto
16
Richard Stallman produziu muitos artigos em que discute diversos aspectos da filosofia GNU, os quais podem ser
consultados em http://www.gnu.org/.
22 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
no domı́nio público, prescindiu de todos os direitos legais que sobre ele poderia deter. Por este
motivo, esta forma de distribuição não é encorajada pelos defensores do free software.
Distribuir um programa como software livre não significa que o programador prescinda ou
ceda os direitos de autor. Este facto permite que o autor, embora sem limitar o direito de cópia e
modificação por terceiros, possa colocar limitações à forma como este programa é utilizado ou redistribuı́do por terceiros. Para clarificar este aspecto, o conceito de software livre segundo a GNU
foi formalizado na chamda Gnu Public Licence (GPL), que define um conjunto de condições que
devem ser respeitadas por qualquer utilizador de software GNU. Basicamente, a GPL estabelece
que o autor original do software retem os seus direitos iniciais e que a redistribuição de versões
originais ou modificadas só é permitida quando acompanhadas do código fonte correspondente e
sob as mesmas condições da distribuição original. Quando uma versão modificada é distribuı́da,
deve estar explı́cito no código fonte que se trata de uma versão alterada, devendo as modificações
estar claramente identificadas. Quem modifica o software retém, por sua vez, o direito de autor
sobre as partes que modificou ou acrescentou. A licença GPL não se destina a utilização interna
do projecto GNU, podendo ser adoptada por qualquer programador que deseje distribuir software
nos termos definidos pela GPL.
Frequentemente a designação open software é utilizada alternativamente a free software. Embora em muitas situações práticas estas duas designações sejam equivalentes, estritamente falando
open source apenas identifica que o software é disponibilizado em código fonte. Embora não seja
frequente, esta designação pode abranger software que não seja disponibilizado gratuitamente e
que a sua duplicação seja proı́bida.
Além da versão GPL, há diversas variantes de licenças de distribuição de software livre, cada
uma com as suas subtilezas legais. No seus detalhes, a GPL é geralmente considerada a mais
“fundamentalista” em termos de free software. Existem licenças de software livre que permitem,
apesar de tudo, o desenvolvimento e a comercialização de produtos ou versões modificadas em formato closed-source, ou em que a redistribuição da versão original é livre mas não a redistribuição
de versões modificadas.
2.6.5 Freeware e shareware
Freeware e shareware designam formas de distribuição de software em formato closed source
e, como tal não modificáveis. O software é para, efeitos legais, proprietário do autor.
De um modo geral, designa-se por freeware software de cópia e distribuição gratuita, mas que
é disponibilizado apenas em formato binário e, como tal, não modificável. Deste modo, o freeware
é gratuito, mas não é livre no sentido definido pela GNU e pela GPL.
Shareware é uma forma de distribuição que foi popularizada pela internet e que surge como
O PROJECTO GNU E O SISTEMA GNU/L INUX 23
forma de comercialização alternativa de software proprietário por parte de programadores individuais e pequenas empresas. De forma a evitar o recurso a canais de distribuição comerciais convencionais, que implicam um esforço financeiro e de marketing adicionais, a distribuição de shareware baseia-se na autorização de cópia e distribuição livre por parte dos utilizadores. Pretendese, desta forma, facilitar tanto quanto possı́vel a divulgação do programa distribuı́do. No entanto,
os utilizadores são supostos procederem ao registo da sua cópia e pagamento de uma licença se,
após um perı́odo de teste do programa, optarem pela sua utilização permanente. Frequentemente,
os programas distribuı́dos em shareware descrevem as condições e limitações da versão de teste e,
por vezes, contêm dispositivos que bloqueiam o seu funcionamento após um detrminado perı́odo
de tempo sem registo ou que limitam as sua funcionalidades. Embora as disposições legais do shareware sejam frequentemente ignoradas, do ponto de vista legal, a utilização de shareware após o
perı́odo experimental é equivalente à utilização ilegal de software proprietário.
2.7
O projecto GNU e o sistema GNU/Linux
Conforme se referiu anteriormente, em 1983 Richard Stallman deu inı́cio ao projecto GNU,
o qual tinha por objectivo o desenvolvimento de um sistema operativo compatı́vel com Unix,
que representasse eventualmente uma evolução deste, baseado exclusivamente em software livre. A designação GNU é um acrónimo proposto por Stallman derivado de “GNU’s not Unix”,
definição em que a recursividade surge como um tributo a um conceito importante para a ciência
da computação.
O projecto GNU tinha como objectivo o desenvolvimento de um sistema operativo completo.
Neste contexto, é importante detalhar o significado de completo: além do núcleo, que gere a
distribuição de recursos fı́sicos pelos programas e a comunicação entre estes, um sistema operativo
requer um conjunto grande de programas utilitários. Duplicar, apagar ou editar ficheiros, compilar,
gerir contas de utilizadores e espaço em disco, estabelecer ligações com outros computadores,
arquivar e até dialogar com um utilizador através de uma linha de comando são tarefas que não
são executadas directamente pelo núcleo, mas sim por um vasto conjunto de pequenas aplicações
que são geralmente fornecidas conjuntamente com o sistema operativo. Por exemplo, programas
como o “notepad” e o “explorer” são essenciais numa distribuição do Windows, mas do ponto de
vista funcional são independentes do núcleo do Windows.
Face à complexidade do desenho do núcleo de um sistema operativo, durante vários anos o
projecto GNU dedicou-se apenas ao desenvolvimento de utilitários que constituiam versões melhoradas da maioria das ferramentas do Unix da ATT. Além da contribuição do próprio Stallman,
que incluı́u algumas componentes fundamentais como as versões originais do compilador gcc, do
editor emacs, do gerador de parsers bison, participaram no projecto centenas de programadores.
No inı́cio da década de 90, o projecto GNU já incluı́a versões de praticamente todas as ferramentas
24 U NIX , GNU/L INUX E OUTROS ACR ÓNIMOS
do sistema Unix, faltando apenas o desenvolvimento do núcleo. Stallman pensava desenvolver o
núcleo do GNU baseado no Mach, um sistema operativo que, tal como o Minix de Tanenbaum, se
baseava numa arquitectura de microkernel, mas o projecto enfrentava dificuldades várias.
A decisão de Linus de desenvolver o Linux e o distribuir sob a licença GPL só foi possı́vel
pela existência prévia de todos os utilitários da GNU necessários para preencher o espaço que
medeia entre o núcleo e o utilizador. Estritamente falando, Linux designa apenas o núcleo do
sistema operativo. Se é verdade que o sucesso do Linux só é possı́vel pela existência prévia do
projecto GNU, é também um facto que é o trabalho de Linus que permite dotar, pela primeira vez,
o projecto GNU de um núcleo estável e, assim, fechar o circulo iniciado e projectado por Richard
Stallman em 1983.
Num sistema Linux tal como distribuı́do actualmente por empresas como a RedHat ou a Debbian, cerca de 30% do código fonte é tem origem no projecto GNU e apenas 3% a 5% representa
o núcleo do sistema operativo17 . Por este motivo, Richard Stallman defende que a designação
correcta para os sistemas Linux deveria ser sistema GNU/Linux e não apenas Linux, de forma a
substanciar o papel que o projecto GNU teve e tem na génese e manutenção do Linux.
17
O restante software é também gratuito, mas nem sempre distribuı́do sob a licença GPL (é o caso, por exemplo da
versão XFree86 do sistema X Windows).
Capı́tulo 3
Ambiente de trabalho em Unix
3.1
Introdução
Neste capı́tulo faz-se uma sintese dos principais comandos do sistema Unix e de alguns aspectos do seu funcionamento. Pretende-se aqui descrever apenas os comandos essenciais a uma
primeira interacção com o sistema, sem aprofundar os seus detalhes de funcionamento. Supõe-se
que aprendizagem do comando <man> e a consulta de outros elementos de estudo (ver capı́tulo
6) serão os complementos deste texto introdutório.
Conforme se referiu no capı́tulo 2, o GNU/Linux não é mais do que uma implementação de
Unix em software livre. Deste modo, no seguimento utilizar-se-á a designação “Unix” a propósito
de comandos e conceitos genéricos, restringindo-se uso da designação “Linux” a exemplos e
situações que digam respeito esepcificamente a esta implementação do Unix.
3.2
3.2.1
Acesso ao sistema
Conta de utilizador
O sistema UNIX é um sistema multi-utilizador, capaz de gerir o acesso simultâneo de diversos
utilizadores e aplicações a uma mesma máquina.
Cada utilizador é identificado perante a máquina pela especificação de um dado username,
atribuı́do pelo gestor do sistema. O username permite a manutenção de um registo (account, ou
conta de utilizador) individual das operações efectuadas e recursos utilizados. Cada utilizador é
responsável perante o gestor da máquina por todas as utilizações indevidas ou ilegais dos recursos
disponibilizados que sejam registados na sua conta individual.
26 A MBIENTE DE TRABALHO EM U NIX
De modo a garantir a confidencialidade e segurança do acesso a cada conta de utilizador, a
cada username encontra-se associada uma password especı́fica. A password é atribuı́da inicialmente pelo gestor do sistema, mas pode ser alterada em qualquer altura pelo próprio utilizador (o
comando a utilizar para este efeito é descrito numa secção seguinte). A password tem uma dimensão máxima de 8 caracteres podendo incluir a maioria dos caracteres disponı́veis nos teclados.
Dada a existência de programas capazes de descodificar passwords com estruturas simples, a
escolha de uma password deve obedecer aos seguintes critérios:
• Ter uma dimensão mı́nima de 6 caracteres.
• Não corresponder, em nenhum caso, a uma palavra simples ou nome próprio de qualquer
lı́ngua.
• Incluir caracteres minúsculos e maiúsculos.
• Incluir alguns dı́gitos e pelo menos 1 caracter não alfanumérico (p. ex., &, *, !, etc.) na sua
composição.
3.2.2 Login e Shell
O acesso a uma sessão de trabalho em UNIX efectua-se especificando o username (solicitado
normalmente pela indicação login:) e password solicitados pelo sistema. A especificação quer do
username quer da password deve ser seguida da tecla <return>. Por razões de confidencialidade,
a password não surge no monitor quando é introduzida.
Após a entrada em sessão, o utilizador passa a dialogar com um interpretador de comandos de
UNIX, vulgarmente designado por shell. Existem diversos interpretadores de comandos de UNIX
com caracterı́sticas distintas (bash, cshell, tcshell, bourne, etc). A discussão das caracterı́sticas
que distinguem as diversas shells encontra-se fora do âmbito deste texto. No seguimento, assumirse-á que o utilizador trabalha com a bash, a qual é a shell por omissão dos sistemas Linux. Note-se,
no entanto, que os comandos mais correntes de UNIX correspondem a aplicações independentes
do interpretador de comandos, e como tal disponı́veis em qualquer shell.
No final da sessão de trabalho, o utilizador deverá desligar a sua sessão pela execução do
comando logout. A verificação de que a sessão foi desligada é essencial para garantir a segurança
do sistema e evitar a utilização indevida da sua conta de utilizador.
No sistema Unix, cada programa tem geralmente associado um conjunto de variáveis que
contêm informação sobre o ambiente e que podem ser consultadas em qualquer altura. Algumas
destas variáveis são inicializadas pelo sistema, enquanto que outras podem ser definidas pelo utilizador no ficheiro .bashrc do seu directório principal, o qual é lido sempre se inicia o interpretador
O SISTEMA DE JANELAS X 27
de comando bash. Por exemplo, a variável PATH, especifica a lista de directórios consultados pela
shell para procurar um programa que se pretenda executar, separados por doispontos. A consulta
desta variável pode ser feita pelo comando
$ echo $PATH
3.3
O sistema de janelas X
O sistema de janelas X é a interface gráfica adoptada em máquinas com o sistema Unix.
Quando o utilizador efectua o login no sistema de janelas X, passa a poder abrir diversas
janelas simultaneamente no écran. Assim, uma janela poderá incluir um gestor de ficheiro, outra
pode corresponder a um terminal virtual onde é executada uma shell e outra a um editor de texto.
Com o login, é normalmente executado automaticamente um programa designado gestor de
janelas (window manager), responsável pelo controlo das diversas janelas e pela gestão dos menus
de utilizador, geralmente acessı́veis posicionando o rato em qualquer ponto do fundo do écran e
carregando no botão do lado direito. No entanto, embora o sistema X seja o mesmo, existem
hoje em dia diferentes gestores de janelas e interfaces de utilizador, com aspectos gráficos muito
distintos e configuráveis através de temas, skins e outras opções do utilizador. Este facto gera uma
grande variabilidade nas interfaces possı́veis, fazendo a sua descrição cair fora do âmbito deste
texto.
Sublinhe-se apenas que existem vários programas que permitem abrir um terminal virtual no
sistema de janelas X, entre os quais o xterm, o nxterm ou o gnome-terminal. Um terminal virtual
executa uma shell, a qual funciona em modo de comando de forma idêntica ao que sucede em
modo de texto. Grande parte da descrição das próximas secções admitem que o utilizador dialoga
com o sistema, através de uma shell, em modo de comando.
No sistema X, é possı́vel executar um programa num computador e a janela gráfica correspondente ser aberta no monitor ligado a outra máquina. Esta possibilidade é controlada, nos
programas que usam X, através da variável de ambiente DISPLAY. Uma inicialização incorrecta
desta variável é suficiente para impedir o funcionamento correcto do sistema gráfico. Embora
esta variável seja inicializada automaticamente de forma a apontar para o écran em que se está a
trabalhar, é possı́vel alterá-la com o comando
$ export DISPLAY=<nome>:0
onde <nome> é o nome do computador em cujo sistema gráfico se pretende abrir a janela. Para
que isto seja possı́vel é necessário que este último autorize a ligação. Esta autorização que pode
28 A MBIENTE DE TRABALHO EM U NIX
ser dada através dos comandos xhost ou xauth.
3.4
3.4.1
Modo interactivo
Hierarquia de directórios
Um ficheiro corresponde a um conjunto estruturado de dados residente na memória secundária
(disco) do sistema. O conteúdo de um ficheiro pode ser texto (como o deste manual), um programa
executável, dados, etc.
Os ficheiros em UNIX encontram-se organizados por directórios (ou directorias). Um directório pode ser comparado a um arquivo em que são guardados ficheiros relativos a um tema comum. No entanto, cada directório pode incluir, além de ficheiros, outros directórios, não existindo
um limite pré-estabelecido para o número de nı́veis que esta estrutura hierárquica pode suportar.
Na figura 3.1 apresenta-se um exemplo tı́pico de uma árvore de directórios em UNIX. Nesta figura,
os rectângulos a cheio representam ficheiros e os restantes directórios.
Nos sistemas UNIX, um directório não é mais que um caso particular de um ficheiro com
funcionalidades especı́ficas. Frequentemente, um mesmo comando pode ser aplicado igualmente
a um ficheiro ou a um directório, embora o seu modo exacto de funcionamento possa ser ligeiramente diferente num caso e outro.
Em geral, cada utilizador tem associado à sua conta um directório de defeito (home directory)
que pode gerir da maneira que considerar mais conveniente. A partir da sua home directory, o
utilizador pode criar um número arbitrário de nı́veis de directórios (em nı́veis hierarquicamente
inferiores), sendo apenas limitado pelo espaço disponı́vel em disco (ou pelo espaço em disco associado à sua conta de utilizador). Como é evidente, é conveniente o utilizador definir os seus
directórios de acordo com as diferentes trabalhos que realiza no sistema, embora este procedimento não seja obrigatório.
A cada ficheiro de UNIX encontra-se associado um nome (filename). O nome de um ficheiro
é composto de 1 a 14 caracteres (embora muitas versões de UNIX admitam nomes mais longos).
Apesar de ser possı́vel utilizar quase todos os caracteres disponı́veis no nome de um ficheiro, é
por diferentes motivos conveniente restringir os nomes de ficheiros a caracteres alfanuméricos
(números e letras) e aos caracteres ’.’ e ’ ’. Como é evidente, todos os ficheiros residentes num
mesmo directório têm um nomes distintos; no entanto, é possı́vel haver ficheiros com nomes
idênticos em directórios diferentes.
Todos os directórios do sistema UNIX são definidos a partir de um directório de nı́vel superior.
A única excepção a esta regra é o directório raı́z do sistema (root directory) o qual é criado durante
M ODO INTERACTIVO 29
Figura 3.1: Exemplo de uma árvore de directórios em UNIX.
30 A MBIENTE DE TRABALHO EM U NIX
o processo de instalação do sistema na máquina. No caso do exemplo da figura 3.1, o directório
raı́z surge no topo da hierarquia, sendo referenciado pela barra (/). Todos os directórios existentes
no sistema de ficheiros ”descendem”em última análise deste, embora seja variável o número de
nı́veis da hierarquia existente entre ambos.
Cada ficheiro ou directório é registado em nome de um dado utilizador. O sistema mantem,
paralelamente, um mecanismo de controlo de acessos a cada ficheiro ou directório. A permissão
de acesso a um dado ficheiro pode ser definida em 3 nı́veis distintos: utilizador proprietário do
ficheiro (owner), grupo (group) e todos os outros utilizadores (world). A definição de grupos
de utilizadores permite a que utilizadores de um mesmo grupo partilhem ficheiros de interesse
comum. Para cada um deste nı́veis, é possı́vel definir o ficheiro como de leitura (r), escrita (w),
execução (x) ou qualquer combinação dos três modos anteriores. A permissão de acessos a dado
ficheiro pode ser alterado em, qualquer altura pelo proprietário do ficheiro com o comando chmod.
3.4.2 Pathnames Absolutos
Durante a execução de uma tarefa especı́fica no sistema, o utilizador encontra-se localizado
num directório bem determinado (directório de trabalho). Quando um ficheiro é especificado
pelo seu nome simples, admite-se que este directório reside (ou deve ser criado, se for este o
caso) no directório de trabalho. É no entanto possı́vel especificar um ficheiro residente em outro
directório pela indicação do pathname absoluto do ficheiro. O pathname absoluto de um ficheiro
é constituı́do pelo seu nome precedido pelo nome de todos os directórios de que ele depende até
ao directório raı́z, separadas por uma ’/’1 .
Considere-se por exemplo o ficheiro prog.c residente no nı́vel mais baixo da hierarquia representada na fig. 3.1. O pathname absoluto deste ficheiro é
/home/user1/prog1/src/prog.c
Na definição de um pathname absoluto pode ser usado o sı́mbolo ˜ (til) para referenciar o
directório de defeito de um dado utilizador. Por exemplo,˜<username> referencia o directório
de defeito do utilizador <username>. Caso o nome de utilizador seja omitido,˜referencia o directório de defeito do utilizador que usa o comando. Por exemplo, no caso da figura 3.1, admitindo
que a área de defeito do utilizador user1 é
/home/user1
1
Quem estiver familiarizado com o sistema MS-DOS, facilmente reconhecerá a semelhança entre a hierarquia de
ficheiros nos dois sistemas, substituindo a barra invertida (backslash) por /. É conveniente ainda notar a ausência em
UNIX do conceito de drive do MS-DOS.
M ODO INTERACTIVO 31
e do utilizador user2
/home/user2
o utilizador user2 pode aceder a prog.c (se tiver permissão de acesso a este ficheiro) explicitando
˜user1/prog1/src/prog.c
enquanto que utilizador user1 poderá obter o mesmo resultado referenciando
˜/prog1/src/prog.c
3.4.3 Pathnames relativos
Conforme se viu na secção anterior, a especificação de um pathname absoluto começa com
uma ’/’, que indica o directório raı́z do sistema. Se esta barra inicial for omitida na especificação do pathname, este é considerado como relativo ao directório de trabalho. Deste modo, se o
directório de trabalho fôr
/home/user1
é possı́vel aceder directamente a prog.c especificando
prog1/src/prog.c
Quando um directório é criado, são automaticamente criadas dois ficheiros que têm funções
especı́ficas. O primeiro destes ficheiros é identificado por um único ponto (’.’) e identifica o
próprio directório. O segundo ficheiro é identificado por dois pontos (’..’) e identifica o directório
de nı́vel hierárquico imediatamente superior, i.e., o directório de que este descende. Este último
ficheiro pode ser usado para especificar um pathname relativo de um ficheiro residente num nı́vel
superior da hierarquia ou num ramo diferente. Admita-se por exemplo que o directório de trabalho
é
/home/user1/prog1/src/sub1
é possı́vel aceder directamente a prog.c especificando
../prog.c
32 A MBIENTE DE TRABALHO EM U NIX
De modo semelhante, caso o directório de trabalho seja
/home/user2/prog/src
é possı́vel aceder directamente a prog.c especificando
../../../user1/prog1/src/prog.c
3.5
Comandos
O utilizador dialoga com a shell pela introdução de comandos. Um comando é normalmente
especificado por uma linha de texto seguida da tecla <return>2 . Após a execução de cada comando, surge no monitor o prompt do interpretador, indicando que este está pronto a receber
uma nova linha de comando. O prompt de defeito da shell é o caracter $, embora este possa ser
redefinido pelo utilizador.
Um comando em UNIX tem habitualmente a forma3
$ <nome do comando> <flags> <argumentos>
As <flags> são geralmente opcionais e especı́ficas de cada comando. Têm normalmente a
forma de um hı́fen ’-’ seguido de uma letra. São geralmente utilizadas para especificar determinadas funcionalidades não disponı́veis na versão base do comando.
Os <argumentos> são igualmente depedentes do comando, e designam habitualmente entidades sobre as quais o comando opera.
Embora esteja fora do âmbito deste texto uma descrição dos comandos disponı́veis em UNIX,
inclui-se aqui uma breve listagem dos utilizados mais frequentemente. A descrição apresentada
é muito sumária, devendo o utilizador usar o comando man para consulta a uma descrição mais
detalhada de cada comando.
• man <comando>
Lista a página de manual de <comando> e tem as funcionalidades associadas ao help
existente em outros sistemas operativos. De um modo geral, a página de manual inclui
2
É possı́vel utilizar comandos com mais de uma linha de texto; no entanto este caso não será aqui considerado.
Nos exemplos de comandos incluı́dos neste texto, faz-se preceder o comando do sı́mbolo $, caracterı́stico do prompt
da shell. Convém notar no entanto que este sı́mbolo não é introduzido pelo utilizador.
3
C OMANDOS 33
uma descrição sumária das funcionalidades do comando e das suas opções. As páginas de
manual de Unix são, de um modo geral, sistemáticas e sintéticas. Embora o seu formato
tı́pico possa parecer hermético nas primeiras consultas, o mesmo revela-se extremamente
eficiente após um primeiro perı́odo de habituação à terminologia utilizada.
• pwd
Indica o directório de trabalho corrente.
• ls
Lista os ficheiros existentes no directório de trabalho. É possı́vel acrescentar argumentos de
forma a selecionar apenas ficheiros com determinadas caracterı́sticas: por exmplo,
ls a*
lista todos os ficheiros começados por a, enquanto que
ls a*f*b ghi*
lista todos os ficheiros cujo nomes tenha, inı́cio em a, fim em b e apresentem um f pelo
meio, além de todos os ficheiros iniciados por ghi.
• cd <nome>
Muda o directório de trabalho corrente para o directório <nome>. Se <nome> não for
indicado, muda o directório corrente para a home directory do utilizador.
• mkdir <nome>
Cria o directório <nome>
• cp <origem> <destino>
Copia o ficheiro <origem> para <destino>. Se <destino> fôr um directório, é criado um
ficheiro com o nome <origem> neste directório.
• mv <origem> <destino>
Muda o nome do ficheiro ou directório <origem> para <destino>. Se <destino> fôr um
nome de um directório já existente, o ficheiro ou directório <origem> é deslocado para o
directório <destino>, mantendo o mesmo nome.
• rm <nome>
Apaga o ficheiro <nome>.
• rmdir <nome>
Apaga o directório <nome>.
34 A MBIENTE DE TRABALHO EM U NIX
• cat <nome>
Lista o ficheiro <nome>. Para visualização do conteúdo de um ficheiro, este comando é
geralmente substituido pelo comando <less>, descrito mais à frente.
• du -s <nome>
Indica o espaço em disco ocupado pelo ficheiro <nome>. Caso <nome> seja um directório, o espaço indicado inclui todos os seus ficheiros e sub-directórios. Para saber a área
total ocupada pelo utilizador usar du -s .
• less <nome>
Lista o ficheiro <nome> página a página. O avanço de cada página é realizado pela utilização da tecla de espaço. O comando pode ser terminado em qualquer altura com a tecla
q.
• chmod <modo> <nome>
Muda a permissão de acessos do ficheiro <nome> de acordo com <modo>.
• grep <sequencia><nome>
Lista todas as linhas do ficheiro <nome> que contenham a sequência de caracteres
<sequencia>.
• passwd
Altera a password do utilizador.
• logout
Sair de sessão.
Um comando pode ser interrompido premindo simultaneamente as teclas <ctrl> e c.
3.6
Dispositivos de entrada e saı́da
Os dispositivos de entrada e saı́da são tratados no sistema UNIX como ficheiros de caracterı́sticas especiais (special files). A cada dispositivo de entrada/saı́da está geralmente associado
um ficheiro do directório /dev. Por exemplo, a escrita ou leitura do terminal de trabalho (seja ele
real ou uma janela virtual) pode ser escrevendo ou lendo o ficheiro /dev/tty. Este tipo de organização permite uma flexibilidade muito grande no desenvolvimento e utilização de aplicações.
R EDIRECCIONAMENTO 35
3.7
Redireccionamento
A todas as aplicações de UNIX são automaticamente associados dois dispositivos de saı́da e
um de entrada:
• standard output Dispositivo de defeito para saı́da de mensagens. No caso de uma sessão no
terminal, este dispositivo é, por defeito, o monitor do terminal
• standard error Dispositivo de defeito para saı́da de mensagens de erro. No caso de uma
sessão no terminal, este dispositivo é, por defeito, o monitor do terminal.
• standard input Dispositivo de defeito de entrada de dados. No caso de uma sessão no terminal, este dispositivo é, por defeito, o teclado do terminal.
Em qualquer dos casos (teclado/monitor), estes dispositivos correspondem ao ficheiro especial
/dev/tty.
Frequentemente, é conveniente alterar um ou mais dos dispositivo de defeito anteriormente
indicados. A especificação de um dispositivo entrada/saı́da alternativo pode ser efectuado na linha de comando. A especificação de um dispositivo alternativa como standard output efectua-se
adicionando à linha do comando o sı́mbolo > seguido do nome do dispositivo pretendido:
$ <comando> <flags e argumentos>
>
<dispositivo de saı́da>
Considere-se, por exemplo, o caso do comando ls. Como descrito anteriormente, este comando lista os ficheiros de um dado directório. Por defeito, este comando produz uma listagem
no terminal (standard output). Se se pretendar criar um ficheiro de nome lista no directório de
trabalho com o resultado da listagem, o comando a utilizar é
$ ls > lista
Se pretender redireccionar conjuntamente o standard output e standard error para um mesmo
ficheiro, pode ser usada a seguinte linha de comando:
$ <comando> <flags e argumentos>
>&
<dispositivo de saı́da>
De igual modo, é possı́vel redireccionar o dispositivo de entrada standard input adicionando
à linha do comando o sı́mbolo < seguido do nome do dispositivo pretendido:
$ <comando> <flags e argumentos>
<
<dispositivo de entrada>
36 A MBIENTE DE TRABALHO EM U NIX
3.8
Pipes
O UNIX possibilita que o dispositivo de standard output de uma aplicação seja ligado directamente ao dispositivo de standard input de uma segunda aplicação pela utilização do mecanismo
de pipe. Este resultado é obtido indicando as duas aplicações em sequência na mesma linha de
comando, separados pelo caracter |. Este mecanismo é equivalente a redireccionar a saı́da da
primeira aplicação para um ficheiro, e utilizar o ficheiro assim criado como entrada da segunda
aplicação.
Recorrendo ao exemplo já dado anteriormente, admita-se que se redirecciona a listagem do
directório corrente para um ficheiro lista, e posteriormente se pretende visualizar o conteúdo do
ficheiro com o comando less. Este procedimento pode ser realizado pela sequência de dois comandos:
$ ls > lista
$ less lista
Exactamente mesmo resultado pode ser obtido, sem a criação do ficheiro lista, pela utilização
de um pipe em que a saı́da do comando ls é automaticamente utilizada como entrada do comando
less.
$ ls | less
Note-se que a utilização de pipes, além de facilitar a especificação de comandos estruturados complexos, é extremamente eficiente dado não implicar a criação de ficheiros temporários
intermédios (toda a comunicação entre aplicações é efectivamente realizada na memória central
da máquina).
Capı́tulo 4
Desenvolvimento de programas
4.1
Introdução
O desenvolvimento de programas em linguagens de alto nı́vel requer um processo de desenvolvimento, teste e aperfeiçoamento que, na maioria dos casos, tem que ser repetido diversas vezes
diversas vezes até se atingir uma versão funcional e estável. Grande parte do software comercial
é sujeito a revisões, melhoramentos e correcções de erros mesmo depois da primeira versão ser
comercializada.
O processo iterativo de desenvolvimento e teste de um programa é designado por ciclo de
desenvolvimento de um programa, e o seu entendimento é fundamental para a compreensão dos
diversos componentes que envolvem od desenvolvimento de um programa numa linguagem de
alto nı́vel.
4.2
Assembly e Linguagens de alto nı́vel
As instruções executáveis directamente por um dado processador têm uma estrutura relativamente simples e variam consoante o modelo e o fabricante. Estas instruções têm formatos relativamente simples e uma ligação próxima ao hardware, designando-se por isso código máquina
do processador. Uma determinada instrução em código máquina pode ter como significado “lê o
conteúdo do endereço de memória 1000 e coloca-o no registo A” ou “testa o conteúdo do registo
B e, se for zero, executa as intruções que se encontram a partir do endereço 21456”.
A linguagem de programação Assembly permite programar em código fonte (ou seja, em
formato de texto) mas usando uma linguagem muito semelhante à do processador. A tradução de
Assembly para código binária é feita por um programa designado Assemblador.
38 D ESENVOLVIMENTO DE PROGRAMAS
Dada a sua proximidade ao hardware, a linguagem Assembly é conveniente para explorar as
potencialidades do processador, mas muito pouco prática para desenvolver estruturas lógicas mais
elaboradas1 . Deste modo, os programas são geralmente desenvolvidos numa linguagem de alto
nı́vel, em que as instruções especificam operações entre entidades lógicas e funcionais abstractas
e independentes do processador. Por exemplo, a sequência de instruções em C
if ( a == b)
x += 5;
else
y = x + 3;
tem um significado próximo do que é de esperar da sua leitura em inglês natural: “compara o
valor das variáveis a e b e, se forem iguais, incrementa a variável x de 5 unidades, senão atribui à
variável y o resultado da adição de x com 5”.
Existem diversas linguagens de alto nı́vel, como por exemplo o C, o C++, o Pascal, o Java,
o Lisp, o Fortran e o Basic, entre outras. Além da maior comodidade de programação, o desenvolvimento de programas em linguagens de alto nı́vel garante que o código desenvolvido seja
independente do processador. A tradução de um programa de alto nı́vel para linguagem máquina
é realizada por um programa designado por compilador. Assim, quando um fabricante desenvolve
um novo processador, é suficiente escrever um compilador para uma dada linguagem de alto nı́vel2
para que o software existente nessa linguagem possa ser executado no novo processador.
O C, o C++, o Pascal e o Fortran são exemplo de linguagens de alto nı́vel compiladas. Nestes casos, o programa é trazudido e só então executado. Alternativamente, existem linguagens
que interpretadas: o programa é lido por um interpretador, que lê o código de alto nı́vel e procede simultaneamente à execução das instruções correspondentes de baixo nı́vel. São exemplo de
linguagens interpretadas o Basic e certos formatos de Java e Lisp.
A execução de um programa compilado é geralmente mais rápida do que a de um programa
interpretado, já que neste último caso o interpretador procede simultaneamente à tradução e à
execução do código fonte. Por outro lado, a inexistência de um passo de compilação explı́cito nas
linguagens interpretadas simplifica a fase de desenvolvimento e teste de um programa.
1
No entanto, a utilização de Assembly foi uma prática generalizada para a escrita de compiladores e sistemas
operativos até à década de 80.
2
Na maioria dos casos, não é necessário re-escrever a totalidade do compilador, sendo suficiente a adaptação de um
já existente.
C ICLO DE DESENVOLVIMENTO 39
4.3
4.3.1
Ciclo de desenvolvimento
Compilação e “linkagem”
O ciclo de desenvolvimento de um programa numa linguagem de alto nı́vel compilada
encontra-se esquematizado na figura 4.1, onde os sufixos dos ficheiros correspondem ao desenvolvimento de um programa C em Unix.
A primeira etapa do desenvolvimento envolve a escrita de um ficheiro de texto (ficheiro ou
código fonte) com as instruções do programa, utilizando um determinado editor de texto. Existem diversos editores de texto disponı́veis em Linux, semdo todos eles adequados à escrita de
programas (ver capı́tulo 5).
O nome do ficheiro fonte é arbitrário, devendo ser escolhido pelo programador de modo a ser
sugestivo da função realizada pelo programa. Além do nome do propriamente dito, o sufixo ou
extensão do ficheiro deve especificar a linguagem de linguagem de programação adoptada: xpto.c
para um programa desenvolvido em C, xpto.cc para o C++, xpto.f para o Fortran ou xpto.p para
o Pascal.
Após esta etapa, o ficheiro fonte é traduzido para o chamado código objecto através do compilador. Em Linux, a compilação de um programa escrito em C é realizada pelo compilador gcc.
Assim, admitindo que o código fonte reside no ficheiro xpto.c, a compilação efectua-se executando
o comando
$ gcc -ansi -pedantic -Wall -c xpto.c
As opções “-ansi -pedantic” indicam ao compilador que só deve aceitar código C-ansi e a opção
“-Wall” que deverá reportar todas as situações potencialmente incorrectas que sejam detectáveis.
A opção “-c” indica que se pretende apenas compilar o ficheiro fonte. Como resultado deste
comando é criado um ficheiro xpto.o com o chamado código objecto. O sufixo dos ficheiros do
código objecto é .o em Unix e .obj em DOS/Windows.
O código objecto é um formato binário, em que as instruções do ficheiro fonte se encontram
já traduzidas em código máquina. No entanto, o ficheiro assim obtido não é ainda um programa
executável porque se encontra geralmente incompleto: a criação de um programa executável exige
normalmente que sejam reunidos ao código objecto módulos pré-compilados no sistema sob a
forma de bibliotecas, os quais são responsáveis pela execução de funções que são idênticas para
vários programas. É o caso, por exemplo, de módulos para a realização de operações de leitura e
escrita de dados ou para o cálculo de funções trigonométricas.
A geração do programa executável realiza-se atravé do chamado linker, designação que não
40 D ESENVOLVIMENTO DE PROGRAMAS
Figura 4.1: Ciclo de desenvolvimento de um programa.
C ICLO DE DESENVOLVIMENTO 41
tem ainda uma tradução bem aceite em Português. Por este motivo, é frequente designar por
“linkagem” a operação realizada pelo linker, embora se trate obviamente de um aportuguesamento
forçado3 .
A “linkagem” de um programa em Unix pode ser realizada pelo comando
$ gcc xpto.o
operação que dá origem a um ficheiro designado a.out com o código executável. Sublinhe-se
que embora a compilação e o “linker” sejam invocados pela execução do mesmo comando (gcc),
este verifica qual a operação a realizar pela análise do sufixo dos ficheiros envolvidos e, caso se
trate de um ficheiro objecto, este é automaticamente passado ao linker (programa ld em Unix). A
vantagem de este ser invocado através do gcc é a junção automática ao processo de “linkagem”
das bibliotecas pré-compiladas da linguagem C que, de outra forma, teriam que ser especificadas
pelo utilizador.
No comando de “linkagem” simples é possı́vel gerar um ficheiro executável com um nome
alternativo a a.out. Assim, o comando
$ gcc xpto.o -o xpto
especifica que o nome do executável deverá ser xpto. Por outro lado, as fases de compilação e
“linkagem” podem ser chamadas conjuntamente com o comando
$ gcc -ansi -pedantic -Wall xpto.c -o xpto
mas deve manter-se presente que este comando realiza as duas operações (compilação e “linkagem”) em sequência.
A execução do programa executável tem lugar por um comando com o nome do ficheiro
executável ou seja
$ a.out
ou
$ xpto
consoante o caso.
3
As traduções literais “ligador” e “ligação”, apesar de serem termos sugestivos da operação realizada, não são
correntes em Português.
42 D ESENVOLVIMENTO DE PROGRAMAS
4.3.2
Erros sintáticos e semânticos
Considere-se que se pretende escrever um programa em C para cálculo do dobro do coseno
de um número e que, para este efeito, se cria um ficheiro “dobro.c” com o seguinte conteúdo’:
/*
*FILE
* dobro.c
*
*CONTENTS
* Programa que calcula o dobro do coseno de um numero
*
*CREATOR/CONTACT
Fernando Mira da Silva, IST ([email protected])
*
*
*/
#include <stdio.h>
#include <math.h>
int main(){
/* Declaração de variáveis */
float x,y;
/* Bloco de instruções */
printf(" Introduza o argumento: ");
scanf("%f",&x);
y = 3.0 * cos(x0);
printf(" O dobro do coseno de %f é %f \n",x,y)
exit(0);
}
A primeira parte deste programa, demarcada pelos caracters /* e */, corresponde à zona de
comentários. A directiva “#include <stdio.h>” é necessária porque o programa utiliza operações
de entrada e saı́da e “#include <math.h>” porque é utilizada uma função matemática (coseno). O
corpo do programa encontra-se entre as chavetas que se seguem a main(). float x,y; indica que o
programa utiliza duas variáveis de tipo numérico real. As instruções printf e scanf são utilizadas
para escrever mensagens e ler variáveis, respectivamente.
C ICLO DE DESENVOLVIMENTO 43
A compilação deste ficheiro com o comando gcc, em vez de produzir o ficheiro objecto,
origina um conjunto de mensagens de erro:
$ gcc -ansi
dobro.c: In
dobro.c:23:
dobro.c:23:
dobro.c:23:
dobro.c:25:
dobro.c:26:
-pedantic -Wall -c dobro.c
function ‘main’:
‘x0’ undeclared (first use in this function)
(Each undeclared identifier is reported only once
for each function it appears in.)
parse error before ‘exit’
warning: control reaches end of non-void function
Os erros reportados pelo compilador derivam dos chamados erros sintácticos, assim designados por corresponderem à não observação de uma ou mais regras sintácticas impostas pela
linguagem. A interpretação das mensagens de erro requer alguma habituação, mas trata-se de um
processo simples desde que seja feita uma leitura atenta do seu conteúdo. Um dos problemas correntes na interpretação das mensagens de erro resulta de, com alguma frequência, estes só serem
detectados depois do local exacto do erro.
As mensagens de erro geradas pelo gcc começam sempre por especificar o nome do ficheiro
e, seguidamente, o número da linha em que o erro foi identificado. Neste caso, o primeiro erro é
detectado na linha “y = 3.0 * cos(x0)”. A mensagem “‘x0’ undeclared” chama a atenção de que
a variável x0 não existe, pelo que aquela linha deverá ser corrigida para “y = 3.0 * cos(x)”. Um
segundo erro é identificado na linha 25 (exit(0);), sendo a mensagem “parse error before ‘exit”’.
De facto, estritamente falando, o erro que existe é na linha anterior, já que falta o “;” obrigatório
no final da instrução “printf(...)”. No entanto, dado que os espaços em branco e mudanças de
linha são sintacticamente irrelevantes em C, o erro só é detectado no inı́cio da instrução seguinte.
Finalmente, a última mensagem, na linha 26, é consequência do erro anterior: a ausência do “;”
leva a que a instrução “exit(0)” não seja identificada e, como tal, o compilador avisa que chegou
ao fim do ficheiro sem ter encontrado esta instrução.
Note-se que a última mensagem surge reportada como aviso (warning) e não como erro. Enquanto que os erros propriamente ditos impedem o programa de ser compilado e executado, os
avios limitam-se a chamar a atenção para potenciais falhas do programa, mas não impedem a sua
compilação e execução. No entanto, salvo em casos excepcionais, os warning correspondem de
facto a erros do programador, devendo ser corrigidos antes da execução do programa.
Após a correcção dos erros sintáticos, a compilação do programa não origina qualquer mensagem, mas o mesmo não sucede com a “linkagem”:
$ gcc -Wall -ansi -pedantic -c dobro.c
$ gcc dobro.o -o dobro
44 D ESENVOLVIMENTO DE PROGRAMAS
dobro.o: In function ‘main’:
dobro.o(.text+0x2e): undefined reference to ‘cos’
collect2: ld returned 1 exit status
Neste caso, existe um erro durante a “linkagem” do programa, indentificável pela mensagem “ld
returned 1 exit status”, e que surge por o linker ld não ter encontrado um componente necessário
ao programa. A mensagem “undefined reference to ‘cos”’ esclarece que o problema resulta da
inexistência do código necessário para o cálculo da função coseno. Este código está disponı́vel,
conjuntamente com outras funções matemáticas e trigonométricas, na biblioteca pré-compilada
libm.a (em Unix, o nome das bibliotecas pré-compiladas tem o prefixo lib e a extensão .a). No
entanto, o uso desta biblioteca deve ser explicitado no comando de linkagem. Assim, por exemplo,
a inclusão de um biblioteca com o nome libxpto.a é feita especificando no comando de “linkagem”
a opção -lxpto. No caso do programa dobro, a inclusão da biblioteca “libm.a” implica a adição da
opção -lm no comando, de modo a obter-se uma “linkagem” sem erros.
$ gcc -lm dobro.o -o dobro
A execução do programa dobro conduz ao seguinte diálogo com o utilzador
$ dobro
Introduza o argumento: 0.1
O dobro do coseno de 0.100000 é 2.985013
$ dobro
Introduza o argumento: 3.1416
O dobro do coseno de 3.141600 é -3.000000
$
Agora, o programa é executado aparentemente sem erros. No entanto, os mais atentos notarão
que o dobro do coseno de 3.1416 deveria ser próximo de 2 e não 3. Uma rápida análise do código
fonte revela que se definiu “y = 3.0 * cos(x)” em vez de “y = 2.0 * cos(x)”. Este tipo de erros,
obviamente não detectáveis pelo compilador, designam-se por erros semânticos.
Os erros semânticos são incomparavelmente mais difı́ceis de corrigir do que os erros
sintácticos, já que derivam de erros na construção do programa e, como tal, não são automaticamente detectáveis.
A detecção e correcção de erros semânticos é geralmente efectuada durante a fase de teste
ou depuração (debug), em que o programador simula situações de funcionamento tı́picas do programa e analisa o seu comportamento. No entanto, em programas de complexidade elevada, a
identificação de erros com base apenas na análise do resultado final do processamento é uma tarefa difı́cil. Em muitos casos, torna-se necessário analisar etapas intermédias do funcionamento
C ICLO DE DESENVOLVIMENTO 45
interno do programa, observando os valores de variáveis e seguindo o fluxo de execução do programa. Os chamados “debuggers” são programas de teste que facilitam significativamente o processo de depuração e de identificação de erros durante o ciclo de desenvolvimento.
4.3.3
Depuração: gdb e ddd
De modo poder ser testado com um debugger, o código fonte deve ser compilado com uma
opção especial (-g), que permite que o ficheiro executável contenha “marcas” legı́veis pelo debugger que permitam fazer uma correspondência entre as instruções do ficheiro executável e do
código fonte. A opção -g, embora seja conveniente durante a fase de teste, gera um programa
executável mais lento e de maior dimensão e, como tal, não deve ser utilziada depois do processo
de depuração ter sido concluı́do. No caso do programa “dobro”, a compilação e “linkagem” com
opção de debug pode ser efectuada com o comando
gcc -g -Wall -ansi -pedantic dobro.c -lm -o dobro
O gdb é o debugger standard da gnu. Para executar o programa “dobro” com o auxı́lio do gdb
deve ser usado o comando
$ gdb dobro
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
(gdb)
Neste ponto, o programa “dobro” não foi ainda executado, já que o debugger requer um comando
especı́fico para esse efeito.
Antes de iniciar a execução do programa, o código fonte pode ser consultado com o comando
l (list) do gdb:
(gdb) l 20
15 int main(){
16
17 /* Declaração de variáveis */
46 D ESENVOLVIMENTO DE PROGRAMAS
18
float x,y;
19
20 /* Bloco de instruções */
21
printf(" Introduza o argumento: ");
22
scanf("%f",&x);
23
y = 3.0 * cos(x);
24
printf(" O dobro do coseno de %f é %f \n",x,y);
Note-se que cada linha de programa é precedida do número da linha no ficheiro. O argumento 20
especifica que devem ser listada as 5 linhas antes e depois da linha 20 do ficheiro.
Uma das principais vantagens do debuger é permitir a execução de um programa linha a linha
ou, alternativamente, até a um determinado ponto especificado por um breakpoint. O comando
(gdb) br 21
Breakpoint 1 at 0x80484b6: file dobro.c, line 21.
indica que ao debugger que deve ser introduzido um breakpoint imediatamente antes da linha 21
de dobro.c. Se, depois deste comando, for dado o comando de execução do programa r (run), o
programa só será executado até à linha 21, parando em seguida:
(gdb) r
Starting program: /ldisks/r015a/fcr/ist/manuais/intprog/dobro
Breakpoint 1, main () at dobro.c:21
21
printf(" Introduza o argumento: ");
Neste ponto, é possı́vel continuar a execução normal do programa, com o comando c (continue),
ou executar o programa linha a linha, com o comando n (next). Neste último caso, ter-se-á, por
exemplo
(gdb) n
22
scanf("%f",&x);
(gdb) n
Introduza o argumento: 0.1
23
y = 3.0 * cos(x);
(gdb) n
24
printf(" O dobro do coseno de %f é %f \n",x,y);
(gdb)
C ICLO DE DESENVOLVIMENTO 47
O conteúdo das variáveis x e y pode ser analisado com o comando p (print). Assim,
(gdb) p x
$8 = 0.100000001
(gdb) p y
$9 = 2.98501253
(gdb)
A continuação do programa até ao final pode ser obtida pelo comando c (continue):
(gdb) c
Continuing.
O dobro do coseno de 0.100000 é 2.985013
Program exited normally.
(gdb)
Embora a utilização de um debugger não permita só por si identificar os erros semânticos de
um programa, a possibilidade de análise das variáveis internas e de execução parcelar do programa
faz desta ferramenta um importante auxiliar ao desenvolvimento e teste de programas.
Se o terminal Unix utilizado tiver disponı́vel o sistema gráfico X, a utilização do gdb pode ser
simplificada pela utilização da interface gráfica ddd. No caso do programa dobro, a execução do
debugger tem lugar pelo comando
$ ddd dobro
dando origem à janela apresentada na figura 4.2.
A janela inicial do ddd encontra-se dividida em duas partes. A parte inferior desta janela
além de permitir interactuar directamente com o gdb, usando os comandos descritos anteriormente, deve ser utilizada para a introdução de dados no programa. Na janela superior, além da
visualização do código fonte, é possı́vel definir breakpoints com o auxı́lio do botão do lado direito
do rato. A execução do programa com os comandos c (continue), r (run), n (next) e s (step) é
facilitada usando a janela auxiliar com os botões de comando.
Durante a execução do programa, o valor das variáveis do programa pode ser consultado
passando simplesmente o rato sobre o nome da variável na janela superior. Caso se pretenda
uma visualização permanente de uma ou mais variáveis, deverá ser aberto um segmento de dados,
seleccionando a opção do menu “View/Data Window”. Após este passo, é suficiente apontar a
48 D ESENVOLVIMENTO DE PROGRAMAS
Figura 4.2: A interface gráfica ddd
C ICLO DE DESENVOLVIMENTO 49
Figura 4.3: A interface gráfica ddd, com o segmento de dados visı́vel
50 D ESENVOLVIMENTO DE PROGRAMAS
variável que se pretende visualizar no segmento do código fonte e, com o botão do lado direito do
rato, seleccionar a opção Display. O valor da variável seleccionada surgirá no segmento superior
(V. figura 4.3).
Para mais informação relativamente à utilização do ddd para depuração de programas, deverá
ser consultado o manual (Foundation, 2000).
4.4
Compilação em módulos separados
Mesmo em programas de de complexidade reduzida, o código fonte pode atingir alguns milhares de linhas. Com o aumento da dimensão do programa, a manipulação do ficheiro com um
editor torna-se progressivamente mais difı́cil, sobretudo quando é necessário localizar determinados blocos ou identificar segmentos em que são utilizadas determinadas variáveis.
De modo a evitar a utilização de ficheiros de dimensão excessiva, a maioria das linguagens
de alto nı́vel permite que o programa seja dividido por diversos ficheiros fonte, os quais são compilados individualmente. A junção dos vários ficheiros objecto é relizada durante o processo de
“linkagem”.
Não existem regras formais para realizar esta divisão, a qual depende em grande parte da
metodologia do programador. No entanto, a divisão do programa não deve ser feita de forma
arbitrária, devendo obedecer a critérios funcionais claros. Uma estratégia possı́vel para planear
esta divisão baseia-se no agrupamento de conjuntos de funções e operações que dizem respeito
a um mesmo tipo de dados. Com esta metodologia, é geralmente possı́vel chegar a conjunto de
módulos que, embora com funções complementares no conjunto do programa, são funcionalmente
independentes entre si.
A correcta identificação dos blocos ou módulos funcionais do programa desde o inı́cio da
análise do problema que se pretende resolver, permite, de um modo geral, simplificar significativamente o processo de teste e desenvolvimento. Com efeito, a identificação de módulos relativamente autónomos permite desenvolver e testar os diversos blocos constituintes do programa
separadamente. Um erro frequente em programadores inexperientes é a estratégia de resolução
horizontal do problema, tentando abordar todos os seus detalhes simultaneamente. Esta metodologia, além de originar programas com uma estrutura lógica e funcional muito mais intrincada,
dificulta significativamente a identificação e correcção de erros.
C OMPILAÇ ÃO EM M ÓDULOS SEPARADOS 51
Figura 4.4: Compilação e “linkagem” de um programa.
52 D ESENVOLVIMENTO DE PROGRAMAS
4.5
Bibliotecas estáticas e dinâmicas
Já se referiu anteriomente que o processo de “linkagem” envolve a junção ao código objecto
de blocos de instruções pre-compilados, disponı́veis no sistema sob a forma de bibliotecas. As
bibliotecas podem ser estáticas ou dinâmicas. Embora o seu funcionamento, para o utilizador,
seja semelhante na maioria das situações, é importante distinguir os dois tipos.
Tanto as bibliotecas estáticas como as dinâmicas são consultadas durante o processo de “linkagem”, sendo identificados os blocos de instruçÕes necessários à execução do programa. No
entanto, enquanto que nas bibliotecas estáticas os blocos assim identificados são incluı́dos de
imediato no ficheiro executável, no caso das bibliotecas dinâmicas esta operação é adiada até à
execução efectiva do programa.
As bibliotecas dinâmicas4 permitem que o código executável tenha menor dimensão e, que o
inı́cio da execução do programa seja, em geral, mais rápido. Este último facto é, aparentemente,
contraditório com a necessidade de completar a “linkagem” no inı́cio da execução. No entanto,
as bibliotecas dinâmicas, sendo idênticas para vários programas, encontram-se já frequentemente
na memória central quando é dado o comando de execução do programa, o que permite que este
tenha inı́cio mais rapidamente.
A maior desvantagem das bibliotecas dinâmicas reside na redução de portabilidade do programa executável entre máquinas distintas. Com efeito, quando um programa executável utiliza
bibliotecas dinâmicas e é copiado de uma máquina para outra é necessário garantir que as mesmas bibliotecas estejam disponı́veis na máquina de destino para que a execução seja possı́vel. O
mesmo não sucede num programa que só utilize bibliotecas estáticas (“linkagem” estática), já que
todo o código se encontra incluı́do no executável.
Na figura 4.4 representa-se graficamente o processo de compilação, linkagem e execução de
um programa constituı́do por diversos ficheiros fontes e envolvendo bibliotecas estáticas (libs1.a,
libs2.a e libs3.a) e dinâmicas (libd1.so e libc.so). Neste exemplo, os comandos de compilação e
“linkagem” poderiam ser, por exmplo,
$
$
$
$
gcc
gcc
gcc
gcc
-Wall -ansi -pedantic -c main.c
-Wall -ansi -pedantic -c modulo1.c
-Wall -ansi -pedantic -c modulo2.c
-ls1 -ls2 -ls3 -ld1 main.o modulo1.o modulo2.o
No comando de “linkagem” não se especifica a biblioteca libc.so porque esta é uma biblioteca
“standard” incluı́da automaticamente na chamdada ao “linker” pelo comando gcc.
4
Em Windows, as bibliotecas dinâmicas são conhecidas pelo nome e sufico dll, proveniente de dynamic loadable
library
O UTILIT ÁRIO make 53
Geralmente, todas as bibliotecas dinâmicas tem uma versão estática equivalente. No caso da
figura 4.4 é provável que o sistema disponha também das bibliotecas estáticas libd1.a e libc.a.
Por omissão, o linker utiliza preferencialmente as versões dinâmicas das bibliotecas. No entanto,
caso se pretenda uma “linkagem” estática, esta é pode ser obtida especificando a opção -static na
linkagem:
$ gcc -static -ls1 -ls2 -ls3 -ld1 main.o modulo1.o modulo2.o
4.6
O utilitário make
Em programas complexos, é frequente o programa fonte ser constituı́do por dezenas de ficheiros. Durante a fase de desenvolvimento, o programador edita estes ficheiros com frequência,
sendo fácil perder o controlo de quais os que foram modificados e que devem ser recompilados, e
os que não foram alteradas e que, como tal, não necessitam deste processo.
Uma primeira solução para este problema é escrever um ficheiro com comandos (designado
por script) de forma a que os comandos de compilação e “linkagem” fossem sempre executados
em sequência para todos os ficheiros. Esta solução, embora razoável em programas de pequena
dimensão, tem o inconveniente de poder ser muito demorada em caso de programas complexos.
Assim, por exemplo, no caso de um programa com 50 ficheiros fonte, não é eficente recompilar 50
ficheiros apenas porque se modificou 2 ou 3. No entanto, chamar o compilador manualmente para
os dois ou três ficheiros modificados, além de ser pouco prático, conduz facilmente a situacões em
que um ou mais ficheiros não são actualizados, originando programas executáveis inconsistentes
com o porgrama fonte.
O utilitário make permite ultrapassar esta dificuldade através de um sistema de regras, especificadas pelo utilziador, combinadas com a comparação das horas de modificação dos vários
ficheiros. Assim, por exemplo, o utilizador pode especificar uma regra que o ficheiro xpto.o deriva
do ficheiro xpto.c por um comando de compilação. Sempre que o comando make é executado,
são comparadas as datas dos ficheiros xpto.o e xpto.c e o compilador será chamado sempre que a
data de alteração deste último for mais recente que a do primeiro.
As regras do utilitário make são escritas num ficheiro especial com o nome makefile. A makefile pode incluir um número ilimitado de regras e pode atingir uma complexidade elevada em
projectos de programação de dimensão elevada. Embora o utilitário make possa ter regras extremamente elaboradas, na sua versão básica cada regra tem uma estrutura simples. Cada regra é
constituı́da por duas linhas. A primeira linha indica a estrutura de depências de um dado ficheiro e
a segunda linha especifica o comando que permite gerar o ficheiro a partir das suas dependências.
A segunda linha da regra distingue-se da primeira por conter obrigatoriamente um caracter de
54 D ESENVOLVIMENTO DE PROGRAMAS
tabulação na primeira posição. Note-se que este caracter é uma fonte frequente de mal entendidos na makefile, já que não é possı́vel distinguir visualmente um caracter de tabulação de uma
sequência de oito espaços em brancos, mas só o primeiro é correcto na segunda linha da regra.
No caso do ficheiro xpto.o referido anteriomente, a correspondente regra da Makefile teria a
estrutura
xpto.o: xpto.c
gcc -Wall -ansi -pedantic -c xpto.c
Basicamente, esta regra especifica que o ficheiro xpto.o depende de xpto.c, enquanto que a segunda
linha especifica o comando que permite gerar o ficheiro xpto.o a partir de xpto.c.
No caso de um programa utilizado como exemplo na secção 4.4, a estrutura completa da
makefile poderia ser a seguinte:
#
#FILE
# makefile
#
#CONTENTS
# Makefile para geração do programa de exemplo
# da secção 4.4
#
#CREATOR/CONTACT
#
Fernando Mira da Silva, IST ([email protected])
#
#
a.out: main.o modulo1.o modulo2.o
gcc -ls1 -ls2 -ld1 main.o modulo1.o modulo2.o
main.o: main.c
gcc -c -Wall -ansi -pedantic main.o
modulo1.o: modulo1.c
gcc -c -Wall -ansi -pedantic modulo1.o
modulo2.o: modulo2.c
gcc -c -Wall -ansi -pedantic modulo2.o
O UTILIT ÁRIO make 55
Após a preparação da makefile, a actualização do ficheiro executável apenas requer a execução
do comando make. Este começa por ler a makefile e, seguidamente, executará a sequência de
operações necessárias para gerar ou actualizar o ficheiro especificado na primeira regra da makefile
(neste caso, a.out). Com excepção da primeira regra, que deve especificar o ficheiro a actualizar
pelo comando make, as regras seguintes têm uma ordem arbitrária.
De forma a simplificar a construção da makefile, algumas regras são automáticas e não precisam de ser explicitadas na makefile. De facto, o utilitário make dispõe de uma regra implı́cita que
indica que um ficheiro com a extensão .o pode ser gerado a partir de um ficheiro com extensão .c
através do gcc. Assim, a makefile do exemplo anterior poderia ser simplificada como se segue:
#
#FILE
# makefile
#
#CONTENTS
# Makefile para geração do programa de exemplo
# da secção 4.4 (versão simplificada)
#
#CREATOR/CONTACT
#
Fernando Mira da Silva, IST ([email protected])
#
#
CFLAGS=-Wall -ansi -pedantic
a.out: main.o modulo1.o modulo2.o
gcc -ls1 -ls2 -ld1 main.o modulo1.o modulo2.o
Neste exemplo, embora se tenham omitido as regras implı́citas de compilação, foi necessário especificar através de uma variável (CFLAGS) quais as opção de compilação que devem ser adoptadas
pela regra implı́cita (por omissão, o compilador é chamado apenas com a flag “-c”, modo que é
desaconselhável em programas novos).
Capı́tulo 5
Editores de texto
5.1
Introdução
Sendo relativamente simples o desenvolvimento de um editor de texto, e sendo este uma ferramenta de uso frequente em Unix, os editores de texto multiplicaram-se de modo a satisfazer os
gostos de vários tipos de utilizadores. emacs, vi, pico e joe são alguns destes editores. Dado que o
código fonte não é mais que um ficheiro de texto, qualquer destes editores pode ser utilizado para
o desenvolvimento de programas em C.
A escolha do editor de texto é uma opção pessoal de cada utilizador. Normalmente, editores
mais sofisticados tendem a requerer uma fase de habituação mais prolongada, mas o investimento
inicial é normalmente recompensado pela maior flexibilidade e facilidades disponı́veis. Para a
programação em código fonte, os modos formatação automática do emacs fazem deste um dos
editores preferidos de muitos programadores.
5.2
5.2.1
O editor emacs
Introdução
O editor emacs foi escrito por Richard Stallman no inı́cio do projecto GNU e tem sido objecto
de um desenvolvimento contı́nuo desde então. Actualmente, é considerado o mais completo e
configurável dos editores de texto disponı́veis em Unix.
Duas caracterı́sticas fazem do editor emacs particularmente atractivo em ambientes de
programação. Por um lado, o emacs dispõe de um sistema de formatação automática para várias
linguagens de programação (entre as quais, o C). A formatação automática é particularmente útil
58 E DITORES DE TEXTO
para identificar alguns erros simples que são correntes em C: parenteses e chavetas não equilibrados, ciclos mal delimitados, etc. Por outro lado, o editor emacs permite chamar directamente um
comando compilação e, caso existam erros, posicionar o cursor no ficheiro fonte próximo do local
onde foi detectado o erro.
5.2.2
Modos de edição e de comando
O emacs é chamado simplesmente com o comando emacs. Se o terminal do utilizador dispuser do sistema X, o emacs é aberto numa janela gráfica, sendo possı́vel utilizar o rato para
posicionar o cursor, seleccionar texto, e aceder aos menus que se encontram no topo superior da
janela.
Após o seu inı́cio, o emacs apresenta uma janela ao utilizador constituı́da por duas partes. A
superior, que ocupa a quase totalidade do espaço visı́vel, corresponde ao buffer de edição propriamente dito. A parte inferior da janela é constituı́da porm uma única linha, onde são introduzidos
os comandos do editor, designado por minibuffer.
Durante a edição, o texto é introduzido da forma habitual no buffer de edição. O acesso ao
modo de comando tem geralmente lugar através de caracteres especiais, através de combinações
especiais de teclas. No seguimento, utiliza-se a notação C- para indicar que a tecla <control>
(ou <ctrl> deve ser premida simultaneamente com o caracter seguinte. Assim, por exemplo, C-c
indica que devem ser premidas simultaneamente as teclas <ctrl> e c. Adicionalmente, o emacs
prevê a existência de uma tecla especial adicional, designada por meta, que permite o acesso a
um segundo conjunto de funções especiais. Assim, vários comandos do emacs são descritos pela
notação M- para indicar que a tecla meta deve ser premida simultaneamente com o caracter seguinte. Assim, por exemplo, M-x indica que devem ser premidas simultaneamente as teclas meta
e c. Em terminais gráficos ou terminais de PC, a tecla meta corresponde às teclas Alt. Em terminais que não tenham disponı́vel a tecla Meta, esta pode ser substituı́da premindo em sequência a
tecla escape (Esc) e a tecla especificada seguinte.
O acesso ao minibuffer pode ser conseguido através da tecla M-x. Na maioria dos comandos,
o emacs regressa automaticamente ao buffer de edição após este ser finalizado. No entanto, caso
seja necessário, o cancelamento do modo de comando é possı́vel com o comando C-G.
5.2.3
Leitura de ficheiros
A leitura de um ficheiro tem lugar com o comando C-X C-F, o qual solicita a indicação do
nome do ficheiro a editar no minibuffer. O comando C-X C-S grava o ficheiro em edição.
O emacs permite a edição simultânea de diversos ficheiros, colocando cada um num buffer de
O EDITOR VI 59
edição separado. O comando C-X C-B lista todos os buffers correntes, enquanto que o comando
C-X B permite mudar o buffer em edição.
5.2.4
Formatação automática
Ao editar um ficheiro com extensão .c, o emacs entra automaticamente no modo C, realizando
uma formatação (indentação) automática do código fonte. Para posicionar o cursor no local correcto ou indentar uma dada linha no modo C basta em qualquer altura de introdução de uma linha
premir a tecla <Tab>.
5.2.5
Compilação e localização de erros
O comando de compilação é chamado com o comando M-C-G, seguido da tecla de <Enter>.
Por omissão, o comando de compilação é make -k, mas pode ser editado em qualquer altura de
forma a adpatá-lo a outra situação.
Quando o comando de compilação é executado dentro do emacs, as mensagens resultantes do
comando surgem dentro de um “buffer” designado compilation. Caso tenha havido erros, o comando “M-x compile-goto-error” posiciona o cursor no código fonte, próximo do erro detectado.
5.3
O editor vi
5.3.1
Introdução
O editor de texto vi é uma aplicação standard do sistema Unix. Embora existam actualmente editores mais sofisticados, o editor vi é ainda extremamente popular devido sobretudo à sua
eficiência e facilidade de manuseamento. No entanto, este editor apresenta algumas caracterı́sticas
distintas das encontradas em editores de texto de outros sistemas, sendo por vezes necessário alguma habituação ao seu modo particular de funcionamento.
O editor vi pode ser invocado pela linha de comando
$ vi <nome do ficheiro a editar ou criar>
Na altura em que é invocado, o vi copia o ficheiro a editar para uma zona de memória designada por buffer de trabalho. Todas as alterações ao ficheiro são efectuadas primeiro nesta zona de
trabalho e só posteriormente copiadas em definitivo para o disco. Este processo ocorre no final da
60 E DITORES DE TEXTO
sessão de edição ou quando explicitamente indicado pelo utilizador, evitando-se assim que erros
graves na edição se traduzam numa alteração irrecuperável do ficheiro em disco.
O editor vi tem dois modos de funcionamento distintos: modo de comando e modo de edição. No modo de comando, o vi aceita sequências de teclas como comandos, executando cada
comando à medida que estes são introduzidos no teclado. No modo de edição, as teclas premidas
correspondem a texto que se pretende inserir no ficheiro, surgindo no monitor os caracteres à
medida que são introduzidos.
A descrição que se segue, embora não exaustiva, descreve a maioria dos comandos necessários
a uma sessão de edição com o vi .
5.3.2
Modo de edição
No inicio de uma sessão de edição, o vi encontra-se no modo de comando. A passagem ao
modo de edição efectua-se pela indicação de um comando especı́fico para este efeito. A passagem
do modo de edição ao modo de comando faz-se premindo a tecla escape em qualquer altura do
processo de edição.
Quando o editor se encontra no modo de comando, a inserção de texto pode efectuar-se, por
exemplo, deslocando o cursor para a zona onde se pretende inserir texto, e premindo a tecla i. A
partir deste momento, o editor entra no modo de inserção, surgindo o texto no monitor à medida
que for sendo introduzido. Note-se que existem outros comandos que permitem passar do modo
de comando ao modo edição (V. secções 5.3.4 e 5.3.6).
Tal como é habitual, a tecla <del> ou <backspace> pode ser usada para corrigir o último
caracter introduzido. No entanto, os caracteres apagados permanecem normalmente no monitor
até serem corrigidos ou se carregar na tecla de <return>. Este modo de funcionamento, embora
pouco usual, minimiza os acessos ao monitor, reduzindo o overhead do processo.
5.3.3
Movimentação do cursor
A movimentação do cursor pode ser realizada no modo de comando pela utilização das teclas
descritas no seguimento. Note que a movimentação do cursor de uma posição em qualquer das
direções efectua-se pelas teclas h, j, k e l as quais se encontram em sequência no teclado.
• h Move o cursor um caracter para a esquerda.
• l Move o cursor um caracter para a direita.
• j Move o cursor um caracter para baixo.
O EDITOR VI 61
• k Move o cursor um caracter para cima.
• k Move o cursor um caracter para cima.
• H Move o cursor para o inicio do monitor.
• M Move o cursor para a linha central do monitor.
• L Move o cursor para a última linha.
• C-D Avança meio écran de texto.
• C-U Recua meio écran de texto.
• C-F Avança um écran de texto.
• C-B Recua um écran de texto.
5.3.4
Inserir texto
Quando se encontra no modo de comando, o vi pode ser colocado no modo de edição utilizando os seguintes comandos:
• i Insere texto antes da posição actual do cursor.
• a Insere texto após a posição actual do cursor.
• o Insere uma linha a seguir à linha corrente.
• O Insere uma linha antes da linha corrente.
• r Substitui o caracter existente na posição do cursor.
• R Substitui caracteres a partir da posição actual do cursor.
5.3.5
Apagar texto
Quando se encontra no modo de comando, o vi pode apagar texto já introduzido com os
seguintes comandos:
• x Apaga o caracter corrente.
• dd Apaga a linha corrente.
• 5dd Apaga 5 linhas, com inı́cio na linha corrente.
62 E DITORES DE TEXTO
• d0 Apaga desde o inı́cio da linha até à posição do cursor.
• dw Apaga desde a posição actual até ao fim da palavra.
• db Apaga desde a posição actual até ao inı́cio da palavra.
• d<ret> Apaga 2 linhas de texto.
O comando u pode ser usado para desfazer (undo) a última operação de apagar texto.
5.3.6
Mudar texto
Os seguintes comandos podem ser usados para substitui texto:
• cw Mudar o texto desde a posição actual do cursor até ao fim da palavra.
• c4w Mudar o texto desde a posição actual do cursor até ao fim da terceira palavra seguinte.
• cb Mudar o texto desde a posição actual do cursor até ao inı́cio da palavra.
• cc Mudar toda a linha corrente.
Ao utilizar os comandos de mudar texto, a linha só é actualizada totalmente após a passagem novamente ao modo de comando. Assim, os caracteres que surgem no écran podem não
corresponder directamente ao estado actual do ficheiro. Por exemplo, se uma palavra pequena for
substituida por outra com maior número de caracteres, os últimos caracteres introduzidos podem
surgir por cima de texto que não se pretende alterar. Ao passar ao modo de comando verifica-se
no entanto que o efeito obtido é o desejado.
5.3.7
Procurar texto
Para procurar um dada sequência de texto no ficheiro, passar ao modo de comando e usar o
comando / seguido da sequência de texto que se pretende procurar e da tecla <return>.
Além deste, os seguintes comandos podem ser usados para procurar texto:
• n Repete a última operação de procura (i. e., usando a mesma sequência de caracteres).
• N Repete a última operação de procura, mas recuando no ficheiro.
O EDITOR VI 63
5.3.8
Substituir texto
Para substituir uma sequência de caracteres por outra podem ser usados os comandos de substituição de texto. Nos exemplos seguintes, admite-se que se pretende substituir a sequência de
caracteres xpto por abdefg. Admite-se que se está inicialmente no modo de comando.
• :s/xpto/abdefg/g Substitui a sequência de caracteres em todo o ficheiro.
• :<endereços>s/xpto/abdefg/g Substitui a sequência de caracteres nas linhas especificadas
do endereço. O endereço pode ser o número de uma linha, aplicando-se neste caso o comando apenas a essa linha, ou dois números de linha separados por um ,. Neste último
caso, a substituição processa-se na gama de linhas especificadas. Como número de linha
podem ser usados, além do valor numérico, os sı́mbolos . (linha corrente) e $ (última linha
do ficheiro). São exemplos da utilização de endereços no comando de substituição:
– :2,.s/xpto/abdefg/g Substitui a sequência de caracteres desde a linha 2 até à linha
actual.
– :.,100s/xpto/abdefg/g Substitui a sequência de caracteres desde a linha actual até à
linha 100.
– :20,$s/xpto/abdefg/g Substitui a sequência de caracteres desde a linha actual até ao
fim do ficheiro.
– :.,.+4/xpto/abdefg/g Substitui a sequência de caracteres desde a linha actual até à
quarta linha seguinte.
– :7s/xpto/abdefg/g Substitui a sequência de caracteres na linha corrente.
5.3.9
Cortar, copiar e mover texto
Sempre que um comando de apagar é usado, o material retirado é colocado numa zona especial
de memória designada por buffer temporário. É a existência deste buffer que possibilita a utilização do comando u (undo), descrito anteriormente.
É possı́vel colocar o texto apagado numa zona alternativa do ficheiro usando o comando put:
• p Insere o texto existente no buffer temporário na posição a seguir ao cursor.
• P Insere o texto existente no buffer temporário na posição anterior ao cursor.
O editor vi permite utilizar 26 buffers alternativos que também podem ser usadas para guardar
texto temporariamente numa sessão de edição. Ao apagar texto, ou ao usar o comando de put, é
64 E DITORES DE TEXTO
possı́vel usar um buffer alternativo fazendo preceder o comando de aspas (”) e de uma letra do
alfabeto. Existem 26 buffers deste tipo, cada um correspondendo a uma letra do alfabeto. Assim,
por exemplo:
• ”h4dd Apaga 4 linhas de texto e colocá-lo no buffer h.
• ”hp Coloca o texto existente no buffer h na posição a seguir ao cursor.
Note-se que, geralmente, é usada uma letra minúscula para designação do buffer. Neste caso,
o conteúdo anterior do buffer, caso exista, é apagado. Se se usar uma letra maiúscula, o texto
apagado é adicionado (sequencialmente) ao texto já ali colocado por comandos anteriores.
Por vezes, é conveniente copiar texto para o buffer temporário ou um buffer alternativo sem
o apagar da posição onde se encontra no buffer de trabalho. Esta operação pode ser obtida com o
comando y, o qual tem exactamente as mesmas variantes do comando d. Assim, para copiar texto
para o buffer temporário podem ser usados os seguintes comandos:
• yy Copia a linha corrente.
• 5yy Copia 5 linhas, com inı́cio na linha corrente.
• y0 Copia desde o inı́cio da linha até à posição do cursor.
• yw Copia desde a posição actual até ao fim da palavra.
• yb Copia desde a posição actual até ao inı́cio da palavra.
• y<ret> Copia 2 linhas de texto.
Tal como anteriomente, é possı́vel usar um buffer alternativo fazendo preceder o comando de
aspas (”) e de uma letra do alfabeto.
5.3.10
Outros comandos
Os seguintes comandos são também frequentemente usados no vi :
• J Junta a linha actual e a próxima.
• C-g Imprime informação sobre o ficheiro a ser editado.
• :w Actualiza o ficheiro
• :w nome Escreve o conteúdo do buffer de trabalho para o ficheiro nome.
O S EDITORES PICO E JOE 65
• :r nome Lê o conteúdo do ficheiro nome para o buffer de trabalho. O texto lido é inserido,
sem sobreposição, ao já existente. O texto é inserido a seguir à linha corrente.
5.3.11
Saı́r
Para abandonar o vi , os seguintes comandos podem ser usados:
• ZZ Actualiza o ficheiro e sai do vi .
• :q Abandona o processo de edição.
• :q! Abandona o processo de edição sem pré-aviso de possı́veis alterações não actualizadas
no ficheiro.
5.4
Os editores pico e joe
Os editores pico e joe são muito menos sofisticados que os editores emacs e vi mas, por este
motivo, a sua utilização é extremamente simples e intuitiva. No caso do editor pico, os códigos de
acesso aos principais comandos surgem sempre nas últimas duas linhas do buffer de edição, pelo
que não é necessário a sua memorização. No editor joe, a linha de topo recorda que a sequência
C-K H dá acesso ao modo de ajuda (help), onde são listadas as sequências de acesso aos principais
comandos.
Embora os editores pico e joe sejam atractivos numa primeira utilização, é necessário ter
em atenção que não têm disponı́veis facilidades importantes como a edição simultânea de vários
ficheiros e, sobretudo a formatação/indentação automática de ficheiros disponı́vel no emacs.
Capı́tulo 6
Textos e manuais complementares
Pretende-se com este texto facilitar uma primeira abordagem ao sistema operativo Unix e a
algumas das ferramentas necessárias ao desenvolvimento de programas neste sistema. Embora se
pretenda que este manual seja tanto quanto possı́vel completo a um nı́vel introdutório, é evidente
que a a diversidade e sofisticação das ferramentas envolvidas não permita a sua condensação num
documento desta dimensão.
Neste capı́tulo apresenta-se um extenso conjunto comentado de materiais bibliográficos cuja
referência detalhada se encontra na secção de “Bibliografia” deste manual. Na sua grande maioria, os tópicos abordados extravasam largamente as necessidades do estudante médio que pretenda
apenas uma primeira abordagem à Programação e ao sistema operativo Unix, pelo que a sua consulta não é de forma alguma obrigatória. No entanto, tratam-se de textos que podem ser úteis
aos leitores mais interessados, para consulta ou para o aprofundamento de conhecimentos relativamente a tópicos especı́ficos.
Na lista de referências que se seguem, deu-se preferência a textos disponı́veis livermente na
internet, a maioria dos quais resultantes do chamado LDP (Linux Documentation Project), o qual
tem por objectivo organizar e sistematizar manuais e guias referentes ao sistema operativo Linux
e software da GNU. É possı́vel aceder a um mirror do LDP no IST em http://ldp.ist.utl.pt/. De
destacar que, além de alguns manuais e guias com a organização habitual de um livro, o LDP
inclui um conjunto extenso de pequenos textos introdutórios a tópicos especı́ficos designados por
HOWTO e que, como o nome indica, são manuais muito simple e curtos que apresentam soluções
(frequentemente em formato de receita, sem grandes aprofundamentos técnicos) para muitos dos
problemas que frequentemente surgem com o sistema operativo Linux (embora a utilidade de muitos extravase o âmbito restrito do sistema Linux). Além de disponı́veis nas páginas do LDP, muitos
destes textos estão por vezes disponı́veis nas máquinas linux sob os directórios /usr/doc/HOWTO
e /usr/doc/HOWTO/mini.
68 T EXTOS E MANUAIS COMPLEMENTARES
6.1
Sistema Operativo Unix e Linux
Para os interessados em instalar Linux num PC, existem hoje em dia diversas empresas que
distribuem pacotes completos de Linux com um conjunto alargado de aplicações open source
incluı́das e cuja instalação é quase automatizada. Entre as mais conhecidas encontram-se a Red
Hat (a mais frequente no IST), Slackware, Debbian, SUSE e a Caldera. Saliente-se que estas
empresas não vendem o software em si, já que este é de distribuição e cópia livre. O preço
destes pacotes, de um modo geral relativemente baixo, destina-se apenas a cobrir os custos de
distribuição, preparação do conjunto e software de instalação e de suporte ao cliente.
Note-se que é possı́vel e simples instalar no mesmo PC dois sistemas operativos, desde que
estes residam em partições distintas. Um bom HOWTO introdutório, fácil e rápido de seguir, é
(Raymond, 2000). Um texto mais completo do LDP para apoio à instalação do Linux é (Welsh e
outros , 1998). Complementarmente, (Greenfield, 1996) constitui um bom manual do Linux para
o utilizador. Um livro que constitui também uma boa condensação do fundamental do Unix na
óptica do utilizador é (Robbins, 1999).
Para os interessados na implementação de sistemas operativos, (Marques e Guedes, 1990) é
um bom texto introdutório, focando vários aspectos do sistema Unix. (Bach, 1986) é geralmente
considerado uma das melhores referências pedagógicas para aprendizagem do sistema Unix, tendo
sido o texto seguida por Linus Torvalds nas fases iniciais da implementação do Linux. Este texto
inclui uma descrição aprofundada de diversos detalhes de implementação do núcleo e do sistema
de ficheiros do Unix, tal como concebido originalmente por Ritchie e Thompson(Ritchie e Thmompson, 1974). Um texto menos académico e mais focado na implementação actual do núcleo
do sistema operativo Linux pode ser encontrado em (Rusling, 1998).
6.2
Ambiente de trabalho
Tal como referido anteriomente, o interpretador de comandos (shell) actualmente mais utilizado no sistema operativo Linux é o bash.
Uma primeira introdução a esta shell pode ser encontrado em (Orr, 1996), que constitui um pequeno HOWTO suficiente para uma primeira abordagem. Um texto mais aprofundado e completo
é o livro (Newham e Rosenblatt, 1998).
Relativamente ao sistema gráfico X11, que serve frequentemente de interface ao sistema operativo Unix, uma primeira abordagem pode ter por base a referência (Brigleb, 1999), uma vez
mais um HOWTO do LDP. Um texto mais técnico e aprofundado sobre o sistema de X11 pode ser
encontrado em (Quercia e O’Reilly, 1993). Embora este livro esteja parcialmente ultrapassado,
P ROGRAMAÇ ÃO E DEPURAÇ ÃO DE PROGRAMAS EM C 69
inclui uma boa descrição dos princı́pios e protocolos ainda hoje adoptados pelo sistema X11.
6.3
Programação e depuração de programas em C
O primeiro livro de divulgação da linguagem C foi publicado por Kernighan e Ritchie em 1978
(Kernighan e Ritchie, 1978). Este texto, pela sua clareza e qualidade, é ainda hoje considerado
uma referência incontornável da linguagem C. Embora sem grandes alterações de forma, este texto
foi revisto anos mais tarde de forma a adaptar-se ao standard ANSI (Kernighan e Ritchie, 1990).
Este livro não é, no entanto, o mais adequado para uma primeira aprendizagem de
Programação. Para este efeito, aconselha-se a referência (Damas, 1999), onde a apresentação
da linguagem C é acompanhada de uma introdução às técnicas de programação procedimental.
Uma referência interessante a nı́vel introdutório do C é também (Oualline, 1997) e, do mesmo
autor, mas para os interessados em explorar o C++, (Oualline, 1995).
A escrita de programas em unix requer a utilização de um editor de texto. Para além do editor
vi, brevemente descrito nestas folhas, existem diversos editores alternativos cuja escolha depende,
em grande parte, do gosto do utilizador. De um modo geral, o editor emacs é considerado o
mais completo disponı́vel no sistema operativo Unix. Embora as suas sequências de comandos
requeiram alguma habituação, a sua utilização é fortemente recomendada. Uma boa introdução
ao emacs pode ser encontrada no HOWTO (Zawodny, 1999). Uma referência mais completa sobre
este editor é (Cameron e outros, 1996).
Informações especı́ficas relativamente ao compilador de C (gcc) utilizado no sistema operativo
Linux podem ser encontradas em (Barlow, 1996). Para a depuração de programas em Linux
utilizando o ddd, é possı́vel recorrer ao manual desta ferramenta (Foundation, 2000), também
disponı́vel na rede. Relativamente ao utilitário make, o seu manual (Stallman e McGrath, 2000)
encontra-se igualmente disponı́vel na rede.
De um modo geral, uma boa referência para uma abordagem integrada da programação em
UNIX/Linux é (Loukides e Oram, 1996). Este manual inclui uma introdução à utilização do editor
emacs, compilador gcc, utilitário make, debugger gdb, além de introduzir a ferramenta RCS para
manutenção de software.
Bibliografia
Bach, M. J. (1986). The design of the Unix Operating System. Prentice-Hall.
Barlow, D. (1996). The Linux GCC HOWTO. LDP - The Linux Documentation Project,
http://ldp.ist.utl.pt/HOWTO/GCC-HOWTO/index.html.
Brigleb, R. (1999). The X Window User HOWTO. LDP - The Linux Documentation Project,
http://ldp.ist.utl.pt/HOWTO/XWindow-User-HOWTO.html.
Cameron, D., Rosenblatt, B., e Raymond, E. (1996). Learning GNU Emacs. Unix series. O’Reilly,
2nd edition.
csn (2000). NT holds up against linux onslaught; others suffer. Client Server News, (337).
Damas, L. (1999). Linguagem C. FCA - Editora de Informática.
Foundation, F. S. (2000). DDD - Data Display Debugger.
http://www.gnu.org/manual/ddd/.
Free Sofwtare Foundation,
Greenfield, L. (1996). The Linux User’s Guide. LDP - The Linux Documentation Project,
http://ldp.ist.utl.pt/guides.html.
Kernighan, B. e Ritchie, D. (1978). The C Programming Language. Prentice-Hall.
Kernighan, B. e Ritchie, D. (1990). The C Programming Language - The ANSI edition. PrenticeHall.
Loukides, M. e Oram, A. (1996). Programming with GNU software. Unix series. O’Reilly &
Associates, Inc.
Marques, J. A. e Guedes, P. (1990). Fundamentos de Sistemas Operativos. FCA - Editora de
Informática.
Newham, C. e Rosenblatt, B. (1998). Learning the bash Shell. Unix series. O’Reilly, 2nd edition.
Orr, G. (1996).
Bash Prompt HOWTO.
LDP - The Linux Documentation Project,
http://ldp.ist.utl.pt/HOWTO/Bash-Prompt-HOWTO.html.
72 B IBLIOGRAFIA
Oualline, S. (1995). Practical C++ Programming. Unix series. O’Reilly & Associates, Inc, 3thd
edition.
Oualline, S. (1997). Practical C Programming. Unix series. O’Reilly & Associates, Inc, 3thd
edition.
Quercia, V. e O’Reilly, T. (1993). Volume 3: X Window System User’s Guide. X Window System
series. O’Reilly & Associates, Inc.
Raymond, E. S. (2000). The Linux Installation HOWTO. LDP - The Linux Documentation Project,
http://ldp.ist.utl.pt/HOWTO/Installation-HOWTO.html.
Ritchie, D. e Thmompson, K. (1974). The unix timesharing system. Commun ACM, páginas
365–375.
Robbins, A. (1999). Unix in a Nutshell: System V Edition. Unix series. O’Reilly & Associates,
Inc.
Rusling, D. A. (1998). The Linux Kernel.
http://ldp.ist.utl.pt/guides.html.
LDP - The Linux Documentation Project,
Stallman, R. M. e McGrath, R. (2000).
GNU Make.
http://www.gnu.org/manual/html node/make toc.html.
Free Sofwtare Foundation,
Tanenbaum, A., Linus Torvalds, K. T., e outros (1993). Debate over Linux/Minix - Exchanged
e-mails. http://www.oreilly.com/catalog/opensources/book/appa.html.
Welsh, M. e outros (1998). Installation and Getting Started Guide. LDP - The Linux Documentation Project, http://ldp.ist.utl.pt/guides.html.
Williams, J. (1993). Hard Drive: Bill gates and the Making of the Microsoft Empire. HarperCollins
Publishers, New York, NY.
Zawodny, J. D. (1999). Emacs Beginner’s HOWTO. LDP - The Linux Documentation Project,
http://ldp.ist.utl.pt/HOWTO/Emacs-Beginner-HOWTO.html.
Download

Introdução ao Sistema Operativo Unix e