Cosa fa il simbolo della pipe di Linux “|”? [duplicare]


23

Ecco un comando che ordina i file in una cartella in ordine inverso

ls | sort -r

Cosa fa il |simbolo in quel comando?

Quello che sto davvero cercando qui è una spiegazione di alto livello (facile da capire) delle pipe per i principianti di Linux. Vedo altre domande sulle pipe qui su Superuser, ma nulla che suscita una risposta che spiega in termini semplici cosa fanno e come differiscono dal reindirizzamento (il simbolo >o <).


7
Questo non ha nulla a che fare con Linux (che è un kernel). I tubi in generale sono un mezzo per ri-dirigere input / output, in una shell come bash non è diverso. L'unica cosa speciale di a |è che non usa un nome, l'output del comando l-hand viene passato direttamente all'input per il comando sul lato r della pipe.
Andon M. Coleman,

Per una lezione di storia sull'argomento, leggi linfo.org/pipe.html
Fredrik Pihl,

ls -1r(Nota l'argomento numero uno) dovrebbe produrre risultati simili a ls | sort -r.
Ivan Chau,

Mi piace spiegarlo in questo modo: una pipe prende l'output di un comando e lo rende utilizzabile per un comando seguente. Ad esempio, puoi farlo cat /somefile | grep cool. Questo prenderà l'output di somefile e lo renderà disponibile per grep, quindi grep stamperà tutte le righe con la parola cool in esso.
JohnDoea,

Risposte:


26

Quanto segue è leggermente semplificato per aiutare i nuovi utenti.

Bene, in primo luogo, è necessario comprendere il concetto di input standard e output standard.

In Linux e altri sistemi operativi simili a UNIX, ogni processo ha un input standard ( stdin) e un output standard ( stdout). La solita situazione è quella stdindella tastiera e stdoutdello schermo o della finestra del terminale.

Quindi, quando corri ls, genererà il suo output stdout. Se non fai nient'altro, andrà allo schermo o alla finestra del terminale e lo visualizzerai.

Ora, alcuni comandi di Linux interagiscono con l'utente e lo usano stdin, il tuo editor di testo è uno di quelli. Legge da stdinaccettare i tasti premuti, fare cose e quindi scrivere cose su stdout.

Tuttavia, ci sono anche comandi non interattivi o "filtro" che NON funzionano in modo interattivo, ma vogliono un sacco di dati. Questi comandi prenderanno tutto ciò che stdinha, faranno qualcosa e poi lo lancerannostdout

Diamo un'occhiata a un altro comando chiamato du- indica l'utilizzo del disco. du /usr, ad esempio, stamperà (per stdoutapprezzare qualsiasi altro comando Linux) un elenco di ogni file in quella directory e le sue dimensioni:

# 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 si può capire subito, non è ordinato e probabilmente lo si desidera in ordine di grandezza.

sortè uno di quei comandi "filtro" che prenderanno un sacco di cose stdine le ordineranno.

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 la "pipe" collega il stdoutcomando di un comando a quello stdindi un altro. In genere lo utilizzerai in situazioni come questa in cui desideri filtrare, ordinare o altrimenti manipolare l'output di un comando. Possono essere collegati in cascata se si desidera elaborare l'output tramite più comandi di tipo filtro.

Se digiti sortda solo, proverà comunque a leggere stdin. Poiché stdinè collegato alla tua tastiera, ti aspetterà di digitare e di elaborare le cose fino a quando non premi Control-D. Non ti chiederà perché non è davvero pensato per essere usato in modo interattivo.

È possibile che un programma indichi se stdinè interattivo o meno, quindi alcuni programmi potrebbero agire in modo diverso se vengono emessi da soli o alla fine di una pipe.

Inoltre, il piping di un programma che funziona solo in modo interattivo, come vi, ti farà passare dei brutti momenti.

I tubi sono diversi dal reindirizzamento in quanto i dati vengono mescolati da un comando all'altro senza essere memorizzati in alcun luogo. Quindi, nell'esempio sopra, dul'output non è memorizzato da nessuna parte. La maggior parte delle volte non lo vuoi con le pipe perché il motivo per usare le pipe è quello di elaborare l'output di un comando in qualche modo - ma, c'è un comando teeche ti consente di avere la tua torta e mangiarla anche, lo farà copia ciò che riceve da stdinentrambi stdoute un file di tua scelta. Probabilmente puoi farlo anche bashcon una sintassi arcana che coinvolge e commerciali e parentesi che non conosco.


Nota che questo non è univoco per Linux, o POSIX. La maggior parte (tutte?) Le shell su Windows fanno anche questo. E probabilmente altri sistemi operativi.
Bob,

Conosco il concetto di stdined stdoutè diverso in Windows rispetto a Linux, anche se probabilmente non molto dal punto di vista di Windows cmd.exeo Powershell.
LawrenceC,

Sono piuttosto curioso di sapere come è diverso - ti dispiacerebbe spiegare? Forse in chat se i commenti non sono un buon posto per farlo.
Bob,

1
I programmi Win32 hanno sicuramente un input e un output standard. Ad esempio, è possibile recuperare input, output o handle di errore standard del processo con la funzione Win32 GetStdHandle(). È anche banale reindirizzare gli stream standard di un processo [figlio] generato con .NET, che credo sia mappato alle funzioni Win32 (ma non ne sono sicuro al 100% - non sono uno sviluppatore Win32).
Bob,

1
Ah, ecco l'equivalente di Win32, impostando i parametri appropriati nella STARTUPINFOstruttura per CreateProcess().
Bob,

27

Se hai dimestichezza con il reindirizzamento di output e input, la spiegazione è davvero abbastanza semplice.

Command1 | Command2

fa lo stesso di

Command1 > tempfile
Command2 < tempfile

ma senza tempfile. L'uscita di Command1è direttamente collegata all'ingresso di Command2e il trasferimento avviene in memoria.


Potrei sbagliarmi, ma penso che il tempfile esista anche nella sintassi della pipe. Semplicemente non ha un nome.
Taemyr,

3
No non lo fa. Non sono coinvolte operazioni sul file system quando si esegue il piping dell'output da un comando all'input di un altro comando.
Daniel B,

1
Anche se, sotto DOS (e molto probabilmente Windows), un file temporaneo viene creato dal tubo. Non * nix, ma non vale la differenza.
Jeremy J Starcher,

Sono abbastanza sicuro che questo non sia corretto. Process Monitor segnala di no CreateFileo WriteFilechiama per sostenere il reclamo. / modifica: ovviamente per la parte Windows.
Daniel B,

3

Davvero se vuoi sapere cosa fanno le pipe e la differenza tra> e |, vai in una directory con molti file e

da un terminale ls vs ls | more (o farlo da Windows con DIR e DIR | ALTRO)

Se hai usato> more vedrai che crea un file chiamato 'more' anziché inviare l'output di ls al comando 'more'. Quindi, se qualcuno facesse> di più, probabilmente sarebbe un errore, non si farebbe> di più si farebbe> file1. More è un comando ben noto.

<Like the> serve anche per collegare un comando e un file, anziché un comando a un comando. Ma mentre> invia l'output di un comando a un file, <invia un file come input a un comando. Uso raramente <come di solito uso cat file1 | per inviare l'output di un file a un comando.

$ grep a <file1 abc

$ cat file1 | grep a abc

grep con 2 parametri è del file modello grep del modulo. grep con un parametro è il modello grep. E puoi inviarlo al file eseguendo il piping del contenuto del file o usando <. Se si utilizza <, si scrive prima il nome del comando, quindi il nome del file dopo il comando <file. Se si utilizza | per reindirizzare il contenuto di un file, si utilizza cat file1 | comando.

Inoltre molti comandi accettano comunque un file come input, quindi grep un file1 funzionerà, proprio come cat file1 | grep a e grep a <file1.

Stavo facendo pipe (|) e> su DOS anche 15 anni fa.

Riassumendo come | differisce da <e> - La pipe si trova tra 2 comandi La <e> si trova tra un comando e un file. > Viene emesso in un file. <Viene immesso da un file.


3

Il carattere pipe ( |) collega l'output di un programma all'ingresso di un altro.

In questo esempio echostampa la parola helloe wc -cconta un carattere del suo input:

echo hello | wc -c

Penso che dovresti dire subito che l'eco produrrà "ciao \ n". Non stai dicendo all'OP di studiare, lo stai dicendo a tutti coloro che leggono la tua risposta. Perché moltiplicare questa perdita di tempo?
Rodrigo,

Grazie per il feedback, ho abbreviato la mia risposta.
bbaassssiiee,

2

Per capirlo, provalo tu stesso:

sort -r

Ora stai appeso con un cursore e non sta facendo nulla. Cosa succede se si digitano alcuni dati?

1
2
3
5
4

Ancora niente, vero? Ora premi ctrl + D

5
4
3
2
1

Quindi, ciò che fa l'ordinamento è, prende input (ciò che hai digitato), fa qualcosa con esso (ordina) e lo restituisce come output. Il lscomando non accetta input, genera solo output. Il simbolo della pipe prende l'output lse lo alimenta come input per il sortcomando.

>non invia l'output a un programma, ma archivia l'output come file. <utilizza un file come input.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.