Se sei a tuo agio con il reindirizzamento dell'output e dell'input, la spiegazione è davvero abbastanza semplice.
Command1 | Command2
fa lo stesso di
Command1 > tempfile
Command2 < tempfile
ma senza tempfile
. L'output di Command1
è direttamente connesso all'ingresso di Command2
e il trasferimento avviene in memoria.
Quanto segue è un po' semplificato per aiutare i nuovi utenti.
Bene, per prima cosa è necessario comprendere il concetto di standard input e standard output.
In Linux e altri sistemi operativi simili a UNIX, ogni processo ha un input standard (stdin
) e uno standard output (stdout
). La solita situazione è che stdin
è la tua tastiera e stdout
è il tuo schermo o la finestra del terminale.
Quindi, quando esegui ls
, genererà il suo output in stdout
. Se non fai nient'altro, andrà sullo schermo o nella finestra del terminale e lo visualizzerai.
Ora, alcuni comandi di Linux interagiscono con l'utente e usano stdin
per farlo, il tuo editor di testo è uno di quelli. Legge da stdin
per accettare le tue sequenze di tasti, fare cose e poi scrivere cose su stdout
.
Tuttavia, ci sono anche comandi non interattivi o di "filtro" che NON funzionano in modo interattivo, ma richiedono un mucchio di dati. Questi comandi prenderanno tutto stdin
has, fai qualcosa e poi lancialo in stdout
Diamo un'occhiata a un altro comando chiamato du
- sta per utilizzo del disco. du /usr
, ad esempio, stamperà (fino a stdout
come qualsiasi altro comando Linux) un elenco di tutti i file in quella directory e la sua dimensione:
# du /usr
2312 /usr/games
124 /usr/lib/tc
692 /usr/lib/rygel-1.0
400 /usr/lib/apt/methods
40 /usr/lib/apt/solvers
444 /usr/lib/apt
6772 /usr/lib/gnash
Come puoi capire subito, non è ordinato e probabilmente vorrai che sia ordinato in ordine di grandezza.
sort
è uno di quei comandi "filtro" che prenderanno un sacco di cose da stdin
e ordinalo.
Quindi, se lo facciamo:
# du /usr | sort -nr
otteniamo questo, che è un po' meglio:
4213348 /usr
2070308 /usr/lib
1747764 /usr/share
583668 /usr/lib/vmware
501700 /usr/share/locale
366476 /usr/lib/x86_64-linux-gnu
318660 /usr/lib/libreoffice
295388 /usr/lib/vmware/modules
290376 /usr/lib/vmware/modules/binary
279056 /usr/lib/libreoffice/program
216980 /usr/share/icons
E ora puoi vedere che il "tubo" collega il stdout
di un comando al stdin
di un altro. In genere lo utilizzerai in situazioni come questa in cui desideri filtrare, ordinare o manipolare in altro modo l'output di un comando. Possono essere collegati in cascata se si desidera elaborare l'output tramite più comandi di tipo filtro.
Se digiti sort
da solo, proverà comunque a leggere da stdin
. Da stdin
è collegato alla tua tastiera, aspetterà che tu digiti ed elabori le cose fino a quando non premi Control-D. Non ti chiederà perché non è pensato per essere usato in modo interattivo.
È possibile che un programma dica se stdin
è interattivo o meno, quindi alcuni programmi potrebbero agire in modo diverso se li emetti da soli o alla fine di una pipe.
Inoltre, reindirizzare un programma che funziona solo in modo interattivo, come vi
, ti farà passare un brutto momento.
Le pipe sono diverse dal reindirizzamento in quanto i dati vengono spostati da un comando all'altro senza essere archiviati da nessuna parte. Quindi, nell'esempio precedente, du
l'output di non è memorizzato da nessuna parte. La maggior parte delle volte non lo vuoi con le pipe perché il motivo per usare le pipe è elaborare l'output di un comando in qualche modo - ma c'è un comando tee
che ti permette di avere la tua torta e anche di mangiarla, copierà ciò che riceve da stdin
a entrambi stdout
e un file a tua scelta. Probabilmente puoi farlo anche da bash
con una sintassi arcana che coinvolge e commerciali e parentesi che non conosco.
Davvero, se vuoi sapere cosa fanno le pipe e la differenza tra> e |, allora vai in una directory con molti file, e
da un terminale ls
rispetto a ls | more
(o farlo da Windows con DIR e DIR | MORE)
Se hai usato> more vedrai che crea un file chiamato 'more' invece di inviare l'output di ls al comando 'more'. Quindi se qualcuno facesse>di più probabilmente sarebbe un errore, uno non farebbe>di più faresti>file1. Altro è un comando ben noto.
Il
$ grep a
$ gatto file1 | grep aabc
grep con 2 parametri ha il formato grep pattern file. grep con un parametro è grep pattern. E puoi inviargli il file inviandogli il contenuto del file o usando <. Se usi <, scrivi prima il nome del comando, poi il nome del file dopo so command
Inoltre, molti comandi accettano comunque un file come input, quindi grep a file1 funzionerà, proprio come cat file1 | grep a, e grep a
Stavo facendo pipe (|) e> su DOS anche 15 anni fa.
Per riassumere come | differisce da