
Ich habe eine Blindfrage an Sie: Ich versuche, einige Zeilen aus einer Datei zu extrahieren, die mit einer speziellen Zeichenfolge beginnen, und sie in eine Datei zu kopieren. Ich habe Folgendes versucht:
cat /dev/ttyACM0 | grep "something" > essai
Die Datei wird erstellt, enthält aber nichts!
Antwort1
Aus Effizienzgründen verwenden grep und viele andere Befehlegepufferte E/A, das heißt, sie lesen große Datenblöcke auf einmal (anstatt etwa jeweils ein Zeichen) und geben Daten erst aus, wenn eine bestimmte Menge angesammelt ist (anstatt etwa jeweils eine Zeile oder ein Zeichen zu schreiben).
Wenn die Eingabe eines Programms jedoch von einem Terminal (wie z. B. Ihrem seriellen Port) kommt, tut das Betriebssystem dem Programm einen Gefallen und gibt jeweils eine Zeile zurück (das Programm kann dies ändern, indem es das Terminal inrohodernichtkanonischer Modus; die meisten tun das nicht).
Und wenn ein Programm diestdioBibliothek wird die Standardausgabe an ein Terminal (in der Dokumentation wird dies als „interaktives Gerät“ bezeichnet) standardmäßig zeilengepuffert, die Ausgabe in eine Datei oder Pipe jedoch vollständig gepuffert.
Ein Programm, das die stdio-Bibliothek verwendet, kann zwischen Vollpufferung, Zeilenpufferung oder keiner Pufferung wählen, indem essetvbuf
Es kann auch anrufenfflush
um einen Schreibvorgang zu erzwingen, wann immer dies gewünscht wird.
GNU grep nimmt eine--line-buffered
Option, die denfolgender Codein der Funktion, die eine passende Zeile ausgibt:
if (line_buffered)
fflush (stdout);
Alle Teile zusammenfügen:
Mit diesem Befehl:
cat /dev/ttyACM0 | grep "something" > essai
cat
liest jeweils eine Zeile aus /dev/ttyACM0
. Nachdem es einige Kilobyte an Ausgabe angehäuft hat, schreibt es in die Pipe. Dies wird wiederholt, bis der Lesevorgang Null zurückgibt oder fehlschlägt (was wahrscheinlich erst passieren wird, wenn der serielle Port offline geht).
grep
liest jeweils einige Kilobyte aus der Pipe und schreibt in die essai
Datei, nachdem einige Kilobyte an Ausgabe angehäuft wurden. Dies wird wiederholt, bis der Lesevorgang Null zurückgibt oder fehlschlägt, was passiert, wenn der cat
Prozess beendet wird.
Sie werden also nichts in der essai
Datei sehen, bis grep
ein paar Kilobyte an übereinstimmenden Zeilen gefunden wurden.
Um die Ausgabe schneller in die Datei zu schreiben, können Sie GNU grep diese Option geben:
grep --line-buffered < /dev/ttyACM0 > essai
Da das Lesen über einen seriellen Port erfolgt, wird es zeilengepuffert und die --line-buffered
Option sorgt dafür, dass auch die Ausgabe zeilengepuffert wird.