Diferente do que ocorre no Windows, no Linux precisamos recorrer com frequência ao terminal para resolver problemas e executar tarefas. Através dele, podemos executar todo tipo de programas, monitorar o sistema, configurar aplicações, e etc. Em muitos casos, é simplesmente mais fácil resolver algo pelo terminal do que pelo ambiente gráfico. Mas se você ainda está adentrando o universo Linux e se sente meio perdido com terminal, não se desespere, pois nesse post vou apresentar os comandos e mecanismos básicos para você sobreviver no shell Linux.

Shell, linha de comando, console, terminal… qual é o certo?

Mais acima, eu falei sobre terminal e shell como se fossem a mesma coisa. E, de fato, muita gente fica na dúvida sobre qual é a diferença entre shell e terminal. Em muitos casos acabamos usando os dois termos de forma intercambiável. Porém, existe uma diferença entre os dois.

Grosso modo, o terminal diz respeito à interface do usuário com o sistema operacional, que se dá basicamente através de entrada e saída de texto. Já o conjunto de dispositivos físicos que possibilitam essa comunicação (geralmente, teclado e monitor) também são chamados de console.

Acontece que geralmente existe um programa responsável por fazer o meio de campo entre o usuário e o sistema operacional. Esse programa é responsável por traduzir instruções do usuário em solicitações ao sistema operacional para realizar as tarefas desejadas. E é a ele que chamamos de shell.

O shell segue mais ou menos a lógica do REPL: Read, Evaluate, Print Loop (ciclo de leitura, execução e impressão). Ou seja, ele espera uma entrada do usuário, executa as ações necessárias, imprime o resultado e volta a esperar por outra entrada do usuário (eu disse “mais ou menos”, porque o shell é um pouco mais complexo que isso). Mas a parte importante é essa: o shell é um programa de computador!

Como a interação com o shell se dá a partir de linhas de comando, é comum tomar o todo pela parte e chamar o shell simplesmente de linha de comando. Entretanto, pode-se dizer de qualquer programa que utilize esse tipo de interação por linhas de comando (como o interpretador interativo do Python ou Scheme), que ele possui uma interface de linha de comando, ou cli (command line interface), em oposição a uma interface de usuário gráfica ou gui (graphical user interface).

Nos dias de hoje, geralmente não lidamos diretamente com um terminal. Ao invés disso, costumamos fazer uso de algum ambiente de área de trabalho, como GNOME, LXQt, Unity, ou KDE, que proveem uma interface gráfica para a utilização do computador. Nesse caso, para acessar o shell, usamos algum emulador de terminal, como xterm ou qterminal, que não são o terminal propriamente dito, mas apenas um meio de acessar o shell através do desktop, como se fosse um terminal.

Nesse post, vou falar um pouco sobre como utilizar o Linux shell. Para isso, você pode utilizar o emulador de terminal da sua distro Linux. Para acessá-lo, tente pressionar ctrl+alt+t, ou localizá-lo numa aba “Sistema” do seu ambiente desktop (se não encontrar, faça uma busca por instruções específicas para sua distro!). Então vamos lá!

Exploração e manipulação de arquivos e diretórios no Shell Linux

Assim que você abre o emulador de terminal, você se depara com um prompt, que é uma linha de texto em que o cursor está posicionado e que espera por alguma entrada. Mas antes de conseguir fazer qualquer coisa útil, como manipular um arquivo ou diretório no Linux, você precisa saber como endereçá-lo. Ou seja, como se pode chegar a esse arquivo, em primeiro lugar.

Para isso, é necessário entender um pouco sobre a estrutura de diretórios do Linux (e de qualquer sistema Unix-like). Para acessar qualquer arquivo ou diretório no shell, precisamos indicar a sequência de diretórios que é preciso percorrer para chegar até ele.

