Topo

terça-feira, 5 de novembro de 2013

Python: primeiros passos

Neste post vamos fazer uma pequena introdução ao Python, que versão escolher, como instalar, bem como apresentar alguns conceitos básicos e instruções simples.

O Python é uma linguagem relativamente simples, muito bem documentada e fácil de aprender. Além disso possui uma série de bibliotecas que permitem estender imenso a sua funcionalidade. Tem sido das linguagens com maior crescimento nos últimos anos, e está no Top 10 das linguagens de programação mais usadas no mundo.

Que versão usar? Python 2 ou Python 3?


Sendo o Python 3 o futuro da linguagem, neste blogue vamos falar desta versão. No entanto existem algumas razões para que um programador possa escolher o Python 2. A razão mais importante prende-se com o número de bibliotecas disponíveis, que é superior, embora as bibliotecas mais importantes já estejam convertidas para o Python 3. No entanto o Python 3 apresenta muitas melhorias relativamente à versão anterior, tais como um melhor suporte para caracteres que não pertençam à língua inglesa (caracteres com assentos, alfabeto cirílico e por ai fora), clarificação da operação divisão inteira, uso coerente de instruções como o print e o input, etc.

Apesar de nos basearmos em Python 3, nos programas aqui apresentados tentaremos sempre que possível indicar a alternativa em Python 2.

Instalação


O arquivos de instalação do Python em Windows e MacOSX podem ser descarregados em http://www.python.org/, na secção Download, do lado esquerdo. Certifica-te que descarregas a versão correta, 32 ou 64-bits, dependendo do sistema operativo que tens instalado.

Em Linux o Python 2 costuma vir instalado de raiz, mas o Python 3 apenas vem instalado nas distribuições mais recentes. Para te certificares que o Python 3 está instalado (assim como o IDLE, que é o IDE pré-definido do Python), executa o seguinte comando num terminal:

$ sudo apt-get install python3 idle3


O Python interativo


Em Linux, abre um terminal e escreve:

$ python3

No Windows ou MacOSX corre o programa Python (command line), que foi instalado no passo anterior.

Neste momento deverás ter uma janela de terminal preta à tua frente, com um cursor a piscar. O Python, ao contrário das outras linguagens de programação discutidas neste blogue, permite uma interação direta com o utilizador, isto é, podemos ir inserindo comandos, que serão imediatamente processados pelo Python (semelhante ao que acontece com a linha de comando). Esta característica é bastante útil para testar instruções e experimentar código.

Agora que temos o terminal de Python à nossa frente, vamos executar algumas instruções:

>>> x=5
>>> y=2
>>> z=x+y

A primeira instrução atribui o objeto 5 à variável x. A segunda instrução atribui o objeto 2 à variável y. A última instrução atribui o objeto correspondente à soma dos objetos x e y à variável z.

Neste momento já definimos dois conceitos importantes: objeto e variável. Simplificando, as variáveis servem para associarmos nomes a objetos, tal como fizemos nas instruções anteriores, onde associámos os objetos 5, 2 e 7 às variáveis de nome x, y e z, respetivamente. Para sabermos qual o valor do objeto associado a uma variável, podemos usar a função print:

>>> print(z)
7

A utilização do print em Python 2 é ligeiramente diferente, pois não se usam os parêntesis, ou seja, seria print z. Experimenta criar variáveis com outros nomes e com outros valores, experimenta fazer outras operações matemáticas e verifica que resultados obténs. Não há nada melhor que uma boa experimentação para se entender melhor os pormenores de uma linguagem de programação. Algumas dicas:
  • Os números reais têm um ponto a separar a parte inteira da parte fraccionária, por exemplo, 2.35
  • As operações aritméticas suportadas pelo Python são a + (soma), - (subtração), * (multiplicação), / (divisão), // (divisão inteira), % (resto da divisão inteira) e ** (exponenciação) - atenção que no Python 2 a operação / também realiza a divisão inteira se for aplicada a números inteiros.
  • Os nomes das variáveis em Python podem conter letras, números e o caractere '_' (underscore). No entanto não podem começar com um número (por exemplo, altura_2 é um nome válido, enquanto que 3d_altura é um nome inválido). 
  • Os nomes das variáveis em Python não podem ser iguais a certos nomes pré-definidos na linguagem, tais como if, while, for, e por ai fora. 

Os objetos


Os objectos são os elementos básicos que o Python pode manipular. Um objeto é definido por:
  • id - Um número inteiro que identifica unicamente cada objeto, e que se mantém ao longo do programa para esse mesmo objeto. Este número pode ser obtido com a função id().
  • tipo - O tipo de objeto, por exemplo um número inteiro (int), um número real (float), uma sequência de caracteres (string), etc. O tipo de objeto pode ser obtido com a função type(). Experimenta no terminal de Python executar as instruções type(5) e type(3.98), e verifica o resultado obtido.
  • valor - O valor que está associado a um objeto de determinado tipo. Por exemplo, um objeto do tipo float (número real) pode ter o valor 4.5234. Se for possível alterar o valor de um objeto, esse objecto diz-se mutável. Caso contrário o objeto é imutável.
Os objetos podem representar qualquer estrutura de dados, desde a mais simples até à mais complexa. No Python existem quatro tipos básicos de objetos, denominados de escalares, pois são indivisíveis (isto é, não são compostos por mais objetos). Podem pensar nos objetos escalares como os átomos que constituem a linguagem. Os quatro tipos escalares são:
  • int - Representam números inteiros.
  • float - Representam números reais.
  • bool - Representam os valores lógicos True e False (verdadeiro e falso).
  • None - É um tipo com apenas um valor (None), que tem uma funcionalidade específica que analisaremos noutro post.
Os objetos escalares são por definição imutáveis. O contrário não é necessariamente verdade. Por exemplo, uma sequência de caracteres (objeto do tipo string) é imutável (não pode ser alterada), mas não é escalar (é composta por vários objetos mais pequenos, os caracteres).

Alguns exemplos


Podemos obter o tipo de um objeto (também referido como classe de um objeto) diretamente, ou usando o nome da variável à qual esse mesmo objeto está associado.

>>> um_real=22.91
>>> type(22.91)
<class 'float'>
>>> type(um_real)
<class 'float'>

Agora vamos verificar que podemos associar o mesmo objeto a mais do que uma variável.

>>> real1=6.1
>>> real2=real1
>>> id(real1)
140064643951784 

>>> id(real2)
140064643951784

Podemos concluir que as variáveis real1 e real2 estão associadas ao mesmo objecto pois a função id() retorna o mesmo ID para ambas.

É possível alterar o objeto que está associado a um determinado nome. Por exemplo, a variável x pode estar originalmente associada ao objeto do tipo inteiro com valor 5, e posteriormente podemos alterar x para ficar associada ao objecto do tipo inteiro com valor 7.

>>> x=5
>>> id(x)
10188960

>>> x=7
>>> id(x)
10189024

Verifica-se que a variável x está de fato a ser associada a dois objetos diferentes, pois a funcão id() retorna IDs diferentes. Os objetos em si não foram modificados, pois objetos do tipo inteiro são imutáveis, ou seja, não podem ser alterados.

