# Encadeamento (Unix)

Um encadeamento (em inglês: pipeline), nos sistemas operacionais do tipo Unix, é um mecanismo implementado com base no conceito original de canalização: um conjunto de processos encadeados através de seus fluxos padrão, de forma que a saída de um processo é utilizada como entrada do processo seguinte. Cada conexão é implementada através de um pipe anônimo e frequentemente são utilizados filtros nos dados transferidos entre os programas. Este conceito foi inventado por Douglas McIlroy para a shell do Unix e o seu nome é uma analogia com um tubo (pipe em inglês) de transporte de fluidos.

## Exemplo

Abaixo é mostrado um exemplo de encadeamento que implementa uma espécie de corretor ortográfico para uma página Web indicada por uma URL. (Algumas máquinas utilizam o diretório /usr/share/dict/words).
A sequência de operações é a seguinte:
* o comando curl obtém o documento, no formato HTML, encontrado no endereço indicado pela URL;
* o comando sed remove do conteúdo todos os caracteres que não são espaços ou letras, substituindo-os por espaços.
* o comando tr altera todas as letras em caixa alta para caixa baixa e converte todos os espaços encontrados no texto em novas linhas. (Uma linha para cada palavra).
* o comando grep remove as linhas com espaços em branco.
* o comando sort organiza as palavras em ordem alfabética e remove palavras duplicadas.
* finalmente o comando comm mostra quais palavras não são encontradas no arquivo de dicionário (neste caso /usr/dict/words).

## Encadeamentos em interfaces de comando

A maioria das shells possuem construções sintáticas especiais para a criação de encadeamentos. Tipicamente, utiliza-se o caractere ASCII "|" (barra vertical) que, por esta razão, também é conhecido como "caractere encadeamento" pelos usuários do Unix.

### Fluxo de erro

Normalmente, os fluxos padrão de erro dos processos em um encadeamento não são passados adiante mas, por outro lado, são agrupados e direcionados para a console do computador. Muitas implementações de shells contém uma sintaxe adicional para alterar este comportamento. Na shell csh, por exemplo, utilizando-se "|&" ao invés de "|" indica-se que o fluxo padrão de erro deve ser agrupado com a saída padrão e enviado ao próximo processo. A Bourne shell também pode agrupar a saída padrão de erro, assim como redirecioná-la para um arquivo diferente.

## Criando encadeamentos em programação

Um encadeamento pode ser criado por um programa através da chamada de sistema pipe, que instrui o sistema operacional para construir um novo objeto do tipo pipe anônimo. Isto resulta na abertura de dois novos descritores de arquivo no processo: um descritor para leitura no "final" da canalização e outro descritor para escrita no "final" desta mesma canalização. Estes descritores são iguais a qualquer outro descritor de arquivo, com a exceção de que não é possível executar o comando seek nos mesmos.
Para evitar deadlock e exploit de paralelismo, um processo que cria novas canalizações geralmente cria novos processos através de uma chamada de sistema do tipo fork. Cada um destes processos fecha a canalização de que não precisa antes de produzir ou consumir dados. Em uma implementação alternativa os processos podem criar novas linhas de execução e utilizar canalizações para permitir a comunicação entre elas.
Um pipe anônimo pode ser criado através das chamadas de sistema de nome mkfifo ou mknod e apresentado como saída ou entrada de um programa. Elas permitem que canalizações com múltiplos caminhos (paths (em inglês)) sejam criados, e são especialmente eficientes quando combinados com redirecionamento do fluxo padrão de erro, ou com o comando tee.

## Implementação

Na maioria dos sistemas do tipo Unix, todos os processos de um encadeamento são iniciados ao mesmo tempo, com os seus fluxos conectados de forma apropriada e gerenciados, junto com todos os outros processos em execução na máquina, pelo escalonador de processos. Um aspecto importante neste cenário é a utilização de mecanismos baseados em buffers de memória: se um programa produzir 5000 bytes por segundo e um programa receber estes dados a uma taxa de 100 bytes por segundo, nenhum byte será perdido. Para que isso seja possível, os dados escritos pelo primeiro programa são mantidos em um buffer (ou fila). Quando um programa está pronto para receber dados, o sistema operacional direciona os dados do programa que os envia para um buffer, de onde o outro programa realizará a leitura. Se o buffer ficar cheio, o programa que envia os dados é suspenso (blocked) até que o outro programa possa ler algum dado, liberando espaço no buffer.

### Encadeamentos de rede

Ferramentas como o netcat e socat podem conectar canalizações em sockets TCP/IP, seguindo a filosofia Unix que diz: "tudo é um arquivo".

## História

O conceito do encadeamento e a notação da barra vertical foram inventados por Douglas McIlroy, um dos autores das primeiras shells do Unix, após perceber que perdia muito tempo com a tarefa de transformar a saída de um programa na entrada de outro.

### Outros sistemas operacionais

Esta funcionalidade do Unix foi emprestada por outros sistemas operacionais como o Taos e o MS-DOS, e hoje é considerado um padrão de projeto de software para implementação do conceito de canalização.