Cada diretório é separado por uma barra (‘/’), e a sequência de diretórios deve ser separada do nome do arquivo por uma outra barra (‘/’). A string formada pela junção da sequência de diretórios com o nome do arquivo (se este existir) é chamada de path (que é o caminho propriamente dito até o arquivo ou diretório). Alguns exemplos de caminhos:

/home/foobar/Documentos/fb.txt /usr/bin Musicas/Ramones/ Documentos/Códigos/Python/script_boladao/main.py

Daqui a pouco você vai entender porque alguns desses caminhos começam com uma barra e outros não!

O comando pwd (descobrindo o caminho do diretório corrente)

A shell sempre “está” em algum diretório, que é o chamado diretório de trabalho atual, ou current working directory (cwd). Por padrão, quando você inicia uma sessão na shell, o cwd é o diretório home do usuário atual. Geralmente, existe um prefixo na linha de comando da forma “usuário@grupo: diretório atual$, que você pode usar para saber em que diretório você se encontra (nota: o diretório home do usuário atual costuma ser abreviado para ~). Caso esse caminho não seja exibido, você pode descobrir o cwd através do comando pwd (Print Working Directory).

O comando ls (descobrindo o conteúdo de um diretório)

Para descobrir que arquivos e diretórios existem no diretório atual, você ṕode utilizar o comando ls. Esse comando irá listar todos os arquivos e diretórios (não ocultos) contidos no diretório atual.

O comando cd (navegando pelos diretórios)

O comando cd (change directory) altera o diretório de trabalho atual da shell. Em outras palavras, usamos cd para mudar de diretório. Para isso, precisamos digitar cd seguido do endereço do diretório para o qual desejamos ir. Se você se encontra no diretório home, digitando ls, você deve encontrar os nomes dos subdiretórios do home, como Documentos, Desktop, Imagens, etc. Então, se você quiser acessar o diretório Documentos, basta digitar:

cd Documentos/

Agora, digitando ls de novo, você verá uma lista com os arquivos e diretórios que existem em Documentos. Você também pode verificar que mudou de diretório checando o prefixo da linha de comando ou utilizando pwd.

Caminhos relativos e caminhos absolutos

Agora, suponha que em Documentos existe um diretório chamado Foo, que por sua vez contém um diretório chamado Bar. Você poderia pular para o diretório Bar, a partir do diretório Documentos, com o comando:

cd Foo/Bar/

Perceba que o ponto de referência do comando cd é relativo ao diretório no qual você se encontra. O raciocínio é: “a partir do diretório atual, entre no diretório Foo, e depois no diretório Bar É por isso que esse tipo de caminho é chamado de caminho relativo (relative path).

Mas você também pode se referir a um arquivo ou diretório através de seu caminho absoluto, que é o caminho do diretório raiz até o arquivo. O diretório raiz, chamado simplesmente de / (uma singela barra) é a grande mãe da qual todo e qualquer outro diretório descende. É por conta disso que a estrutura de diretórios em sistemas Unix costuma ser chamada de árvore de diretórios.

 

Árvore de diretórios do Linux. Fonte: https://commons.wikimedia.org/wiki/File:GNU-Linux_directory_tree.png

 

Continuando com o exemplo anterior, se o seu nome de usuário fosse myself, e você estivesse no diretório Documentos, então o caminho absoluto para o diretório Bar seria provavelmente /home/myself/Documentos/Foo/Bar/. De posse do caminho absoluto de um arquivo, é possível se referir a ele a partir de qualquer diretório do sistema. Ou seja, o comando:

cd /usr/bin

Sempre levará você para o diretório bin, dentro do diretório usr, dentro do diretório raiz, independente de qual seja o diretório corrente no shell. Ao navegar pelos diretórios utilizando cd, também podemos nos referir a alguns diretórios através de seus apelidos.

Os mais importantes são:

~ (til): o diretório home do usuário atual. Exemplo: cd ~/Documents/Foo/Bar

. (ponto): o diretório atual. (pode parecer inútil, mas tem suas aplicações)

..(ponto ponto): o diretório anterior. Exemplo: cd ../Foo/ (volta para o diretório anterior e depois entra no diretório Foo).