No próximo post


No próximo post vamos criar o nosso primeiro programa em Python. Por outras palavras, em vez de usarmos o Python interativo, onde as instruções que introduzimos são executadas imediatamente, vamos guardar várias instruções num ficheiro e executar esse ficheiro como um programa. Vamos também falar sobre os comentários em Python. Até breve!

domingo, 16 de junho de 2013

Linguagem C: comentários e identação

Um tópico muito importante em C (e em qualquer linguagem de programação) são os comentários. Quando os programas começam a ficar muito grandes, torna-se difícil seguir o raciocínio que o programador utilizou (mesmo que esse programador tenhas sido tu!). Os comentários são blocos de texto normal que inserimos entre as instruções do nosso programa para nos ajudar a seguir a lógica do mesmo. Substitui o código do nosso programa pelo seguinte:
 
/* Em baixo temos uma diretiva de pré-processador */
#include <stdio.h>

/* Vamos começar o nosso programa. */
int main() {
    /* Escrever no ecrã uma frase */
    printf("O meu primeiro programa em C!\n"); /* O \n indica uma nova linha*/
    /* Vamos retornar zero, indicando que correu tudo bem. */
    return 0;
}

Como podes constatar, os comentários em C são colocados dentro de blocos que começam com /* e terminam com */, como por exemplo /* isto é um comentário */. Se compilares e executares o programa vais verificar que os comentários são totalmente ignorados. É uma excelente prática comentar os nossos programas, e algo que aconselho fazerem sempre, seja em projetos para a universidade ou a nível profissional.

Outra boa prática é a chamada identation (não existe uma palavra exata em Português, mas para facilitar vamos chamar-lhe identação). A identação não é mais do que chegar à frente os conteúdos de um bloco. Por exemplo, tudo o que está dentro do bloco da função main está identado com quatro espaços. Desta forma o programa torna-se mais claro e mais fácil de entender. A identação é essencial para que um programa seja minimamente legível. Aqui vamos usar identação de 4 espaços (o chamado estilo Kernighan & Ritchie), no entanto cada pessoa tem a sua preferência, alguns usam 2 espaços, outros usam um tab, e por ai fora. O que interessa é que o nosso programa seja consistente e mantenha a mesma identação do princípio ao fim. Se por acaso tiverem longas partes do vosso código que não estejam identadas, estejam mal identadas ou estejam identadas de forma inconsistente, existem várias formas automáticas de resolver o problema. Deixo duas soluções, uma usando a interface gráfica, outra usando a linha de comandos:
  1. A maioria dos IDEs (ver aqui o que é um IDE) suporta esta operação. Por exemplo, no Code::Blocks, basta ires ao menu "Plugins => Source Code Formatter (AStyle)", e o teu código fica automaticamente identado. Para alterares o estilo de identação efetuada através deste processo, edita as preferências do plugin em "Setting => Editor", e selecionares em baixo "Source Formatter". Como podes verificar, existem vários estilos de identação, e podes inclusive criar um personalizado.
  2. Usando o comando indent. Este comando também suporta uma série de estilos diferentes, bem como personalizações específicas de cada estilo. Após instalares o indent (ver parágrafo seguinte), podes fazer identação automática do nosso primeiro programa usando o seguinte comando:

    $ indent -kr -nut primeiroprog.c

    As opções -kr e -nut indicam que queres usar o estilo Kernighan & Ritchie e que não queres usar tabs, respetivamente. Para veres todas as opções deste comando basta fazeres:

    $ man indent
Nem o Code::Blocks nem o comando indent estão instalados por defeito na maioria das distribuições Linux. Em distribuições baseadas em Debian (Ubuntu, Mint, WattOS, Bodhi, etc.), um simples comando serve para instalar os dois programas de uma só vez:

$ sudo apt-get install codeblocks indent

Seja qual for o estilo que usares, convém seres consistente e usares esse estilo em todo o teu programa. Em situações em que várias pessoas estão a trabalhar no mesmo código, convém definir à partida o estilo usado, de forma a que o resultado final tenha um aspeto coerente.

segunda-feira, 10 de junho de 2013

Linguagem C: o nosso primeiro programa


Neste post vamos voltar a falar do nosso primeiro programa em C, e vamos assumir que o leitor já tem um sistema preparado para compilar e executar programas em C (ver posts anteriores).

Vamos criar uma pasta para colocarmos o nosso código, e vamos abrir o gedit para editar o nosso programa. Para isso abre um terminal, e insere os seguintes comandos (explicações detalhadas de todos estes comandos estão disponíveis nos posts anteriores):

$ mkdir aprender_c
$ cd aprender_c
$ gedit primeiroprog.c &

Agora, faz copy-paste do código em baixo para dentro do gedit, e guarda o ficheiro.
 
#include <stdio.h>

int main() {
    printf("O meu primeiro programa em C!\n");
    return 0;
}

Vamos então por partes. A linha 1 do código contém o seguinte texto:
 
#include <stdio.h>

