Non ho mai pensato a come la shell esegua effettivamente i comandi convogliati. Mi è sempre stato detto che "lo stdout di un programma viene convogliato nello stdin di un altro", come un modo di pensare alle pipe. Quindi, naturalmente, ho pensato che nel caso di esempio, A | B
, A
verrebbe eseguito prima, quindi B
ottiene lo stdout di A
e utilizza lo stdout di A
come input.
Ma ho notato che quando le persone cercano un processo particolare in ps
, includerebbero grep -v "grep"
alla fine del comando per assicurarsi che grep
non appare nell'output finale.
Ciò significa che nel comando ps aux | grep "bash" | grep -v "grep"
è implicito che ps
sapeva che grep
era in esecuzione e quindi è nell'output di ps
. Ma se ps
termina l'esecuzione prima che il suo output venga reindirizzato a grep
, come faceva a sapere che grep
era in esecuzione?
[email protected]: ~$ ps | grep ".*"
PID TTY TIME CMD
3773 pts/0 00:00:00 bash
3784 pts/0 00:00:00 ps
3785 pts/0 00:00:00 grep
Risposta accettata:
I comandi convogliati vengono eseguiti contemporaneamente. Quando esegui ps | grep …
, è la fortuna del sorteggio (o una questione di dettagli sul funzionamento della shell combinata con la messa a punto dello scheduler nelle viscere del kernel) se ps
o grep
inizia prima, e in ogni caso continuano ad essere eseguiti contemporaneamente.
Questo è molto comunemente usato per consentire al secondo programma di elaborare i dati così come escono dal primo programma, prima che il primo programma abbia completato la sua operazione. Ad esempio
grep pattern very-large-file | tr a-z A-Z
inizia a visualizzare le righe corrispondenti in maiuscolo anche prima di grep
ha finito di attraversare il file di grandi dimensioni.
grep pattern very-large-file | head -n 1
visualizza la prima riga corrispondente e potrebbe interrompere l'elaborazione molto prima di grep
ha finito di leggere il suo file di input.
Se leggi da qualche parte che i programmi in pipe vengono eseguiti in sequenza, fuggi da questo documento. I programmi in pipe vengono eseguiti contemporaneamente e sempre.