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
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
-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:
>> – 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
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
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.
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 <e 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:
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).