Este texto não corresponde a código C, mas sim a uma directiva de pré-processador. Não te assustes com o nome. Esta directiva de pré-processador serve apenas para indicar ao compilador que pretendemos usar funções (ou comandos) que estão na biblioteca de funções stdio.h (Standard Input/Output). Esta biblioteca contém funções de entrada/saída de dados, tais como o printf (usado na linha 4, do qual falaremos adiante). Se quisermos usar outros tipos de funções, tais como funções matemáticas ou funções para tratamentos de sequências de caracteres (strings), vamos ter de incluir (#include) mais bibliotecas (math.h no caso das funções matemáticas, e string.h no caso das funções para tratamento de sequências de caracteres). As directivas de pré-processador começam sempre com um cardinal (#), e, ao contrário de todas as expressões e chamadas de função em C, não devem terminar com um ponto e vírgula (;), como acontece nas linhas 4 e 5.

Nas linhas 3 e 6 temos o início e o fim da função principal, main, que é chamada em primeiro lugar assim que o nosso programa é executado.
 
int main() {
}

A palavra-chave int antes do nome da função (neste caso main), indica o tipo de dados que a função vai devolver a quem a chamou. Por definição, a função main devolve sempre um número inteiro. Adiante falaremos melhor sobre os diferentes tipos de dados existentes em C. Tudo o que está entre as chavetas {...} é o nosso programa propriamente dito, que é composto por instruções. As instruções em C devem ser sempre terminadas por ponto e vírgula.

Na linha 4 temos a função printf.
 
printf("O meu primeiro programa em C!\n");

Esta função, na sua forma mais simples, aceita uma sequência de caracteres, e escreve/imprime essa sequência no ecrã. Em C, as sequências de caracteres são definidas entre aspas (ex. "sou uma sequencia de carateres"). Repara nos dois últimos caracteres da sequência que estão dentro do printf. Temos uma barra "\" seguida de um "n". Esta sequência, "\n", indica uma nova linha (new line), e serve para indicar o fim da linha atual e o início de uma nova linha. Vamos ver um exemplo do seu efeito mais à frente. Por último, na linha 5 temos a seguinte instrução:
 
return 0;

Esta instrução indica o fim da função main, e por consequência o fim do nosso programa, devolvendo o valor zero (que é um número inteiro). Neste caso o valor é devolvido ao sistema operativo, e é comum este valor indicar que o programa terminou sem erros.

Agora que temos um entendimento mais completo sobre o nosso programa, vamos compila-lo e executa-lo. Salva o documento no gedit, e na linha de comandos escreve o seguinte:

$ gcc primeiroprog.c -ansi -pedantic -Wall -g -o primeiroprog

Se tudo correr bem, o programa vai compilar sem erros. Antes de executarmos o nosso programa, uma pequena explicação sobre as opções que usámos para o compilador gcc:
  • gcc : Nome do comando de compilação
  • primeiroprog.c : Nome do ficheiro a compilar
  • -ansi e -pedantic : Indicam que o  nosso ficheiro contém código C o mais standard possível, sem extensões mais recentes.
  • -Wall : Pede ao compilador para nos avisar (Warning) de todos (all) os pequenos problemas que possam existir no programa, mesmo que esses problemas não impeçam a compilação.
  • -g : Pede ao compilador para incluir informação de depuração (debug), que nos pode ajudar a resolver problemas usando um depurador (debugger) tal como o gdb, o qual vamos usar mais à frente.
  • -o primeiroprog : Indica ao compilador que o ficheiro executável resultante (output) da compilação deve-se chamar primeiroprog.
Vamos executar o programa da seguinte forma:

$ ./primeiroprog

O resultado será:

O meu primeiro programa em C!

Se removermos o "\n" da cadeia de caracteres dentro do printf e voltarmos a compilar, vamos verificar que no fim da execução do programa o cursor fica situado logo à frente da frase e não por baixo da mesma. Existem outros caracteres especiais em C, como podes ver aqui. Experimenta inserir alguns destes caracteres especiais na cadeira de caracteres, volta a compilar e executar o programa e observa o resultado!

No final do nosso programa retornamos o valor zero, que indica que o programa terminou sem problemas. Após a execução de qualquer comando em Linux podes verificar o resultado retornado usando outro comando:

$ echo $?

Ao executares este comando após teres executado o nosso primeiro programa, vais ver o resultado retornado: zero. Na linha 5 do nosso programa, substitui o 0 por outro valor inteiro, volta a compilar e executar, e logo de seguida corre o comando anterior e verifica o resultado obtido.

Por último o programador deve ter em atenção que o C é case-sensitive, ou por outras palavras, é sensível às maiúsculas e minúsculas. Se por exemplo em vez de escrevermos main, printf ou return, escrevermos Main, PRINTF ou ReTuRn, o programa não vai sequer compilar.

domingo, 26 de maio de 2013

Introdução à linha de comandos: parte III


Neste vídeo vamos de falar de mais algumas ferramentas úteis para a linha de comandos.

Comando man para procurar comandos

Em publicações anteriores falámos do comando man, e sobre como este comando nos pode dar informações sobre todos os outros comandos (incluindo ele próprio!). O problema é que podemos não saber que comando estamos à procura. No entanto o man também nos ajuda nesse aspeto. Para tal, usamos a opção -k. Por exemplo, se quisermos saber que comandos ou programas estão disponíveis para editar texto, podemos executar o seguinte comando:

man -k edit

Dependendo da distribuição de Linux e do software que tivermos instalado podemos ter diferentes resultados. Experimenta com outras palavras-chave!

Comando ln para criar atalhos

Para criarmos um atalho simples, usamos o comando ln na seguinte forma:

ln -s alvo atalho

em que o alvo é o ficheiro ou pasta para o qual queremos criar um atalho e atalho é o atalho propriamente dito. Notar que o alvo e o atalho podem estar em localizações/pastas diferentes.

Transferir documentos e ficheiros da net

Para este efeito usamos o comando wget. Por exemplo, para transferir o logótipo do jornal Público, basta fazer:

wget http://static.publico.pt/files/homepage/img/logo.png

Comando sudo para obter permissões de administrador

Muitas operações requerem permissões de administrador, como por exemplo, instalar e remover programas, ver conteúdos de certas pastas, adicionar e remover utilizadores, etc. Os comandos/operações que requerem este tipo de permissões devem ser precedidos do comando sudo. No entanto é necessário que o utilizador esteja na lista de administradores para que o comando sudo cumpra a sua função (como é sempre o caso do utilizador que instala o sistema operativo).


Comandos para comprimir/descomprimir ficheiros e pastas

Podemos comprimir e descomprimir ficheiros usando comandos tais como zip, unzip, tar, rar e por ai fora.

Em algumas distribuições, comandos como o rar podem não vir instalados de origem sendo necessário recorrer ao apt-get para os instalar, como por exemplo:

sudo apt-get install rar

O comando apt-get, com a opção install, tem como objetivo instalar programas no computador, operação que requer permissões de administrador. Assim sendo, o comando apt-get tem de ser precedido do comando sudo.

Adicionar e remover utilizadores do sistema

É muito simples adicionar e remover utilizadores do sistema usando a linha de comandos. Para adicionar um utilizador chamado Zé, basta fazer:

sudo adduser ze

Para remover esse mesmo utilizador basta executar:

sudo deluser ze

Como são operações que requerem privilégios de administração, os comandos adduser e deluser têm de ser precedidos por sudo.

Alterar a propriedade de ficheiros ou pastas

Esta funcionalidade é implementada através do comando chown (change owner). Por exemplo, se quisermos que o ficheiro teste.txt passe a ser propriedade do utilizador Zé, vamos fazer:

sudo chown ze:ze teste.txt

Normalmente a mudança de propriedade requer privilégios de administração, mas nem sempre é o caso. O nome ze aparece duas vezes: a primeira corresponde ao utilizador propriamente dito, e a segunda ao grupo de utilizadores. Por defeito cada utilizador típico tem sempre um grupo com o mesmo nome.

quarta-feira, 24 de outubro de 2012

Introdução à linha de comandos: parte II

Neste post vamos continuar a falar sobre a linha de comandos, mais especificamente sobre os comandos mais utilizados para interagir com o sistema de ficheiros. No entanto, convém primeiro introduzir alguns conceitos sobre a hierarquia de pastas e sistema de permissões.

Vamos começar pela hierarquia de pastas. Abrimos um terminal, e executamos o  seguinte comando:

$ ls /

O comando ls serve para listar os ficheiros existentes numa determinada pasta, como já referimos em posts anteriores. Ao escrevermos "/" como pasta, estamos a dizer ao comando para listar os conteúdos da raiz do sistema de ficheiros. O sistema de ficheiros é equivalente a uma árvore, em que as pastas e sub-pastas são os ramos da árvore; por sua vez os ficheiros são as folhas da árvore. Assim sendo, a raiz é a base do sistema de ficheiros, ou seja, o tronco da árvore. O comando anterior vai dar algo parecido com o seguinte:

bin    etc             lib         lost+found  proc  selinux  usr
boot   home            lib32       media       root  srv      var
cdrom  initrd.img      lib64       mnt         run   sys      vmlinuz
dev    initrd.img.old  libnss3.so  opt         sbin  tmp      vmlinuz.old

Estas são as pastas e ficheiros que existem na raiz do nosso sistema de ficheiros. Podemos usar o gestor de ficheiros gráfico para ver esta mesma informação. Na grande maioria das distribuições Linux basta clicar no ícone com uma pasta, e clicar de novo, no lado direito, onde diz "File System" ou "Sistema de Ficheiros", tal como indicado na imagem seguinte.


Não é crucial saber o significado de todos estes ficheiros e pastas que estão presentes na raiz do sistema de ficheiros. No entanto, pode ser importante pelo menos ter ideia para que servem três ou quatro destas pastas1. Antes de nos debruçarmos sobre isso, o leitor mais atento reparou que a listagem apresentada pelo comando ls não diferencia entre ficheiros, pastas e atalhos; para isso basta usar a opção "-l" (formato longo), ou "-g" (igual a "-l", mas não especifica o proprietário dos conteúdos). Todas as opções do comando ls podem ser analisadas com o comando man ls, como explicado no post anterior. Repetindo o comando anterior, desta feita com a opção "-l", vamos obter algo parecido com o seguinte:

drwxr-xr-x   2 root root  4096 Oct 19 22:37 bin
drwxr-xr-x   3 root root  4096 Oct 19 22:59 boot
drwxr-xr-x   2 root root  4096 May  6 18:09 cdrom
drwxr-xr-x  17 root root  4140 Oct 23 17:21 dev
drwxr-xr-x 173 root root 12288 Oct 23 17:21 etc
drwxr-xr-x   5 root root  4096 May  6 18:10 home
lrwxrwxrwx   1 root root    32 Oct 19 22:36 initrd.img -> boot/initrd.img-3.5.0-17-generic
lrwxrwxrwx   1 root root    33 Oct 19 22:30 initrd.img.old -> /boot/initrd.img-3.5.0-17-generic
drwxr-xr-x  25 root root  4096 Oct 19 22:42 lib
drwxr-xr-x   2 root root  4096 Oct 19 21:48 lib32
drwxr-xr-x   2 root root  4096 Oct 19 22:42 lib64
lrwxrwxrwx   1 root root    36 Oct 19 22:22 libnss3.so -> /usr/lib/x86_64-linux-gnu/libnss3.so
drwx------   2 root root 16384 May  6 18:04 lost+found
drwxr-xr-x   3 root root  4096 Oct 21 01:28 media
drwxr-xr-x   2 root root  4096 May  7 20:19 mnt
drwxr-xr-x   9 root root  4096 Sep  4 16:17 opt
dr-xr-xr-x 289 root root     0 Oct 23 16:46 proc
drwx------  11 root root  409drwxr-xr-x   2 root root  4096 Oct 19 22:37 bin
drwxr-xr-x   3 root root  4096 Oct 19 22:59 boot
drwxr-xr-x   2 root root  4096 May  6 18:09 cdrom
drwxr-xr-x  17 root root  4140 Oct 23 17:21 dev
drwxr-xr-x 173 root root 12288 Oct 23 17:21 etc
drwxr-xr-x   5 root root  4096 May  6 18:10 home
lrwxrwxrwx   1 root root    32 Oct 19 22:36 initrd.img -> boot/initrd.img-3.5.0-17-generic
lrwxrwxrwx   1 root root    33 Oct 19 22:30 initrd.img.old -> /boot/initrd.img-3.5.0-17-generic
drwxr-xr-x  25 root root  4096 Oct 19 22:42 lib
drwxr-xr-x   2 root root  4096 Oct 19 21:48 lib32
drwxr-xr-x   2 root root  4096 Oct 19 22:42 lib64
lrwxrwxrwx   1 root root    36 Oct 19 22:22 libnss3.so -> /usr/lib/x86_64-linux-gnu/libnss3.so
drwx------   2 root root 16384 May  6 18:04 lost+found
drwxr-xr-x   3 root root  4096 Oct 21 01:28 media
drwxr-xr-x   2 root root  4096 May  7 20:19 mnt
drwxr-xr-x   9 root root  4096 Sep  4 16:17 opt
dr-xr-xr-x 289 root root     0 Oct 23 16:46 proc
drwx------  11 root root  4096 Oct 19 22:26 root
drwxr-xr-x  25 root root   860 Oct 23 17:56 run
drwxr-xr-x   2 root root 12288 Oct 19 22:15 sbin
drwxr-xr-x   2 root root  4096 Mar  5  2012 selinux
drwxr-xr-x   2 root root  4096 Apr 25 17:04 srv
dr-xr-xr-x  13 root root     0 Oct 23 16:46 sys
drwxrwxrwt  19 root root 12288 Oct 23 19:33 tmp
drwxr-xr-x  12 root root  4096 Oct 19 20:00 usr
drwxr-xr-x  14 root root  4096 Oct 23 15:45 var
lrwxrwxrwx   1 root root    29 Oct 19 22:36 vmlinuz -> boot/vmlinuz-3.5.0-17-generic
lrwxrwxrwx   1 root root    29 Oct 19 22:30 vmlinuz.old -> boot/vmlinuz-3.5.0-17-generic

A opção "-l" dá-nos muito mais informação. Aqui fica uma breve explicação sobre o significado desta informação, coluna a coluna, tendo como exemplo a primeira linha:

drwxr-xr-x   2 root root  4096 Oct 19 22:37 bin
  • drwxr-xr-x = A primeira letra indica o tipo de arquivo, enquanto as restante letras indicam as permissões do arquivo (sobre isto falaremos adiante). Sobre a primeira letra, eis os códigos mais relevantes:
    • d= pasta
    • l = atalho (soft link)
    • - = ficheiro
  • 2 = Número de hard links para o arquivo. Se se tratar de uma pasta este valor indica o número de sub-pastas + a própria pasta + a pasta mãe (a pasta em questão, bin, tem o valor 2 pois não tem sub-pastas, ou seja, este valor corresponde a ela própria e à pasta mãe, neste caso a raiz). Se se tratar de um ficheiro, então este valor indica por quantos nomes é conhecido o ficheiro em questão no sistema de ficheiros2.
  • root = Nome do utilizador proprietário do arquivo. Neste caso, root corresponde ao nome dado ao administrador principal de todos os sistemas Linux (também conhecido como super-utilizador).
  • root = Corresponde do nome do grupo a que pertence o utilizador proprietário do ficheiro. Para os utilizadores normais, o nome do grupo a que pertencem é tipicamente igual ao seu nome de utilizador (como é o caso no arquivo em questão).
  • 4096 = Tamanho do arquivo em bytes. Em Linux, as pastas normalmente ocupam 4096 bytes (ou 4 Kb).
  • Oct 19 22:37 = Data e hora de última modificação do arquivo.
  • bin = Nome do arquivo.

Alguma desta informação também pode ser obtida na maioria dos gestores de ficheiros gráficos, bastando para isso carregar nas teclas Ctrl+2 (primeira das imagens seguintes). Se quisermos mais pormenores sobre uma pasta ou ficheiros podemos clicar com o botão direito em cima da respetiva pasta ou ficheiro e selecionar "Properties" ou "Propriedades" (segunda das imagens seguintes).



Voltando à questão das permissões, vamos olhar de novo para a primeira linha da listagem, mais concretamente para a informação na primeira coluna:

drwxr-xr-x   2 root root  4096 Oct 19 22:37 bin

Como já mencionamos, a primeira letra indica o tipo de arquivo. No caso em questão, o arquivo bin é uma pasta, tal como indicado pela primeira letra, d (de directoria). Os restante nove caracteres podem ser divididos em três partes com três caracteres cada, que correspondem às permissões para: 1) o proprietário do arquivo; 2) para o grupo a que pertence o proprietário do arquivo; e, 3) para todos os outros utilizadores. No caso da pasta bin, temos que:
  • rwx = Permissões para o proprietário (owner) do arquivo (utilizador root).
  • r-x = Permissões para o grupo (group) a que pertence o proprietário do arquivo (grupo root).
  • r-x = Permissões para todos os outros (other).