É possível utilizar os dois pontos de forma cumulativa. Por exemplo: cd ../../Bar voltaria dois diretórios na hierarquia de diretórios, e então entraria no diretório Bar. Recomendo que você passe um tempo brincando com terminal pra pegar o jeito da coisa, usando cd e ls para explorar a estrutura de diretórios. Pra tonar a brincadeira mais interessante, você também pode criar e remover diretórios (com cuidado, para não obter nenhum resultado catastrófico) e arquivos.

Como criar e remover arquivos e diretórios no terminal

Para criar um diretório dentro do diretório atual, basta usar mkdir seguido pelo nome do novo diretório. Exemplo:

mkdir amador cd amador  

Cria um diretório chamado amador no diretório atual e entra nele. Lembre-se que quando você utiliza o nome do diretório sozinho, ele será criado no diretório atual, mas você também pode utilizar um caminho relativo ou absoluto para criar seu diretório. Por exemplo:

mkdir /home/foobar/Documentos/fb 

Cria um diretório chamado fb no diretório Documentos do usuário foobar (Nota: isso só vai funcionar se você tiver permissão para criar arquivos no diretório do usuário em questão).

mkdir ../fb 

Cria um diretório chamado fb no diretório acima do atual.

Para remover um diretório vazio, você pode utilizar o comando rmdir (remove directory), da seguinte maneira:

rmdir nome_do_diretorio

Para remover um arquivo, você pode utilizar rm (remove):

rm foobar.txt

Caso você queira remover um diretório não vazio, você pode utilizar rm passando como opção a letra r. Assim:

rm -r meu_diretorio

Opções de linha de comando

Aqui cabe fazer uma pequena digressão: a maioria dos comandos que utilizamos na shell são na verdade pequenos programas que são executados quando digitamos seus nomes na linha de comando (uma das poucas exceções é o cd, que realmente é um comando do shell). O comportamento desses programas pode ser modificado através de opções de linha de comando, que podemos passar de diferentes formas, a depender do programa. O jeito clássico de passar opções para um programa no shell é digitar um traço (‘-’) depois do nome do programa, seguido das opções que desejamos.

Nesse estilo, as opções costumam ser referidas por letras, que indicam a funcionalidade que desejamos obter do programa. No exemplo anterior, utilizamos a opção ‘r’ par a o programa rm, que indica que queremos remover o diretório em questão e todos os seus subdiretórios de maneira Recursiva. O ls, por exemplo, aceita, dentre outros, a opção a, que indica que ele deve imprimir na tela todos (All) os arquivos e diretórios, incluindo os ocultos, e a opção l, que indica que ele deve imprimi-los no modo de lista Longa.

Então, se você digitar na linha de comando ls -al, você vai perceber que agora ele vai imprimir um arquivo/diretório por linha, com muitas outras informações sobre cada um, e incluirá também os arquivos ocultos (cujo nome inicia com um ponto). Um outro jeito comum de sinalizar opções para um programa, chamado de opções longas, é utilizar dois traços seguido de uma palavra-chave. A opção -a, do comando ls, por exemplo, pode ser passada alternativamente como:

ls --all 

Geralmente, para obter uma lista completa de possíveis opções para um comando, você pode usar a opção –help. Assim:

ls --help 

 

Parte da mensagem de ajuda do ls

Mover, renomear e copiar arquivos e diretórios no Shell

Para concluir essa parte de exploração e manipulação de arquivos e diretórios, vamos ver mais dois comandos, o mv (MoVe) e o cp (CoPy). Utilizamos o comando mv para mover um arquivo ou diretório para outro local. Esse comando recebe dois argumentos, o caminho de origem e o caminho de destino:

mv origem destino 

O mv tem uma sutileza importante. Ele serve não apenas para mover arquivos ou diretórios, mas também para renomeá-los. O que vai dizer se o arquivo em questão será movido ou renomeado é o contexto. Por exemplo:

