Spiegazione semplificata
Come molte utility, non essendo qualcosa di peculiare per un programma, grep
varia l'output standard tra il buffer di linea e il buffer completo . Nel primo caso, la libreria C buffer esegue l'output dei dati in memoria fino a quando il buffer contenente tali dati non viene riempito o non viene aggiunto un carattere di avanzamento riga (o il programma termina in modo pulito), dopodiché chiama write()
per scrivere effettivamente il contenuto del buffer. In quest'ultimo caso, solo il buffer in memoria che si riempie (o che il programma termina in modo pulito) attiva ilwrite()
.
Spiegazione più dettagliata
Questa è la spiegazione ben nota, ma leggermente sbagliata. In effetti, l'output standard non è bufferizzato in linea ma smart buffer nella libreria GNU C e nella libreria BSD C. Uscita standard è anche ripulita quando la lettura standard di ingresso esaurisce suo buffer nella memoria (di ingresso pre-lettura) e la libreria C deve chiamare read()
per recuperare alcuni più ingressi ed è leggendo l'inizio di una nuova linea. (Una ragione di ciò è prevenire il deadlock quando un altro programma si connette a entrambe le estremità di un filtro e si aspetta di essere in grado di operare riga per riga, alternando la scrittura al filtro e la lettura da esso; come "coprocessi" in GNU awk
per esempio.)
Influenza della biblioteca C.
grep
e le altre utility fanno questo - o, più rigorosamente, le librerie C che usano lo fanno, perché questa è una caratteristica definita della programmazione nel linguaggio C - in base a ciò che rilevano il loro output standard. Se (e solo se) non è un dispositivo interattivo, scelgono il buffering completo, altrimenti scelgono il buffering intelligente. Una pipe non è considerata un dispositivo interattivo, poiché la definizione di dispositivo interattivo, almeno nel mondo di Unix e Linux, è essenzialmente la isatty()
chiamata che ritorna vera per il descrittore di file pertinente.
Soluzioni alternative per disabilitare il buffering completo
Alcune utility come grep
hanno opzioni idiosincratiche come quella --line-buffered
che cambiano questa decisione, che come puoi vedere è sbagliata. Ma una minima parte dei programmi di filtro che si potrebbe usare in realtà ha una tale opzione.
Più in generale, si possono usare strumenti che scavano negli interni specifici della libreria C e cambiano il suo processo decisionale (che hanno problemi di sicurezza se il programma da modificare è set-UID, e sono anche specifici per particolari librerie C, e in effetti lo sono specifico per i programmi scritti o sovrapposti al linguaggio C) o strumenti come quelli ptybandage
che non cambiano gli interni del programma ma semplicemente interpongono uno pseudo-terminale come output standard in modo che la decisione venga presa come "interattiva", per influenza questo.
Ulteriori letture
cat
concatena i file. Cosa stai cercando di fare collegandocat
?