# Pipe (informatica)

Il termine pipe ha due significati strettamente correlati tra loro:
* indica uno degli strumenti di comunicazione tra processi offerti dal sistema operativo;
* indica una funzionalità delle shell testuali basata sul precedente.

## Pipe come strumento di comunicazione tra processi

Nei sistemi operativi una pipe è uno degli strumenti disponibili per far comunicare tra loro dei processi. Le pipe, diversamente dai socket, offrono un canale di comunicazione monodirezionale, e quindi occorre impiegarne due per ottenere una comunicazione bidirezionale.
Nei sistemi operativi Unix e Unix-like una pipe è accessibile tramite una coppia di descrittori di file, uno per scrivere dati e l'altro per leggerli. Un processo crea una pipe tramite la chiamata di sistema pipe(2), che restituisce i due descrittori di file.
In maniera analoga, nei sistemi operativi Microsoft Windows una pipe convenzionale è denominata anonymous pipe ed è usabile tramite una coppia di handle: il primo per la scrittura dei dati, il secondo per la lettura. Per creare una anonymous pipe va usata la chiamata di sistema CreatePipe.
Il flusso di dati scritto da un processo (scrittore) sul descrittore di file o handle aperto in scrittura viene poi letto (nello stesso ordine) dall'altro processo (lettore) tramite il descrittore di file o handle aperto in lettura. I dati generati dallo scrittore e non ancora letti sono memorizzati dal sistema operativo in un buffer di dimensioni predeterminate (tipicamente pochi KiB), dal quale sono automaticamente rimossi dopo essere stati letti.
Il buffer viene usato come meccanismo di sincronizzazione tra i due processi: quando si riempie, il processo scrittore viene sospeso nell'operazione di scrittura fino a quando il lettore non ha prelevato una parte dei dati; quando il buffer si svuota il lettore viene sospeso nell'operazione di lettura fino a quando lo scrittore non ha inviato nuovi dati.
I due processi che comunicano attraverso una pipe devono in qualche modo scambiarsi i descrittori di file o handle da usare:
* nei sistemi operativi Unix e Unix-like un processo può, tramite la chiamata di sistema pipe, creare una pipe, quindi, tramite la chiamata di sistema fork, creare un processo figlio, il quale eredita i descrittori di file del padre: il processo padre può inviare dati al processo figlio scrivendo sul descrittore di file aperto in scrittura, mentre il processo figlio li può ricevere leggendolo dall'altro descrittore di file (aperto in lettura). Questo metodo richiede che tra i due processi esista una relazione di parentela. Altri metodi richiedono lo scambio di descrittori di file mediante un socket in dominio Unix.
* nei sistemi operativi Microsoft Windows un processo può creare una anonymous pipe tramite chiamata di sistema, e poi creare un nuovo processo con cui condividere gli handle specificando i parametri alla chiamata di sistema CreateProcess.

### FIFO o named pipe

Se due processi che devono comunicare tra loro con una pipe sono del tutto separati (ovvero non hanno modo di scambiarsi tra loro dei descrittori di file o handle), è possibile creare nel file system un file speciale detto FIFO o named pipe, che funge da punto di accesso alla pipe: scrivendo su questo file speciale si inviano dati alla pipe, mentre leggendolo si possono prelevare. È da sottolineare che anche in questo caso i dati scambiati non sono memorizzati temporaneamente nel file system, ma transitano da un processo all'altro tramite un buffer.
In questo modo, un processo può offrire un servizio ad altri processi aprendo una named pipe in una posizione nota del file system.
Nei sistemi operativi Unix e Unix-like si può creare una named pipe tramite il comando mknod, o tramite l'omonima chiamata di sistema mknod, o ancora tramite il comando mkfifo; i processi che comunicano tramite essa debbono essere in funzione sullo stesso host (ad esempio non è possibile usare una named pipe creata in un file system condiviso in rete come NFS per far comunicare processi residenti su host diversi).
Nei sistemi operativi Microsoft Windows le named pipe sono create usando la chiamata di sistema CreateNamedPipe. Al contrario dei sistemi Unix e Unix-like, esse possono essere utilizzate direttamente da processi residenti su host diversi.

## Funzione pipe nelle shell testuali

Nelle shell testuali di molti sistemi operativi (tra cui i sistemi Unix e Unix-like, MS-DOS e Microsoft Windows) esiste una sintassi per combinare tra loro con una pipe due programmi semplici, in modo da realizzare una elaborazione complessa in cascata senza l'uso di file temporanei (e quindi adatta ad esempio a grandi volumi di dati).
Il carattere utilizzato nella sintassi è la barra verticale: |, talora detta essa stessa pipe; viene inserita tra le invocazioni di due o più programmi per indicare alla shell che i dati diretti allo standard output del programma precedente debbono essere inviati allo standard input del programma successivo usando una pipe. Di fatto la shell provvede a creare le pipe tramite chiamata di sistema, ed in seguito avvia i programmi indicati sostituendo in essi lo standard output e lo standard input con i descrittori di file della pipe.
Ad esempio, nei sistemi Unix e Unix-like, la riga di comando che segue legge il file file.txt tramite il comando cat, che invia i dati al comando tr per sostituire gli spazi ed i segni di punteggiatura con il carattere di ritorno a capo; a sua volta esso passa il risultato al comando sort per ordinare le linee, che lo passa al comando uniq per scartare le linee duplicate, ottenendo così un elenco ordinato alfabeticamente delle parole contenute nel file:
Una sequenza di comandi uniti con le pipe come quella sopra esposta è detta pipeline software.
Un programma progettato per lavorare leggendo dati dallo standard input e producendo il risultato sullo standard output è detto filtro.