Terminal avançado

De Rede Linux

Veja tambem:
Terminal basico
Comandos comuns

Esse artigo é um apanhado de coisas que consideramos úteis para um usuário freqüente de GNU/Linux.

Os pedaços dele são relativamente auto-contidos, mas é provavel que você precise ver fluxo de texto

Certamente há alguns erros por aqui. Se você achar algum, por favor mande para lucasmmg (arroba) linux (ponto) ime (ponto) usp (ponto) br

Conteúdo

Procurando palavras dentro de textos: grep

grep é um aplicativo para linha de comando de sistemas Unix que procura strings ("pedaços de texto") em arquivos.

Vamos ver se conseguimos esclarecer com um exemplo.

Suponhamos que você tem em sua conta uma lista de supermercado

$ cat compras
cachaça
caipirinha em pó
caipirosca em pó 
vinho tinto
vinho branco

("cat" foi usado para imprimir o conteúdo do arquivo "compras" na tela. De fato ele faz muito mais que isso. Mas uma coisa de cada vez ...)

(outra coisa: para criar esse arquivo, eu poderia ter usado o gedit, o vim ou o emacs, entre muitos outros)

Você pode estar diante do vendedor de vinhos, querendo listar apenas aquilo que você quer comprar dele.

Nesse caso, você digitaria:

$ grep vinho compras
vinho tinto
vinho branco


suponhamos agora que você queira listar só os destilados

$grep ca compras
cachaça
caipirinha em pó
caipirosca em pó


Fluxo de texto: Fazendo programas conversarem

No GNU/linux, há a possibilidade de você fazer um conjunto de programas pequenos, que cumprem tarefas bastante simples e especícicas, e utilizá-los, em conjunto, para realizar uma tarefa grande e complexa.

Para que isso seja possível, é necessário que os tais programas possam se comunicar de alguma forma.

Uma das formas possíveis de comunicação é o que chamamos (aqui) de "fluxo de texto". Os programas conversam uns com os outros trocando strings (seqüencias de caracteres). Eles fazem isso por meio do que chamamos de "pipe"

Para começarmos a pensar nisso, vamos introduzir um pequeno utilitário chamado "seq"

$ seq 1 10
1
2
3
4
5
6
7
8
9
10

Isso parece bem inútil, não ?

Bom, vamos mostrar mais um programa pouco útil:

$ wc -l
um          <- to digitando               
dois        <- ainda sou eu
tres        <- ainda 
quatro      <- ainda
cansei
(dei ctrl-d. Por enquanto você pode encarar isso como "cansei de digitar")
5            <- esse 5 foi o wc que imprimiu, não eu que escrevi

o wc ou "word counter" é um programa para contar palavras (no caso, "wc -l" conta linhas, pois "-l" é essa opção do wc)

ele recebeu a minha digitação (os números de "um" a "cinco"), contou o numero de linhas, e imprimiu na tela

agora, a parte interessante !

$ seq 1 10 | wc -l
10

vamos ver se dá pra entender ...

seq 1 10 ia imprimir os numeros na tela.

ai, ao invés de os números serem impressos na tela, eles foram passados para o wc -l. o wc -l "recebeu" esses números no mesmo "lugar" que, no exemplo anterior, tinha recebido meus numeros escritos por extenso.

e se ...

$ seq 1 10 | wc -l | wc -l
1

para o ultimo wc -l tudo se passou como

$ wc -l
10        <- fui eu
(apertei ctrl-d)
1         <- ele me devolveu

Complicando com Grep: filtrar o ls, achar diretórios grandes ...

Agora, vamos fazer algumas maldades com o grep

Antes de mais nada, vamos esclarecer uma coisa:

nós vimos grep <texto_a_procurar> <arquivo>

mas o grep também pode receber o texto onde procurar pelo teclado, ao invés de usar um arquivo

$ grep vinho
terra
uva
pés
um frances mal humorado 
vinho tinto <- até aqui fui eu digitando
vinho tinto <- saida do grep
(apertei ctrl-d)

é por causa dessa capacidade do grep que nós vamos poder usar o pipe (aquela coisa do item anterior , o "|" );

dito isso ...

$ ls
Desktop Mail Mailbox Maildir private www

$ ls | grep Mail
Mail
Mailbox
Maildir

