Unix e Node – Pipe e Stream
Un flusso anonimo può essere usato per passare lo stream di un processo ad un altro.
Si prenda ad esempio:
cat file.md | grep -c node |
Le pipes sotto UNIX sono tipicamente denotate dal carattere |
. Entrambi i concetti di pipe e la notazione |
sono stati ideati da Doug Mcllroy.
Il comando cat file.md
legge il contenuto del file file.md
, con il restante | grep -c node
non facciamo altro che passare il suo stream ad un altro applicativo chiamato grep
, che in questo caso legge lo stream in input e conta il numero di occorrenze per la stringa “node”.
L’esempio banale mostra come di fatti attraverso stream e pipes si possa passare l’output di un programma ad un altro.
Stream
Node.js fornisce una rappresentazione astratta di uno stream attraverso la classe Stream. E’ attualmente molto usata all’interno di Node e non fa altro che rappresentare ciò di cui abbiam discusso sopra.
Infatti include persino un metodo pipe
:
stream.pipe(destinazione, [opzioni]) |
Questo significa che possiamo di fatti connettere lo standard input (stdin) con lo standard output (stdout) in questo modo:
#!/usr/bin/env node process.stdin.resume(); process.stdin.pipe(process.stdout); |
Il metodo resume
viene chiamato perchè di default lo stdin è messo in pausa.
La prima riga, in UNIX, è necessaria per indicare quale interprete vogliamo usare per eseguire lo script. In questo caso Node.
Eventualmente è possibile anche specificare la codifica per lo stream in input:
process.stdin.setEncoding('utf8'); |
Proviamo adesso a simulare il comportamento di cat
attraverso lo script in Node.
Per prima cosa assicuriamoci che lo script sopra, venga salvato come cat.js ed abbia i permessi d’esecuzione:
chmod 700 cat.js |
Fatto questo siamo pronti ad eseguirlo:
$ echo 'Esempio di input testuale e pipe' | ./cat.js |
Che restituisce effettivamente la stringa in input:
$ Esempio di input testuale e pipe |
La cosa bella degli stream in Node è che funzionano come ogni altra cosa in modo asincrono ed event-based:
stream.on('data', function(data) { console.log('Received data:', data); }); |
Quando uno stream viene passato ad un metodo pipe, l’evento data
viene emesso e può essere catturato.
Conclusioni
Avendo a disposizione queste semplici API asincrone per gli stream, realizzare programmi in Node che interagiscono con altri programmi attraverso le pipeline è estremamente facile.
Per ulteriori dettagli ed esempi si consiglia la lettura della documentazione ufficiale sugli Stream in Node.js.
Commenti