Usando pipes e redirecionamentos no linux
Uma das caracterÃsticas mais interessantes de sistemas baseados em Unix, como o linux, é a possibilidade de juntar diversos comandos em um só e poder enviar a saÃda para um arquivo. Vamos aprender a fazer isso usando pipes e redirecionamentos.
Entre as caracterÃsticas do linux, talvez a mais interessante seja a noção de que tudo é um arquivo. Até mesmo dispositivos de hardware são encarados pelo sistema como sendo arquivos.
Da mesma forma, saÃdas e entradas de programas de modo texto também são vistos como arquivos.
Quando um programa é iniciado, o shell (no nosso caso o bash) coloca a sua disposição arquivos especiais, o chamado Standard Input/Output ou stdio, em português entrada e saÃda padrão.
Standard I/O
O stdio é formado por três arquivos especiais, são eles:
Standard Input (stdin) – Este arquivo descreve o local de onde o programa vai ler a entrada de dados, geralmente é associado ao teclado.
Standard Output (stdout) – É o local para onde o programa vai enviar a saÃda (informações, mensagens de sucesso, etc.), quase sempre é o terminal onde o programa foi iniciado.
Standard Error (stderr) – Funciona basicamente da mesma forma que o stdout, mas é exclusivo para a saÃda de mensagens de erro. Também é geralmente associada ao terminal.
Stdout e stderr são separados porque é comum que as mensagens de erro sejam processadas de maneira diferente das mensagens comuns.
Pipes
Como vimos acima, tudo no linux é visto como sendo um arquivo, inclusive a saÃda e entrada de dados de programas. Usando essa idéia, podemos juntar diversos comandos por meio de um pipe (em portugês algo como “cano” ou “tubo”), passando a saÃda de um comando para a entrada de outro. Isso facilita muito o trabalho e pode agilizar tarefas que, sem isso seriam praticamente impossÃveis ou pelo menos impraticáveis.
Vamos a um exemplo:
Digamos que você queira analisar as mensagens de inicialização da sua máquina em um paginador, como o less. Você faria assim:
[root@host] # dmesg | less
Dessa forma, o comando dmesg envia sua saÃda para a entrada do comando less.
Outro exemplo:
[root@host] # ps aux | grep httpd
Com esse comando você exibe na tela todos os processos do httpd (servidor web) ativos na sua máquina.
E se você quisesse somente os PIDs? Simples:
[root@host] # ps aux | grep httpd | awk {'print $2'}
Bom, estes são exemplos simples, mas a partir do momento que você se acostumar com a idéia, vai achar diversas funções para isso.
Este processo é gerenciado pelo shell e é transparente para o usuário.
Redirecionamentos
Às vezes é extremamente interessante enviar a saÃda de um comando para um arquivo, para poder analisar posteriormente. Isso é feito usando redirecionamentos.
Um exemplo:
[root@host] # ls -la > file1
dessa forma, a listagem do diretório vai ser gravada em um arquivo, ao invés de ser exibida na tela.
o redirecionador ‘>’ cria um arquivo novo vazio e sobrescreve o arquivo se ele já existir, para adicionar o texto no final de um arquivo existente, use ‘>>’
[root@host] # ls -la >> file1
a listagem será salva no final do arquivo ‘file1′. Se o arquivo não existir, será criado.
Note que o redirecionador ‘>’ envia apenas stdout, para enviar stderr, usamos ’2>’.
É importante saber que o shell vai criar o arquivo antes de executar o comando, ou seja, os pipes e redirecionamentos são analisados antes da execução dos comandos. Por isso temos que tomar cuidado com comandos como esse:
[root@host] # grep 'bruno' arquivo > arquivo
isto nunca deve ser feito, pois o arquivo seria sobreposto por um arquivo vazio, resultando na perda de tudo que havia no arquivo. O correto seria usar um arquivo intermediário para guardar a saÃda do grep e depois renomeá-lo:
[root@host] # grep 'bruno' arquivo > arquivo2
[root@host] # mv arquivo2 arquivo
Estes são os redirecionadores usados no bash, outros shells podem ter sintaxes bem diferentes.
Da mesma forma, podemos ler a entrada de um comando de um arquivo:
[user@host] $ mail -s "novo arquivo" bruno < novoarquivo
Assim o conteúdo do arquivo novoarquivo é enviado para o usuário bruno por email. Normalmente o comando mail espera que você digite a mensagem no terminal.
Os redirecionadores e seus significados:
cmd > arquivo e
cmd 1> arquivo – envia stdout para arquivo
cmd 2> arquivo – envia stderr para arquivo
cmd > arquivo 2>&1 – envia stdout e stderr para arquivo
cmd > arquivo1 2> arquivo2 – envia stdout para arquivo1 e stderr para arquivo2
cmd < arquivo – recebe stdin de arquivo
cmd >> arquivo e
cmd 1>> arquivo – adiciona stdout ao final de arquivo
cmd 2>> arquivo – adiciona stderr ao final de arquivo
cmd >> arquivo 2>&1 – adiciona stdout e stderr ao final de arquivo
cdm1 | cmd2 – Envia stdout de cmd1 para cmd2
cmd1 2>&1 | cmd2 – Envia stdout e stderr de cmd1 para cmd2
Não sei se cabem perguntas aqui xará, mas…
Vc já viu/usou/conhece o redirecionador de entrada “<<”??
Se sim, dá uma palinha sobre ele tb, pode ser??
Valew mano, forte abraço!
Bruno Bastos
Rio de Janeiro – Brasil