È molto più facile visualizzare le cose se pensi a cosa sta realmente succedendo con "reindirizzamenti" e "pipe". I reindirizzamenti e le pipe in bash fanno una cosa: modifica dove i descrittori del file di processo 0, 1 e 2 puntano a (vedi / proc / [pid] / fd / *).
Quando una pipe o "|" l'operatore è presente sulla riga di comando, la prima cosa che succede è che bash crea un FIFO e punta il FD 1 del comando sul lato sinistro verso questo FIFO, e punta FD 0 del comando sul lato destro sullo stesso FIFO.
Successivamente, gli operatori di reindirizzamento per ciascun lato vengono valutati da sinistra a destra e vengono utilizzate le impostazioni correnti ogni volta che si verifica la duplicazione del descrittore. Questo è importante perché dalla prima installazione del tubo, l'FD1 (lato sinistro) e l'FD0 (lato destro) sono già cambiati da quello che avrebbero potuto essere normalmente, e qualsiasi duplicazione di questi rifletterà quel fatto.
Pertanto, quando si digita qualcosa di simile al seguente:
command 2>&1 >/dev/null | grep 'something'
Ecco cosa succede, in ordine:
- viene creato un pipe (fifo). "comando FD1" è puntato su questa pipe. Anche "grep FD0" è puntato su questa pipe
- "comando FD2" è indicato dove "comando FD1" indica attualmente (la pipe)
- "comando FD1" è puntato su / dev / null
Quindi, tutto l'output che "command" scrive su FD 2 (stderr) si dirige verso la pipe e viene letto da "grep" dall'altra parte. Tutto l'output che "comando" scrive nel suo FD 1 (stdout) si dirige verso / dev / null.
Se invece, esegui quanto segue:
command >/dev/null 2>&1 | grep 'something'
Ecco cosa succede:
- viene creato un pipe e "command FD 1" e "grep FD 0" vengono puntati su di esso
- "comando FD 1" è puntato su / dev / null
- "comando FD 2" è indicato dove attualmente punta FD 1 (/ dev / null)
Quindi, tutto stdout e stderr dal "comando" vanno a / dev / null. Nulla va alla pipa, e quindi "grep" si chiuderà senza visualizzare nulla sullo schermo.
Si noti inoltre che i reindirizzamenti (descrittori di file) possono essere di sola lettura (<), sola scrittura (>) o lettura-scrittura (<>).
Un'ultima nota. Se un programma scrive qualcosa su FD1 o FD2, dipende interamente dal programmatore. La buona pratica di programmazione impone che i messaggi di errore debbano andare a FD 2 e l'output normale a FD 1, ma spesso troverete una programmazione sciatta che mescola i due o ignora in altro modo la convenzione.