$ ls | grep -i BoX
Mailbox

(-i = ignore maiusculas )

espero sinceramente que não sejam necessárias maiores explicações.

agora, podemos fazer uma coisa efetivamente útil: caçar diretórios grandes !

$du ~ -h

produz uma lista de diretórios no seu home , precedidos pelo tamanho deles.

Uma das minhas linhas, por exemplo é:

 7,0M    ./.mozilla/firefox/0af3ht7q.default/extensions

Desejamos selecionar linhas que correspondem a diretórios grandes (com mais de um megabyte) Para isso, selecionaremos linhas que contenham um número seguido da letra M.

Para essa seleção, usa-se grep [0-9]M ([0-9] representa todos os números de zero a nove. mais detalhes em Expressão Regular)

Assim, explicamos o enigmático "comando de achar diretórios grandes" do básico

Localizando arquivos: The Chuck Norris' Way

vimos que

 $find ~ -iname '<nome_do_arquivo>'

localiza os seus arquivos pra você.

Mas pra que simplificar ?

você também pode dar

 $find ~ | grep -i <nome de arquivo>

pois "find ~" imprime todos os arquivos de todos os diretórios da sua home

Restringindo o acesso aos meus arquivos

O GNU/linux é um sistema projetado para comportar vários usuários, e impedir que esses usuários comprometam os dados de outros usuários ou do sistema.

Nele, todo arquivo tem um dono, e um conjunto de permissões que dizem quem pode fazer o que com ele.

Todos os arquivos da sua home são seus (ou pelo menos deveriam ...)

Para verificar isso, você pode dar

 $ cd ~
 $ ls -all

o "a" imprime arquivos ocultos. o "l" imprime informações extras (permissões inclusive) o outro "l" é só pra ficar bonitinho ^^

em tese, toda linha da saída deve ser mais ou menos como

 -rw-r--r--  um_numero usuario curso tamanho_do_arquivo data horario nome_de_arquivo

quer ver se tem alguma que não tem o seu nome ?

 $ls -all | grep -v usuario

( grep -v significa "imprima todas as linhas que não casem com o parâmetro" )

Tá. Mas o que o fato de um arquivo ser seu significa ?

Basicamente, significa que você é o único que pode alterar as permissões do arquivo

Bom, deveriamos então descobrir o que são essas tais permissões.

Para arquivos, há permissão de execução (execute, ou x) de escrita (write, ou w) e de leitura (read, ou r)

Essas permissões podem ser dadas em separado para você, o grupo do arquivo (na nossa rede, isso normalmente são os alunos do seu curso) e para "todo o resto do mundo" (no nosso caso, todos os demais usuários da rede linux)

Vamos tentar deixar isso mais claro

 -rw-r--r--   um_numero usuario curso tamanho_do_arquivo data horario nome_de_arquivo
  |1||2||3|

Na saída do ls, |1| representa as permissões dadas a você

Nesse caso, você pode ler o arquivo e escrever nele, mas não pode executá-lo (ao invés de um "x", temos um "-")

já o resto da rede (cujas permissões estão em |3|) pode ler o arquivo, mas não executá-lo ou escrever nele.

suponhamos agora que esse arquivo é muito importante. Tão importante que nem você mesmo poderia mexer nele. (isso pode parecer cretino, mas é de fato útil. Muitas vezes, um programa que você estiver rodando poderá, acidentalmente, escrever sobre um arquivo importante. Se você proteger seu arquivo dessa forma, porém, o próprio GNU/linux se encarrega de impedir essa escrita acidental)

para isso basta

 $chmod u-w arquivo

onde "u" é user (usuário: o dono do arquivo). poderia ser g de group (grupo) o de other (outros) ou a de all (todos: usuario, grupo e outros)

- é "retirar" (poderia ser "+" para acrescentar, ou =, que será explicado em instantes)

e w é escrita (poderia ser x ou r, ou mesmo rw, xw ...)

o igual é só para determinar as permissões independente das que há agora (isso é muito bom para processos automatizados, ou para evitar explicações prolongadas em fóruns ou para colegas pouco interessados)

para voltar às permissões originais você poderia dar

 $chmod u+w arquivo

ou

 $chmod u=rw arquivo