Existem três tipos de permissões. O primeiro caractere de cada parte corresponde à permissão de leitura (read), o segundo caractere é a permissão de escrita (write) e o terceiro caractere é a permissão de execução (execute). O que significam então cada uma destas permissões?
  • read = Permissão de leitura, isto é, é possível ler/aceder aos conteúdos do arquivo.
  • write = Permissão de escrita, isto é, é possível modificar os conteúdos do arquivo ou até mesmo eliminar o arquivo.
  • execute = Permissão de execução, isto é, é possível executar o arquivo como um programa3.
Podemos então concluir que diferentes utilizadores vão estar sujeitos a diferentes permissões para determinado arquivo consoante sejam proprietários (owner), pertencentes ao grupo do proprietário (group) ou outra coisa qualquer (other). Voltando ao caso da pasta bin:
  • rwx = O proprietário (owner), ou seja o utilizador root, pode ler, escrever e executar o arquivo4.
  • r-x = Os utilizadores que pertencem ao grupo (group) de nome root podem ler os conteúdos do arquivo (neste caso, podem fazer ls à pasta) e executar o arquivo (neste caso, podem fazer cd à pasta); no entanto não podem escrever no arquivo (neste caso, não podem adicionar ou remover outros arquivos dentro da pasta).
  • r-x = Os restantes utilizadores (other) têm as mesmas permissões que os utilizadores do grupo (group), ou seja, podem ler e executar o arquivo, mas não podem escrever.
