Terminal avançado
De Rede Linux
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
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
já 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> |
|
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 artigo | veja 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.