terça-feira, 27 de agosto de 2013

Estava eu estudando Shell Script e senti a necessidade de aprender mais sobre REDIRECIONAMENTO (STDIN, STDOUT, STDERR, PIPE) e descobri que esse assunto é tão o mais importante do que qualquer outro no mundo UNIX. Então resolvi pegar um pouco de cada blog que explicava bem alguns tópicos. Então vamos lá:


No Linux é possível trabalhar redirecionando pra onde vai o resultado de um comando, quando um processo precisa acessar um arquivo, ele faz isso através do descritor do arquivo (um número inteiro positivo, que o processo usa para referenciar a um determinado arquivo aberto). Assim, todo processo em um sistema UNIX mantém uma tabela de referências aos descritores de arquivos usados pelo mesmo. Os descritores propriamente dito são mantidos pelo kernel. O tamanho dessa tabela varia de sistema para sistema. Nos linux atuais, o tamanho padrão é 256. Cada processo UNIX dispõe de 20 descritores de arquivo, ordenados de 0 a 19.
Quando um programa é executado, 3 arquivos são automaticamente abertos e associados à esse processo. Abaixo, temos a listagem desses três arquivos:
stdin - 0 - entrada padrão - teclado
stdout - 1 - saída padrão - tela
stderr - 2 - erro padrão - tela
Obs: Os outros 17 descritores estão disponíveis para arquivos.
O arquivo stderr ( descritor 2) é usado pelos programas para imprimir as mensagens de erro(geralmente na tela). Podemos redirecionar a saída de um descritor de arquivo para um arquivo com a seguinte sintaxe:
Sintaxe:


numero-descritor> nome_do_arquivo

Exemplos (assumindo que o arquivo teste.txt não existe no diretório corrente):
$ rm teste.txt


rm: imposível remover

`teste.txt’: Arquivo ou diretório inexistente
Por isso no Linux é comum usar o conceito “entrada padrão” e “saída padrão”. A princípio dá pra se imaginar que, numa interface de console, a entrada padrão é o teclado e saída padrão a tela. Na verdade isso é redirecionado pra um socket, um arquivo em /dev. Chamado de stdout e stdin.
-stdin
Entrada padrão de dados para o programa
-stdout
Saída padrão de dados do programa
 -stderr
Saída padrão de erro


Redirecionamentos
É possível tratar a entrada padrão e a saída padrão usando apenas alguns caracteres especiais. São eles:
> – Redireciona a saída padrão para um arquivo
>> – Redireciona a saída padrão pra um arquivo sem apagar o conteúdo do arquivo
< – Redireciona a entrada padrão usando um arquivo
2> – Redireciona a saída de erro para arquivo
2>> – Redireciona a saída de erro anexando o conteúdo em um arquivo
>&2 – Redireciona a saída padrão para saída de erro
2>&1- Redireciona saída de erro para saída padrão
– Conecta a saída padrão na entrada padrão de outro arquivo

Todos esse redirecionamentos são muito usados. Apesar de parecer complicado não é tanto assim. Usando exemplos práticos fica simples:
echo TESTE > arquivo.txt
escreve TESTE em um arquivo chamado arquivo.txt porém o arquivo é apagado caso já exista
ls foobar 2>> error.log
caso a arquivo foobar não exista (ls falhou) a mensagem de erro é anexada em error.log
cat ls -l | grep evandro
Lista na sáida o no Evandro dentro de um diretório, caso exista.
Por isso é possível criar scripts e arquivos executando varáveis e comandos com textos usando um tipo especial de redirecionamento de saída usando quotes chamado (here document) que permite que você inicie com << PALAVRA e termine com PALAVRA que geralmento é usado <EOF (End Of File – Final de Arquivo). Caractere << é usado para indicar que o texto seja usado para leitura a partir de uma palavra < com marcação e encerrado depois que encontra PALAVRA, como exemplo abaixo:
2
3
1
2
3


----------------------------------------------------------

Descritores de arquivo e ponteiros para os arquivos

Foi visto que o nó de indexação de um arquivo é a estrutura de identificação do arquivo dentro de um sistema. Quando um processo quiser manipular um arquivo, ele vai simplesmente utilizar um inteiro chamado descritor de arquivo. A associação desse descritor ao nó de indexação deste arquivo se faz durante a chamada da primitiva open() (ver 1.5.4), com o descritor tornando-se então o nome local de acesso desse arquivo no processo. Cada processo UNIX dispõe de 20 descritores de arquivo, numerados de 0 a 19. Por convenção, os três primeiros são sempre abertos no início da vida de um processo:
  • O descritor de arquivo 0 é a entrada padrão (geralmente o teclado);
  • O descritor de arquivo 1 é associado a saída padrão (normalmente a tela);
  • O descritor de arquivo 2 é a saída de erro padrão (normalmente a tela).
Os outros 17 descritores estão disponíveis para os arquivos. Esta noção de descritor de arquivo é usada para a interface de Entrada/Saída de baixo nível, especialmente com as primitivas open()write(), etc. Por outro lado, quando as primitivas da biblioteca padrão de entrada/saída são usadas, os arquivos são encontrados através dos ponteiros para os objetos do tipo FILE (tipo definido dentro da ).
Existem três ponteiros definidos neste caso:
  • stdin que aponta para o buffer da saída padrão (geralmente o teclado);
  • stdout que aponta para o buffer da saída padrão (normalmente a tela);
  • stderr que aponta para o buffer da saída de erro padrão (normalmente a tela).


Quem é Almir JR