No próximo post falaremos sobre as várias formas de alterar as permissões de pastas ou ficheiros, nomeadamente usando o comando chmod. Além disso, discutiremos ainda a possibilidade de alterar o proprietário (owner) de um ficheiro ou pasta através do comando chown.

Vamos então discutir os comandos mais utilizados para interagir com o sistema de ficheiros. Antes de mais, vamos situar-nos na nossa pasta "Home" (por defeito, ao abrirmos uma nova janela de terminal, vamos estar automaticamente situados na nossa pasta "Home"):

$ cd /home/<o_meu_username>


No Linux, o simbolo "~" significa a pasta "Home" do utilizador atual. Ou seja, o comando anterior é igual a fazer:

$ cd ~

Usando o comando mkdir (make directory) vamos criar uma pasta para fazermos as experiências:

$ mkdir explica

Através do comando cd (change directory) vamos entrar na nova pasta:

$ cd explica

É possível sabermos em que pasta estamos através do comando pwd:

$ pwd


Com o editor de texto nano (podes usar o gedit ou outro editor se preferires), vamos criar um novo ficheiro:

$ nano teste.txt

Queremos encher este ficheiro com texto para fazermos algumas experiências. Seleciona todo o texto deste blog com o rato (ou então faz Ctrl+A que faz automaticamente o select all), faz Editar=>Copiar (ou Edit=>Copy), e voltando ao terminal, clica com o botão direito do rato em cima do terminal e faz Colar (ou Paste) - se tiveres no terminal podes também fazer Ctrl+Shift+V. Agora temos o nosso ficheiro de texto. No nano faz Ctrl+O para guardar o ficheiro e Ctrl+X para sair. Podemos experimentar ver o conteúdo do ficheiro usando o comando cat:

$ cat teste.txt

Era muito conteúdo? Passou muito rápido? Não há problema, podemos usar o comando more ou o comando less para ir vendo o conteúdo do ficheiro linha a linha:

$ more teste.txt
$ less teste.txt

O comando more só permite andar para baixo com a tecla Enter (ou seja, não podemos voltar a ler linhas que já passámos). Por sua vez, o comando less permite andar para trás e para a  frente no ficheiro usando as teclas de direção5.

Se quisermos mudar o nome ao ficheiro, usamos o comando mv:

$ mv teste.txt novonome.txt 

O comando mv faz mais do que mudar o nome a ficheiros. mv é diminuitivo de move, ou seja, o seu propósito é mover ficheiros ou pastas de um lado para outro. Para verificar isto, vamos criar uma nova pasta (dentro da atual pasta "explica"):

$ mkdir uma_subpasta

Agora vamos mover o ficheiro que criámos para esta sub-pasta:

$ mv novonome.txt uma_subpasta

Em vez de mudar o nome do ficheiro, o comando mv moveu o ficheiro "novonome.txt" para o directório "uma_subpasta". Podemos confirmar isto com o comando

$ ls -l 

que nos dará um resultado parecido com o seguinte (repara nas permissões, etc.):

drwxrwxr-x 2 explica explica 16384 Oct 24 22:49 uma_subpasta

Ou seja, vemos a pasta que criámos, mas não vemos o ficheiro "novonome.txt". Vamos entrar na sub-pasta

$ cd uma_subpasta

e fazer de novo

$ ls -l

comando que nos dará aproximadamente a seguinte informação (repara nas permissões, etc.) :

-rw-rw-r-- 1 explica explica 25347 Oct 24 22:49 novonome.txt 

Ou seja, confirmamos que efetivamente o ficheiro foi movido para a sub-pasta. Então e se quisermos apenas copiar o ficheiro (e não movê-lo) ficando com uma cópia do ficheiro na pasta "explica" e outra cópia na pasta "uma_subpasta"? Nesse caso usamos o comando cp (copy):

$ cp novonome.txt ..

O comando anterior copia o ficheiro "novonome.txt" para a pasta mãe da pasta "uma_subpasta", que é a pasta atual. A pasta mãe é é a pasta "explica".

Estamos quase a chegar ao fim deste post, mas antes de terminarmos vamos eliminar os ficheiros e pastas que criámos. Podemos começar pelo ficheiro "novonome.txt":

$ rm novonome.txt

Vamos voltar à pasta anterior, fazendo:

$ cd ..

Agora vamos apagar a sub-pasta...

$ rmdir uma_subpasta

...e a cópia do ficheiro que copiámos para a pasta "explica":

$ rm novonome.txt 

Voltamos agora à pasta anterior (a nossa pasta "Home"):

$ cd ..

E removemos a primeira pasta que criámos:

$ rmdir explica

Não é possível remover pastas que não estão vazias com o comando rmdir (remove directory). No entanto estas remoções poderiam ser feitas de uma assentada usando as opções "r" e "f" do comando rm (remove). Assumindo que estamos na nossa pasta "Home":

$ rm -rf explica