por último, alguns comentários:

  • x em um arquivo é para você poder executá-lo (rodá-lo se ele é um programa)
  • permissões em diretórios são estranhas
  • cada arquivo tem um grupo. Dessa forma, você poderia usar as permissões de grupo para permitir que apenas determinados colegas mexam em determinado arquivo. Aqui na linux você tem que pedir aos admins, se quiser criar um grupo. De uma olhadinha em grupos


permissões em diretórios

--- Há a possibilidade de erros nessa sessão !!! ---

  • r em um diretório é para poder dar "ls" dentro dele (de forma mais honesta: poder listar os arquivos dele, com ls ou o que for)
  • w em um diretório é para poder modificar seu conteúdo (i.e. criar ou remover arquivos, mover arquivos)
  • x em um diretório é para poder interagir com os arquivo e diretórios dentro dele (ler arquivos, escrever neles, listar o conteúdo de subdiretórios)

(para garantir: com r, você lista mas não consegue ler os arquivos. com x você consegue ler mas não consegue uma lista. Estranho, não ?)

Personalizando meu terminal

Dando nomes a comandos frequentes: alias

suponhamos que você tem, como eu, preguiça de digitar "ls -all" toda a vez.

digitando

 $alias l="ls -all"

digitar "l" no terminal passa a efetivamente chamar o "ls -all"

na verdade, eu poderia até fazer

 $alias ls="ls -all"

sem maiores problemas.

Porém, infelizmente, essas alias não passam de um terminal para outro ... Se você fechar o terminal, sua alias tá perdida (e se você utilizar mais de um terminal ao mesmo tempo, terá que fazer isso em todos)

A solução para esse problema, curiosamente, é executar o comando em todos os terminais que você abrir. Só que de forma automática.

Para isso, basta inserir a alias que quiser no arquivo .bash_aliases

 $echo l="ls -all" >> .bash_aliases

então, todo NOVO terminal que vc abrir vai ter essa alias.

o >> será explicado na segunda parte sobre fluxo de texto.

algumas coisas que foram pra baixo do tapete:

  • você precisa de um novo terminal pro .bash_alias funcionar pq ele só é executado quando você lança um novo bash
  • o .bash_aliases foi executado pelo .bashrc, que possivelmente foi executado pelo .bash_profile

Rodando um programa "novo" no terminal

Suponhamos que você fez um EP super legal, que você resolveu utilizar no seu dia a dia (como, por exemplo, um programa que prevê o valor das ações da bolsa, ou que resolve a quadratura do círculo, ou algo do gênero)

ir até o diretório dele pra roda-lo é chato e cansativo. Você pode simplificar o processo movendo o seu programa para o diretório bin que fica na sua home (i.e., o ~/bin)

$ mv el_magnifico_programa ~/bin

com isso você pode digitar

$ el_magnifico_programa

e isso rodará o programa, indepententemente do diretório em que você esteja.

(desde que, é claro, você tenha dado permissão de execução a ele)

fluxo de texto 2:texto em arquivos

Já vimos, em Fluxo de texto: Fazendo programas conversarem que podiamos substituir a entrada de um programa, normalmente dada por um teclado, pela saída de outro.

Agora, vamos ver como utilizar arquivos de texto para substituir a entrada ou receber a saída.

Guardar a saída em um arquivo texto

 $seq 1 3
 1
 2
 3

Agora, vamos tentar por isso em um arquivo

 $seq 1 10 >> arquivo
 $cat arquivo
 1
 2
 3

novamente, usamos o cat para imprimir um arquivo na tela

e se eu quiser por o 4 ali ?

 $seq 4 4 >> arquivo (ou, de maneira mais simples: echo 4 >> arquivo)
 $cat arquivo
 1
 2
 3
 4

(nota: existe o ">", que, para todos os efeitos, apaga o arquivo original e escreve a saída depois. o resultado de utilizá-lo na segunda chamada teria sido "4" ao invés de 1 2 3 4)

Utilizando um arquivo como entrada

mais simples impossível:

 $wc -l < arquivo
 4

ou, equivalentemente

 $cat arquivo | wc -l
 4

(ver Fluxo de texto: Fazendo programas conversarem se esse segundo exemplo não fez muito sentido)

Programando no terminal