mv foo bar 

Se não existir um diretório chamado bar no diretório atual, então o arquivo ou diretório chamado foo é renomeado para bar. Por outro lado, se existir um diretório chamado bar no diretório atual, então foo é movido para dentro de bar. Vamos supor que no diretório atual existe um arquivo chamado fb.txt e um diretório chamado foo, dentro do qual existe um outro diretório chamado bar, então:

mv fb.txt foo/bar 

Move o arquivo fb.txt para o diretório bar, contido em foo. Por outro lado,

mv fb.txt foo/bar/fb.dat

Move o arquivo fb.txt para o diretório bar, contido em foo e o renomeia para fb.dat. Lembrando que caso você conheça o caminho absoluto de um arquivo, você pode movê-lo mesmo que ele não esteja no diretório de trabalho da shell, por exemplo:

mv /home/seunome/Documentos/info.txt /home/seunome/Textos

Moverá o arquivo info.txt de Documentos para o diretório Textos, independente de qual seja o cwd (contanto que esses arquivos e diretórios existam, é claro!). Por fim, você pode copiar um arquivo utilizando o comando cp (CoPy) de modo semelhante ao mv:

cp origem destino

Como ler arquivos de texto no terminal com cat

Você já aprendeu como passear pelos diretórios, como criar diretórios e como renomear, mover, copiar e remover arquivos no geral. Mas e se você quiser dar uma olhada no conteúdo de algum código fonte, por exemplo? Para isso, basta usar o cat. O nome “cat” vem de “concatenação”, porque ele recebe uma lista de nomes de arquivos como argumento, junta tudo (concatena) e imprime na tela. Assim:

cat texto1 texto2 texto3

Saída: conteúdo do texto1, seguido pelo conteúdo do texto2, seguido pelo conteúdo do texto3.

É claro que se sua lista tiver apenas um arquivo, ele apenas imprimirá o conteúdo do arquivo na tela. Inclusive, é possível que você passe a vida toda usando cat sem jamais concatenar a saída de nenhuma lista de arquivos. Na minha opinião, cat é um dos nomes mais contraintuitivos da história da computação.

Agora execute o cat sem especificar nenhum arquivo no terminal e digite alguma coisa. Você vai ver que o terminal vai imprimir outra vez na tela qualquer coisa que você tiver escrito. E ele vai continuar esperando uma entrada do usuário para repetir, até que você pressione Ctrl-D (que no shell equivale a ler um EOF, uma espécie de caractere especial que significa “fim do arquivo”). Essa funcionalidade pode parecer inútil, mas é ela que permite que criemos arquivos de texto com o cat, através do redirecionamento de entrada, que estudaremos mais abaixo.

Otimizando seu tempo no Shell Linux

Realizar tarefas no shell pode parecer maçante num primeiro momento, pela quantidade de digitação envolvida no processo. Mas na verdade, existe uma série de recursos que podem ser utilizados para tornar mais rápida a interação com o terminal. Vejamos…

Histórico de comandos e Autocompletar do Shell Linux

Enquanto você fazia experiências no shell, deve ter passado por muitas situações em que errou alguma coisa no comando, recebeu uma mensagem de erro do terminal e aí teve que digitar tudo de novo corretamente, não é?

Acontece que o shell conta com um recurso de histórico de comandos que possibilita que você acesse os últimos comandos digitados no prompt. Para isso, basta usar a seta para cima quantas vezes for necessário até chegar no comando desejado. Então você pode modificar o comando conforme necessário e pressionar enter para executá-lo de novo.

Um outro recurso importantíssimo, que você deve se habituar a utilizar é o de autocompletar. Quando você estiver digitando um comando, você pode pressionar tab para que o shell complete o comando para você, economizando a digitação de caracteres.