Muito cuidado com as opções "r" e "f". A primeira apaga os conteúdos de todas as sub-pastas da pasta indicada, enquanto a segunda força a remoção de tudo e não pergunta nada. É por isso muito fácil fazer asneira com estas opções.

Hoje ficamos por aqui. Se tiveres dúvidas em alguns dos comandos aqui usados não hesites em usar o comando man para tirar dúvidas. No próximo post falaremos de wildcards, que servem para selecionar vários ficheiros e/ou pastas de uma assentada, bem como de alguns comando úteis tais como o ln, grep, find, sudo, chmod, chown e apt-get.

Até breve!

1Deixo aqui uma lista sucinta sobre os conteúdos de algumas das pastas mais importantes presentes na raiz:
  • /bin = Contém os comandos mais importantes, que podem ser utilizados por todos os utilizadores do sistema. Experimenta fazer ls /bin, e vais imediatamente reconhecer alguns dos comandos presentes.
  • /etc = Contém ficheiros de configuração do sistema e de algumas aplicações instaladas no sistema.
  • /home = Contém as pastas "Home" de todos os utilizadores do sistema. Cada uma destas pastas contém os documentos, imagens, vídeos, música, etc. de cada utilizador. Se fizeres ls /home/<o_teu_username> vais ver todos os ficheiros e pastas presentes na tua pasta "Home". Se fizeres ls ~ vais ter o mesmo efeito, pois o Linux substitui o ~ pelo caminho completo da pasta "Home" do utilizador atual (isto é, substitui o ~ por /home/<o_teu_username>). 
  • /lib, /lib32 e /lib64 = Bibliotecas (conjuntos de funções) essenciais e módulos importantes do núcleo do sistema (kernel). 
  • /mnt e /media = Contém sub-pastas que são mapeadas em sistemas de ficheiros amovíveis (pens USB, CD-ROM, discos externos, etc.).
  • /opt = Pasta onde normalmente são instaladas aplicações externas, isto é, que não estão presentes no AppCenter da distribuição Linux.
  •  /usr = Pasta muito importante do sistema, com dados partilhados entre todos os utilizadores. Estes dados estão divididos em sub-pastas:
    • /usr/doc = Documentação das aplicações instaladas.
    • /usr/share = Ficheiros de configuração, icones, gráficos, etc. das aplicações instaladas
    • /usr/src = Código fonte do software instalado no sistema, incluindo o núcleo (kernel) do Linux.
    • /usr/include = Ficheiros de cabeçalho (com extensão .h) para o compilador C/C++. Estes ficheiros definem as estruturas e constantes que são necessárias para compilar a maioria dos programas. Já usámos um destes ficheiros, chamado stdio.h, no nosso primeiro programa em C.
    • /usr/local = Tem uma funcionalidade semelhante à pasta /opt.
  • /var = Contém ficheiros de dados que mudam permanentemente, tais como spools de impressão, dados de registos (logs) e de admistração e outros ficheiros temporários.
  • /tmp = Contém ficheiros temporários, como por exemplo downloads efetuados com o browser.

2Esta explicação não está inteiramente correcta do ponto de vista técnico. A questão dos hard links em Linux não é muito simples, mas está bem explicada aqui (nomeadamente a diferença para os soft links). Os hard links não são atalhos, mas sim nomes alternativos para uma pasta ou ficheiro. No mínimo um ficheiro tem um hard link (ele próprio), e uma pasta tem no mínimo dois hard links: ela própria e uma referência a ela própria chamada "." (se fizermos ls -a para vermos os arquivos escondidos começados por ".", podemos verificar que existe sempre um "." dentro de todas as pastas, incluindo a raiz; existe também um arquivo chamado "..", que corresponde à pasta mãe da pasta actual - a raiz não tem pasta mãe, logo não tem ".."). Em Linux, os atalhos correspondem àquilo que se designa por soft link, que são na prática ficheiros independentes e que correspondem a atalhos para outros arquivos (ficheiros ou pastas). Tanto os hard links como os soft links são criados com o comando ln.

3O nosso primeiro programa em C é um ficheiro com permissão execute, uma vez que é possível executar/correr o programa. Ao compilar um programa, o comando gcc atribui sempre a permissão execute ao ficheiro gerado.

4
No caso de pastas, a permissão execute significa poder entrar na pasta, ou seja, no caso em questão significa poder fazer cd bin.

5Por isso se costuma dizer que less is more, ou seja, menos é mais...

quarta-feira, 10 de outubro de 2012

Introdução à linha de comandos: parte I

A linha de comandos, também conhecida como interpretador de comandos ou consola, foi uma das primeiras formas de um utilizador poder dar instruções a um computador, antes do aparecimento de qualquer interface gráfica. Hoje em dia, a linha de comandos, que consiste numa interface de texto entre o ser humano e a máquina, continua a ser a mais direta forma de comunicação entre ambos. A interface gráfica não é mais do que um intermediário intuitivo1 e atraente1 entre o utilizador e a linha de comandos2.

Muitas tarefas podem ser executadas na linha de comandos, tais como criar, copiar, apagar, mover e editar ficheiros, alterar a configuração do sistema, criar e remover utilizadores, alterar passwords dos utilizadores, editar imagens, editar vídeos, criar menus para DVDs, gravar CDs e DVDs, ver páginas web, ver e alterar configurações de rede, testar o acesso a servidores remotos, procurar ficheiros e sequências de caracteres dentro de ficheiros no nosso disco, e até programar (pois a própria linha de comando tem uma linguagem de programação, até no Windows!). Certamente que nem todas estas tarefas são muito adequadas para a linha de comandos (editar um vídeo!?), mas garanto que em certas e determinadas situações a linha de comandos pode ser muito prática e produtiva. Nesta primeira série de posts sobre a linha de comandos vou apenas falar de coisas básicas, nomeadamente a gestão de ficheiros, a hierarquia de pastas no Linux, bem como outros comandos simples e úteis. Um bom entendimento destas questões é essencial para um bom programador.

Vamos começar então pelo sistema de ficheiros, bem como a sua listagem. Vamos abrir o gestor de ficheiros, que automaticamente nos vai situar na pasta "Home". Nesta pasta vamos ver as típicas sub-pastas contendo o ambiente de trabalho (desktop), os vídeos, imagens, etc. Agora abrimos um terminal, de modo a acederemos à linha de comandos. Por defeito, o terminal também é inicialmente aberto na tua pasta "Home". No terminal escreve:

$ ls

No linux Mint vais ver algo parecido com a imagem seguinte (noutras distribuições deverás ver algo muito semelhante):


Podemos verificar que o comando ls fornece a mesma informação que o gestor de ficheiros gráfico, embora numa forma puramente textual. Quando executado sem mais parâmetros, o comando ls (diminutivo de list) lista os conteúdos da pasta atual (neste caso, a pasta "Home"). No entanto podemos adicionar vários parâmetros para modificar a informação retornada pelo ls. Por exemplo, para mostrar o conteúdo em forma de lista, com informação adicional sobre cada ficheiro, podemos fazer:

$ ls -l

Para mostrar o conteúdo da sub-pasta "Videos" (assumindo que estamos na pasta "Home"), podemos fazer:

$ ls Videos

Numa instalação recente de Linux o mais certo é a pasta "Videos" estar vazia. Podemos ainda juntar os dois parâmetros anteriores para listar o conteúdo da sub-pasta "Videos" em forma de lista:

$ ls -l Videos

É muito fácil obter ajuda para os comandos existentes. Para isso basta usar o comando man (manual de referência), que coloca no ecrã o manual do comando que quisermos. Para obter ajuda para o comando ls, fazemos:

$ man ls

Podemos inclusive obter ajuda para o próprio comando man! Para isso basta fazer:

$ man man

A informação devolvida pelo comando man pode por vezes parecer confusa, mas uma leitura mais aprofundada dá sempre resultado. Nomeadamente, ao executarmos o comando anterior, obtemos a explicação de como interpretar a sinopse (resumo) de qualquer comando. Basicamente, indica o seguinte:

  • texto negrito »» escrever exactamente como indicado.
  • texto sublinhado »» substituir com argumento apropriado.
  • [-abc] »» quaisquer argumentos dentro de [ ] são opcionais. 
  • -a|-b »» opções delimitadas por | não podem ser usadas em simultâneo. 
  • argument ...  »» argumento pode ser usado várias vezes. 
  • [expression] ... »» toda a expressão dentro de [ ] pode ser usada várias vezes.

No manual do ls podemos verificar que a sinopse deste comando é:

ls [OPTION]... [FILE]...

Ou seja, podemos concluir que:
  • ls deve ser escrito exactamente como indicado, pois está a negrito.
  • Todos os argumentos do ls são opcionais (estão dentro de [ ]).
  • Todos os argumentos do ls podem ser usados várias vezes, devido às reticencias...
  • Os argumentos indicados devem ser substituídos pelo argumento certo, pois estão em texto sublinhado (no exemplo mais atrás substituímos OPTION por -l e FILE por Videos).

Vamos experimentar ver o manual dos comandos que executamos no post anterior:

$ man sudo
$ man apt-get
$ man gedit
$ man mkdir
$ man gcc


Talvez seja mais fácil perceber algumas das coisas que fizemos. É de notar que o comando cd não tem manual, visto que é demasiado simples, pois basta fazer cd pastaDeDestino. Sugiro ainda a leitura ou observação rápida do manual dos seguintes comandos comuns e/ou essenciais:

  • rmdir - Remover pasta
  • rm - Remover ficheiro(s)
  • mv - Mover ou renomear ficheiros ou pastas
  • cat - Ver o conteúdo de um ficheiro
  • zip/unzip - Comprimir/descomprimir um ficheiro .zip
  • pwd - Ver o caminho completo da pasta atual
  • ps - Ver processos/programas em execução
  • kill - Terminar um processo em execução
  • passwd - Alterar a password de utilizador

No próximo post falarei mais em pormenor sobre a gestão de ficheiros, nomeadamente os comandos para esse efeito, a hierarquia de pastas e o sistema de permissões. Em princípio serão um total de três ou quatro posts sobre a linha de comando, antes de voltarmos ao nosso primeiro programa em C.

Até breve!

1Discutível e depende do caso.

2As interfaces gráficas usam a linha de comandos de uma forma escondida do utilizador, seja no Windows, MacOS X ou Linux. Por exemplo, no Linux Mint, podemos ver que comando é na realidade executado ao clicarmos em qualquer aplicação na interface gráfica: Menu => Preferências (ou Preferences) => Menu Principal (ou Main Menu). A aplicação que acabámos de abrir serve para organizar o nosso menu (raramente o precisamos de fazer, mas em todo o caso temos essa opção). Se clicarmos onde diz "Internet", e clicarmos duas vezes em cima de "Firefox Web Browser", aparece-nos uma nova janelinha com vários campos, um dos quais diz "Comando" (ou "Command"). Podemos ver que o comando a executar é firefox %u, em que o %u é substituído por um endereço web (URL) na altura da execução (ver imagem em baixo). Para verificares isto, abre um terminal e escreve firefox www.publico.pt. Senão quiseres que o terminal pendure à espera que o Firefox termine a execução, podes escrever firefox www.publico.pt &, tal como indiquei no post anterior. Notar que a forma de organizar o menu principal pode variar de distribuição para distribuição.


sábado, 6 de outubro de 2012

Preparar o PC para aprender C: parte II

Vamos então finalizar a configuração do sistema Linux para que possamos escrever o primeiro programa em C. Vou assumir que o leitor deu uma olhada no post anterior e está a usar uma versão do Linux baseada em Debian, como por exemplo o Ubuntu, Mint, Bodhi ou Pear1.

Antes de começarmos a programar, temos de verificar se o software necessário para esse efeito está instalado, e isso leva-nos temporariamente a outro tópico: a gestão e instalação de programas em Linux. A boa notícia é que, regra geral, é muito mais fácil instalar e desinstalar aplicações em Linux do que, por exemplo, em Windows. Por outro lado, a enorme quantidade de maneiras de realizar essa tarefa pode confundir o utilizador inexperiente. Vamos então tentar simplificar: cada distribuição de Linux tem o seu gestor gráfico de aplicações e pacotes (o seu "AppCenter" em linguagem corrente), cujo objetivo é apresentar, instalar e remover o software disponível (99% do qual gratuito e aberto) de forma apelativa; por exemplo, o Ubuntu tem o Ubuntu Software Center, enquanto o Mint tem o Mint Software Center. Existe no entanto um programa comum a todas as distribuições, embora menos "bonito", e que faz a mesma coisa: chama-se Synaptic Package Manager e vem instalado de raiz em algumas distribuições (e caso não venha, é fácil instalar). Todos estes diferentes "AppCenters" não são mais do que interfaces gráficas para o sistema base de gestão de aplicações e pacotes, chamado Apt. O Apt faz parte do núcleo duro do Debian e seus derivados, e vem sempre instalado de raiz. Ao contrário dos restantes "AppCenters", o Apt é usado através da temível linha de comando. Vou usar o Apt na demonstração da instalação de quaisquer aplicações (que neste post são as aplicações necessárias para programarmos em C). No entanto é bom ter a noção de que instalar ou remover um programa usando o Apt tem exatamente o mesmo efeito que fazê-lo com o Ubuntu Software Center, Synaptic, etc. (por exemplo, se instalarmos um programa com o Apt, esse mesmo programa vai aparecer como "Instalado" no Ubuntu Software Center).

A primeira coisa que temos de verificar é se o sistema básico de desenvolvimento de programas está instalado. Algumas distribuições trazem este sistema instalado de raiz, mas outras mais minimalistas (como o Bodhi) nem por isso. Vamos então usar o Apt para instalar (ou confirmar se está instalado) o sistema de desenvolvimento de programas. Para tal, basta abrir a linha de comandos2, e escrever (não meter o $!):

$ sudo apt-get install build-essential

Este comando pode ser críptico para quem não está habituado ao Apt, mas é na realidade bastante simples: estamos a pedir ao Apt para instalar o build-essential, que é o nome do pacote que contém o sistema básico de desenvolvimento de programas. O comando sudo indica que o Apt deve ser executado em modo super-utilizador/administrador, o que normalmente implica a solicitação da palavra-passe ao utilizador. No próximo post vou falar sobre sobre a linha de comandos (incluindo o Apt), pois trata-se de um tópico muito importante para quem deseja perceber como um computador funciona na realidade. Caso o build-essential já esteja instalado, o Apt vai indicar uma mensagem do género:

build-essential is already the newest version.

Caso contrário, o Apt vai pedir confirmação para instalar o pacote e as respectivas dependências3. Estamos prontos para escrever o nosso primeiro programa em C. Para criar o programa é necessário um editor de texto, de preferência com realce de sintaxe, para facilitar a escrita desse mesmo programa. Todas as distribuições de Linux costumam trazer três editores de texto, dois baseados na linha de comando (nano e vi4) e um com interface gráfica. O Ubuntu e o Mint trazem o gedit por defeito, embora distribuições mais leves normalmente optem pelo LeafPad ou MousePad, que são bastante limitados. Caso não encontrem o gedit nos menus da vossa distribuição Linux, é fácil instalar usando o Apt no terminal (ou a tua "AppCenter" preferida):

$ sudo apt-get install gedit

Neste blog vou usar o gedit a maior parte das vezes, pois é rápido, simples e realça a sintaxe de todas as linguagens de programação que vão ser discutidas neste blog. Além disso, o gedit não esconde os detalhes do desenvolvimento do software, e permite ao programador iniciante entender completamente o que se está a passar, ao contrário de alguns IDEs5. As distribuições baseadas no ambiente gráfico KDE6 (tais como o Kubuntu) normalmente trazem o editor Kate, que é do mesmo nível de qualidade do gedit, ou até superior;  caso optem por usar o ambiente KDE, podem perfeitamente usar o Kate em vez do gedit.

Vamos então escrever o nosso primeiro programa em C. Abre um terminal e cria uma pasta onde vamos colocar o nosso primeiro código C:

$ mkdir aprender_c

O comando anterior significa "make directory", ou seja, cria uma pasta ou diretoria. Em seguida vamos para "dentro" dessa diretoria:

$ cd aprender_c

O comando anterior significa "change directory" e vai-nos colocar "dentro" da pasta que acabamos de criar. Em seguida vamos criar o nosso programa em C usando o gedit (ou o teu editor preferido):

$ gedit primeiroprog.c &

O comando anterior invoca o editor gedit, que vai assumir um novo ficheiro chamado primeiroprog.c, localizado na pasta que acabamos de criar. O caractere & no final do comando indica que queremos voltar a ter o controlo do terminal após invocar o gedit (se experimentares o mesmo comando sem o & no fim, vais verificar que o terminal fica bloqueado até fechares o gedit). Obviamente, também é possível invocar o gedit diretamente através do menu, e guardar posteriormente o novo ficheiro na pasta criada. Agora, faz copy-paste do código em baixo para dentro do gedit, e guarda o ficheiro.
 
#include <stdio.h>

int main() {
    printf("O meu primeiro programa em C!\n");
    return 0;
}

Agora vamos compilar o programa, ou por outras palavras, vamos transformar o nosso código C num ficheiro executável. Para tal, executa o seguinte comando no terminal:

$ gcc primeiroprog.c -ansi -Wall -pedantic -g -o primeiroprog

Em princípio não deverás ter erros neste processo. Vamos então executar o nosso programa:

$ ./primeiroprog

O resultado deverá ser:

O meu primeiro programa em C!

Sucesso! Não te preocupes se não percebeste estes últimos passos do processo. Estamos apenas a verificar se o nosso sistema Linux está de facto preparado para desenvolvermos programas em C. Vamos voltar a este primeiro programa mais tarde e dissecar ponto por ponto o que cada um dos passos indicados significa.

Até breve!

1 Não referi estas duas últimas distribuições no meu último post, mas resumindo muito rapidamente, o Bodhi Linux é super-leve e minimalista (usa uma interface gráfica chamada Enlightenment), sendo necessário instalar praticamente tudo o que o utilizador quer usar. Por usa vez, o Pear Linux é basicamente o Ubuntu com uma interface Gnome-shell personalizada para se parecer com a interface do MacOS X.

2 A aplicação Terminal dá-nos acesso à linha de comandos. No Ubuntu ou no Mint basta carregar na tecla "Start" (com o logotipo do Windows, entre o Ctrl e o Alt, do lado esquerdo), começar a escrever "Term...", e a aplicação Terminal aparece logo. Noutras distribuições, o terminal pode ser acedido através do menu "Acessórios => Terminal". Por vezes as distribuições trazem diferentes tipos de aplicações Terminal, que podem ter nomes como LXTerm, Terminology, Konsole, ROXTerm, Sakura,  XTerm, etc. Normalmente é possível invocar a aplicação Terminal em qualquer distribuição pressionando as teclas Ctrl+Alt+T.

3 Muitos programas dependem bibliotecas ou aplicações de terceiros para funcionar, evitando assim "reinventar a roda" para realizar algumas das suas funcionalidades (o mesmo acontece no Windows através dos ficheiros .dll, que por vezes dão problemas e conflitos). Nos sistemas modernos de Linux todas as dependências das aplicações disponíveis nos repositórios são geridas automaticamente pelo Apt (ou pelo "AppCenter" que estivermos a usar), poupando muitas preocupações ao utilizador.

4 O vi, bem como a sua versão melhorada, vim, são editores de texto do mais diferente e estranho que se possa imaginar. Inicialmente são totalmente contra-intuitivos, porém, os fiéis juram a pés juntos que após dominar um ou outro, a produtividade na programação mais que duplica. Não sei se isto é verdade, pois eu não uso nem um nem outro, mas fica a dica.

5 IDEs - Ambientes de desenvolvimento integrado tais como o Eclipse, NetBeans, Code::Blocks ou Kdevelop (ou o Visual Studio no Windows), podem facilitar e acelerar imenso o desenvolvimento de software; porém, para o programador iniciante, os IDEs podem complicar mais do que simplificar, pois ofuscam detalhes importantes do que está na realidade a acontecer, tornando difícil a resolução de certos problemas. Na minha opinião, o programador só deverá começar a usar um IDE quando dominar minimamente a linguagem de programação em questão (especialmente C); até lá, a melhor opção é usar um editor simples tipo gedit para editar o código juntamente com a linha de comando para compilar e executar os programas desenvolvidos. Existe um programa chamado Geany, que oferece algumas facilidades de um IDE sem esconder a complexidade do desenvolvimento de programas (tem inclusive uma linha de comando incorporada...). Todos estes IDEs podem ser instalados na tua distribuição de Linux através da tua "AppCenter" preferida (Apt, Synaptic, etc...).

6 O KDE consiste num ambiente gráfico, bibliotecas gráficas e conjunto de aplicações para Linux. A sua interface é das mais avançadas hoje em dia, embora nem toda a gente o aprecie. Os seu principal concorrente é o Gnome 3 (bibliotecas gráficas + conjunto de aplicações), embora este esteja fragmentado em vários ambientes gráficos tais como o Gnome-shell (ambiente gráfico por defeito no Gnome 3), Unity (ambiente gráfico do Ubuntu) e Cinnamon (ambiente gráfico do Mint).