antes de mais nada: o terminal pode ser usado pra programar qualquer coisa. Nós vamos falar de C porque essa é a necessidade mais usual de uma pessoa que acaba de entrar no IME.

dito isso.

Criando seus programas

Um arquivo .c, que é onde você escreve um programa, é tão somente um arquivo texto. Nada mais.

Você pode utilizar, para editar tais arquivos, o gedit (que é bastante simples e intuitivo) o vim (que roda no terminal e é desenhado para tornar a escrita de programas mais rápida) ou o emacs (que pode ser rodado no gráfico ou no terminal, e também foi desenhado para tornar a escrita mais rápida.

Para aprender sobre o vim, sugere-se

 $vimtutor

Se quiser ver o original em inglês (ou a tradução em polonês ...) veja /usr/share/vim/vim70/tutor/

Rodando esses programas

Para poder rodar esse .c, você precisará compilá-lo (i.e. traduzi-lo de C para uma linguagem que o computador entenda)

Para isso, use o gcc.

 $gcc programa.c
 $ ./a.out         <-o arquivo que o gcc gerou, que já tem permissão de execução

algumas breves dicas:

 $gcc -lm                                <- deixa você usar a math.h
 $gcc -Wall -pedantic -02 -ansi          <- "confere" o seu código em busca de muitos erros comuns

para instruções mais detalhadas, veja Compilando_um_arquivo_em_C

Corrigindo eventuais problemas

Aprenda sobre o gdb e/ou o ddd, que permitem a você acompanhar o que o seu programa está fazendo, para entender erros, quando houver.

Deixar o micro trabalhando sem eu estar aqui

Suponhamos que você tem um EP comprido para rodar.

Ao invés de ficar logado e bundando na frente do micro, você pode utilizar o screen

 $screen

isso abrirá um novo terminal, onde você poderá rodar o que quiser (sugere-se que você encaminhe os resultados para um arquivo texto, com >> )

para sair do screen, aperte "ctrl-a-d"

agora, você pode se deslogar e ir passear, que o seu processo continua rodando

para voltar

 $screen -r

(note que você vai ter que fazer isso na mesma máquina. Se alguém a estiver usando, use o ssh

Rodando um programa grande, pesado e demorado

Se seu programa for consumir muita máquina, e você for colocá-lo dentro de uma screen, é necessário que você deixe-o com prioridade baixa (i.e. seu programa fica sendo considerado "menos importante", e dá licença a outros programas quando eles querem usar o processador)

para isso, dentro da screen, rode

 $nice -n 9 comando (com opções se for o caso)

AO INVÈS DE

 $ comando

Cadê o ctrl-alt-del ? - Matando processos

Alguma coisa parece errada ? Algum programa travou ?

 $ ps aux

lista os processos (programas rodando)

 $ps aux | grep seu_nome_de_usuario

lista os seus processos

Para matar um processo

o primeiro numero que aparece na linha de um processo na saída de "ps aux" é o numero do processo.

use:

 $kill numero_do_processo

e, se não der certo

 $kill -9 numero_do_processo

Note que você só pode matar seus próprios processos

Usando a rede linux de casa: ssh

utilizar a rede de fora é relativamente simples. Se você tiver linux no computador do qual quer acessar a rede, basta digitar

 $ssh nome_de_usuário@shell.linux.ime.usp.br

e então você terá todos os programas de terminal.

Se ainda estiver usando windows, procure o putty

Pulando de uma máquina para outra dentro da rede

Suponhamos que você estava rodando um ep, e usou a dica do screen. Então, você volta e alguém está usando a máquina onde você deixou seu EP rodando.

Agredir a pessoa que está na máquina pode até ser divertido, mas existe uma solução mesmo para os mais pacíficos:

logue-se em outra máquina

dê:

 $ssh nome_da_maquina_que_esta_rodando_seu_ep

e pronto !

PS: você pode fazer isso "em cadeia". Ou seja, dar ssh pra uma máquina, depois para a outra ... Em particular, pode dar ssh para shell.linux.ime.usp.br de fora e então para alguma máquina da rede.

PS2 : Note que, nesse segundo exemplo, não foi necessário dar seu nome de usuário. O ssh assume, se você não disser seu nome de usuário, que ele é o mesmo na máquina de destino e na de origem (e como as duas eram clientes da rede linux, o seu login era realmente o mesmo)

Mais sobre ssh

  • Você pode copiar arquivos via ssh ! Para isso, use um programa chamado scp
  • Você pode usar a rede linux como se fosse um diretório no seu computador. Procure sshfs
  • Você pode acessar aplicativos gráficos (com ssh -X)
  • Existe uma coisa chamada "túnel", que lhe permite acessar a internet como se você fosse uma máquina de dentro da rede (i.e. suponhamos que haja um site que só fica disponível de dentro da rede. Você pode usar o ssh pra acessá-lo de fora !)

Uma lista de comandos simples, para ocasiões diversas

Este guia serve apenas como referência, portanto, os comandos são explicados sucintamente. Para uma explicação mais detalhada, veja os artigos relevantes (usando a ferramenta de busca da wiki) ou utilize "man comando" ou "info comando"

Na coluna sintaxe, temos: nome do comando [argumentos opcionais] <argumentos obrigatorios>

A lista completa de comandos frequentes encontra-se em Comandos frequentes

Manipulação de texto

(o editor de texto está em "ferramentas de programação")


Comando Utilidade sintaxe Obs
cat junta os arquivos dados e os imprime na tela cat <arquivo> [arquivos] "cat arquivo -" junta um arquivo com a entrada do teclado (ou o pipe, pois, como já vimos, elas são equivalentes)
grep procura texto em arquivos (ou na entrada de teclado/pipe) grep <expressão> [arquivo] desconfunda-se no artigo Terminal avançado (nele, há duas sessões dedicadas ao grep e várias outras menções)

Ferramentas de programação

Comando Utilidade sintaxe Obs
vim editor de texto vim [arquivo] (para aprende-lo, vimtutor, logo abaixo)
vimtutor tutorial interativo de vim vimtutor procure em /usr/share/vim/vim70/tutor se quiser o original em inglês
gcc compilar programas em C gcc nome_do_programa.c o executável produzido é o a.out (rode ./a.out)
gdb debugar programas em C
ddd debugar programas em C

Processos: Destravando ou evitando travamentos

Comando Utilidade sintaxe Obs
nice ajusta a prioridade de um processo nice -n 9 <programa> ("-n 9" é o para prioridade baixa)
ps lista os processos na máquina ps aux (opções padrão inclusas)
top lista os processos na máquina, de forma bonitinha top o processo de cima é o máximo consumo de processador
kill mata processos kill (-9) <PID>
  • -9 é mais "bruto". Só tente se não deu sem.
  • Obtenha o PID com o ps
xkill mata processos (com o mouse) xkill clique na janela com o mouse logo após rodar o programa

Sortidos

Comando Utilidade sintaxe Obs
chmod muda as permissões de arquivos e diretórios veja artigo veja artigo
alias associa um comando (digitado) a outro (executado) veja artigoveja artigo
screen abre um terminal que sobrevive a logoffs screen para sair, ctrl-a-d, para voltar, "screen -r"

Comandos de uso menos freqüente

Comando Utilidade sintaxe Obs
file imprime o tipo de um arquivo (pdf,doc ...) file <arquivo>
which imprime onde está um programa which <programa> funciona para os programas que você pode disparar direto do terminal
whoami imprime seu nome de usuário whoami
mutt ver seus emails mutt
last lista os ultimos usuários a se conectarem à maquina em que você está last [usuário] use "last seu_nome_de_usuário" para ver de onde você se conectou as ultimas vezes.
seq imprime a sequencia de "numero1" a "numero2" seq numero1 numero2 pode receber 1 ou 3 argumentos com outros efeitos similares
wc wc conta (caracteres, palavras, linhas ...) wc -l para contar linhas

Obtendo mais ajuda

Caso os conteúdos dessa página não sejam o bastante ( e esperamos sinceramente que não sejam !) lembre-se que há locais onde encontrar ajuda mais detalhada.

em um terminal, você pode dar:

 $man comando

para uma descrição do comando (que será um pouco técnica demais, mas ainda sim pode te ajudar)

você pode também dar:

 $info comando

e conseguirá (se tiver sorte) uma descrição mais detalhada e amigável do comando

Lembre-se também do google. Em particular, ele é ótimo para pesquisar eventuais mensagens de erro.

Usando GNU/Linux