Caso exista mais de uma possibilidade para completar o comando, o shell não fará nada, mas se você pressionar tab uma segunda vez, ele mostrará uma lista de candidatos para autocompletar o comando. Então, você pode digitar mais um pouco até não haver ambiguidade, e pressionar tab outra vez para o shell completar o comando pra você. Nunca, jamais subestime o autocompletar, e tente habituar-se a usá-lo o tempo todo. Ele realmente é uma mão na roda.

Recortar e colar no Shell

Se você estiver usando um emulador de terminal (o que provavelmente é o caso), é possível que você tenha tentado copiar o comando que você escreveu anteriormente para colá-lo de volta no terminal para fazer alguma correção utilizando Ctrl-C, Ctrl-V.. E então seus planos foram frustrados quando o shell imprimiu ^C na tela e pulou uma linha, ou alguma outra coisa inusitada aconteceu.

De fato, é possível recortar e colar texto num emulador de terminal, mas geralmente isso é feito com as teclas Ctrl-Shift-C e Ctrl-Shift-V. O comando Ctrl-C sem o shift serve para uma outra função no terminal. Quando utilizado, ele envia um sinal para encerrar qualquer que seja o programa que esteja rodando em primeiro plano no terminal.

Redirecionamento de entrada e saída no Shell

Um outro recurso muito importante do shell é o redirecionamento de entrada e de saída. Quando executamos algum programa através do terminal da maneira convencional, a saída desse programa é impressa na tela do terminal. Podemos redirecionar essa saída direto para um arquivo de maneira muito simples: utilizando o símbolo >. Por exemplo:

ls > file_list.txt

Se utilizássemos o ls apenas, em seguida apareceria na tela uma lista com os arquivos e diretórios contidos no diretório corrente. Mas utilizando o símbolo > seguido do nome de um arquivo, a saída do ls é enviada para o arquivo file_list.txt (se o arquivo não existir, ele é criado pelo sistema). Você pode rodar o comando acima e depois:

cat file_list.txt

E verificar que o arquivo realmente é criado.

Se você rodar o mesmo comando (ls > file_list.txt) outra vez, o conteúdo do arquivo existente será apagado para dar lugar ao novo conteúdo (que será quase igual, exceto que agora na lista de arquivos terá um arquivo chamado file_list.txt, que você acabou de criar no diretório).

Se ao invés disso, você quiser acrescentar a saída do programa ao conteúdo de um arquivo já existente, você pode utilizar >>. Assim, se o arquivo indicado não existir, será criado um novo arquivo com a saída do programa. Mas caso o arquivo já exista, a saída do programa será acrescentada ao final do arquivo existente.

Agora você já é capaz de entender como é possível criar arquivos de texto com o cat. Quando executamos o cat sem especificar um arquivo para ele ler, ele simplesmente lê a entrada do usuário no shell e envia para a saída padrão (que é o próprio terminal). Se redirecionarmos a saída para um arquivo, então, podemos usar cat para escrever texto direto para um arquivo. Por exemplo:

$ cat > amador.txt amador programa mador programa a        ador programa am (Pressionando Ctrl-D para encerrar a leitura do cat) 

E agora lemos o conteúdo do arquivo que criamos:

$ cat amador.txt  amador programa mador programa a ador programa am 

Também podemos redirecionar a entrada de um programa utilizando <. Desse modo, indicamos que a entrada de dados para um programa não virá do terminal, mas sim de um arquivo.

Esse recurso facilita muito na hora de testar um programa que recebe entrada de dados pelo terminal, já que ao invés de digitarmos uma entrada específica para o programa toda vez que formos testar alguma modificação, podemos simplesmente escrever a entrada num arquivo de texto (por exemplo, entrada.txt) e executá-lo assim:

./meuprograma < entrada.txt

Podemos inclusive redirecionar a entrada e saída de um programa ao mesmo tempo:

./meuprograma < entrada.txt > saida.txt

Utilização de pipes no shell

Redirecionar a saída de um programa para um arquivo é realmente uma mão na roda. E o mecanismo de pipe do shell leva esse conceito mais adiante, permitindo que você use a saída de um programa diretamente como entrada de outro programa. O símbolo utilizado para realizar essa operação é o |. Exemplo:

programa1 | programa2

O termo pipe significa cano em inglês, e motivo é que com essa ferramenta você pode montar um “encanamento” conectando a entrada de um programa na saída de outro.

Pipes com pagers e grep

Para poder demonstrar o poder do pipe, vou apresentar um novo programa/comando do shell: o less. O less pertence a uma classe de aplicações chamadas de pagers, que permitem uma melhor visualização de documentos longos no terminal através de recursos de rolagem. Para fazer um teste, escolha um documento de texto mais extenso e digite:

less nome_do_doc.txt

(Nota 1: é possível que sua distribuição não tenha com o less instalado. Se esse for o caso, provavelmente ela vem com algum outro pager, como o more.)

(Nota 2: para sair do less, pressione Q).

Com frequência, você vai querer analisar a saída de um programa com o conforto de um pager. Você poderia redirecionar a saída de um programa para um arquivo e depois carregá-lo com o less, mas o uso de pipes torna essa tarefa bem mais fácil. Suponha que você queira estudar a página de ajuda do comando ls, por exemplo. Você poderia utilizar:

ls --help | less

Uma outra ferramenta que você deve utilizar com frequência é o grep. O grep recebe uma entrada de texto e um padrão, e então imprime no terminal todas as linhas da entrada que coincidem com o padrão especificado. Quando utilizado com arquivos, devemos chamá-lo da seguinte forma:

grep padrao arquivo

Por exemplo:

grep myfunc script.py 

Imprime na tela todas as linha de script.py em que aparece o termo myfunc.

O grep aceita expressões regulares para flexibilizar a busca por padrões, mas isso está fora do escopo desse post. O que importa agora é saber que quando não especificamos um nome de arquivo, o grep procura pelo padrão no fluxo de entrada padrão.

Então podemos buscar por padrões na saída de determinado programa, utilizando pipes! Por exemplo, o comando ps -e, enumera todos os processos ativos no computador. Se quisermos saber o número do processo do navegador (supondo que você use o Firefox), basta rodar o comando:

 ps -e | grep firefox

Como você deve ter imaginado, você pode fazer um verdadeiro sistema de encanação, ligando a saída e entrada de programas indefinidamente assim:

programa1 | programa2 | programa3 ….

… ao infinito e além.

Obtendo ajuda com as man pages

Como já vimos anteriormente, você pode obter muitas informações sobre o funcionamento de um programa através da opção de linha de comando –help. Entretanto, às vezes as informações da mensagem de ajuda são muito sucintas e não trazem as informações que desejamos.

Nesses casos, as man pages (man vem de manual) podem te ajudar. Man pages são páginas de manual, que trazem a documentação não só de programas, mas também de funções e chamadas de sistema.

O programa man apresenta a página do manual a respeito de determinado programa, já com um pager próprio (semelhante ao less). Essas páginas costumam ser bem completas, e geralmente quando você instala novos programas, suas páginas de manual são inseridas no banco de dados do man. Para utilizá-lo, basta escrever:

man programa

Se você quiser informações sobre o grep, pode digitar:

man grep

Ou, se você quiser obter informações sobre o próprio man, basta escrever:

man man

Se você leu o post todo, agora já deve se encontrar em condições de se virar melhor no terminal do Linux. Toda distro possui uma série de utilitários de linha de comando prontos para serem usados. Outros exemplos dignos de nota são o wc (contagem de palavras) e diff (analisa as diferenças entre dois documentos).

Além disso, você sempre pode estender essas funcionalidades instalando novos programas. Aqui no blog eu já falei sobre algumas outras ferramentas do terminal, como o editor de textos vim, o jp2a (conversor de imagens jpg para ASCII), e o toilet (criação de letreiros em ASCII art). Dá uma olhada, e continue acompanhando o blog pra mais dicas sobre Linux, programação e computação no geral!

 

Related Posts

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *