Warum reagiert die Umleitung der sed-Ausgabe in dieselbe Eingabedatei nicht mehr auf meinem Computer?

13

Ich habe versucht sed, einige Schlüsselwörter in einer großen Datei (100 MB) zu ersetzen. Die -i(Inplace-) Option war mir nicht bekannt, daher war mein erster Versuch, die Weiterleitung folgendermaßen durchzuführen:

sed 's/original/edited/g' file.log >> file.log

Was danach passierte war, dass mein PC zum Stillstand kam, fast ohne Tastatureingabe. Ich habe versucht , eine andere Konsole Ctrl+ Alt+ F1aber nach Benutzername langsam eintritt, ist es auch angehalten. Ohne Tastatur bestand meine einzige Option darin, die Maschine per Hardware-Reset zurückzusetzen. Nach dem Einloggen sah ich, dass file.log ungefähr 8 GB groß war.

Ich möchte wirklich verstehen, warum die Ausführung dieses Befehls dazu geführt hat, dass das System nicht mehr reagiert, und ob auf Systemebene Mechanismen vorhanden sind, die Warnungen auslösen und den fehlerhaften Prozess beenden.

cesarpachon
quelle
7
Ist das eine Single-Core-Maschine? Es scheint sehr seltsam, dass dies einen modernen Computer in die Knie gezwungen haben sollte. Deine Festplatte ist voll, ja. 100% eines Ihrer Kerne verbraucht, ja. Aber ein voller Absturz?
Terdon
Gibt es etwas Besonderes an dieser Datei? Wenn dies kein Problem ist, können Sie den Inhalt in Pastebin posten?
Sergiy Kolodyazhnyy
Wie groß ist auch Ihr Gedächtnis? Könnten Sie uns eine Ausgabe von liefern free -h ?
Sergiy Kolodyazhnyy
Warum überhaupt einen Stream-Editor verwenden, wenn Sie eine Datei ändern möchten? ex -sc '%s/original/edited/ge|x' file.logsollte tun, was Sie in einer UNIX-idiomatischen Weise ohne die sed -iNebenwirkungen wollen.
David Ongaro
Beachten Sie, dass eine Protokolldatei, die zu einem aktiven Prozess gehört, möglicherweise fehlerhaft verarbeitet wird, selbst wenn Sie dies ordnungsgemäß ausführen (nach einer der von den Mitarbeitern bereitgestellten Methoden).
Random832

Antworten:

10

>>Hängt, wie bereits gesagt, an die Datei an, sodass Ihr sedBefehl die gerade ausgegebenen Zeilen liest und sie dann weiter ausgibt. Wenn Sie wollten Ihre Datei an Ort und Stelle ersetzen, >würde immer noch nicht arbeiten, aber Sie sind sich bewusst von sed‚s - -iOption, die auf jeden Fall derjenige ist , Sie wollen.

Wenn Sie jedoch absolut sicher sind, dass Sie an eine Datei, die Sie als Stream lesen, einen Anhang anhängen möchten, und dies nur einmal tun möchten, ziehen Sie die Verwendung spongeaus dem moreutilsPaket in Betracht .

sed 's/original/edited/g' file.log | sponge >> file.log

spongeLiest von stdin in den Speicher, bis EOF, und speichert dann den gesamten Inhalt in stdout. Dadurch sedwird das Ende der Datei erreicht, das Lesen beendet, die Datei geschlossen und der Schwamm beginnt, daran anzuhängen.

ymbirtt
quelle
2
spongeist ein hilfreiches Werkzeug zu wissen, aber sedhat bereits eine -iOption: -i[SUFFIX], --in-place[=SUFFIX], edit files in place (makes backup if SUFFIX supplied).
Joshua Taylor
@JoshuaTaylor, OP verwendete >>, was anhängt und nicht >ersetzt. Zugegeben, OP wurde -iin der Veröffentlichung ausdrücklich erwähnt, und es scheint ein weitaus häufigerer Anwendungsfall als dieser zu sein, aber ich dachte, es wäre erwähnenswert, dass die spezifische Operation, die OP veröffentlicht hatte, ohne allzu großen Aufwand möglich war, wenn Sie wirklich sind Natürlich ist es das, was Sie tun möchten.
Ymbirtt
1
Ich erwähnte es hier, weil es der Schlüssel in der akzeptierten Antwort war . Das heißt, ich bin wirklich glücklich, über Schwamm zu lernen ; Es ist ein neues Tool für meine Toolbox und verdient eine positive Bewertung.
Joshua Taylor
1
Ah! Aha. Ich werde meine Antwort optimieren, um das ein bisschen klarer zu machen. Auch, wenn Sie es genossen haben sponge, werfen Sie einen Blick auf vipe. moreutilsist nur ein magisches Paket mit Dingen, von denen du nie
wusstest,
18

Ihr sedBefehl hat versucht, die Datei zu lesen, an die er angehängt wurde. Es wird niemals das Dateiende erreichen, aber viel CPU-Zeit in Anspruch nehmen. Deshalb wurde ^ C (Interrupt Current Process) erfunden.

Waltinator
quelle
Ich glaube nicht, dass ^ C eine Option war ... es kam zu einem HALT, dh kein blinkender Cursor, steckte fest!
EKons
18

Ein Zurückhängen an die Datei, aus der Sie gelesen haben, ist in keinem Fall eine gute Idee, da Sie am Ende eine ständig wachsende Datei haben werden. Wenn Sie wirklich in die Datei zurückschreiben möchten, sollten Sie das -iFlag verwenden:

sed -i 's/original/edited/g' file.log

oder wenn Sie möchten, dass ein Backup erstellt wird, bevor Sie Änderungen vornehmen, können Sie dem -iFlag ein Dateisuffix hinzufügen :

sed -i.bak 's/original/edited/g' file.log

Dies würde eine Datei mit dem Namen erzeugen file.log.bakund dann die Änderungen vornehmen, die Sie dort vorgenommen haben, indem Sie versucht haben, an die Datei, aus der Sie lesen, einen Slang für Daten anzuhängen, in dem verschiedene Prozesse für dieselbe Datenquelle - Eingabe oder Ausgabe - in Frage kommen . Dies ist auch der Grund, warum Ihre Maschine zum Stillstand gekommen ist.

Videonauth
quelle
1
Ich bin überrascht, dass dies die akzeptierte Antwort ist, da sie nicht einmal die Frage von OP beantwortet"I really would like to understand why the execution of that command was able to make the system so unresponsive, and if mechanisms exist at the system level to trigger alerts and kill the offending process?"
Steve,
@Steve Warum es zum Stillstand kam habe ich angesprochen, aber für den zweiten Teil hast du recht. Ich habe das nicht angesprochen, weil ich keine Antwort darauf kenne. Wir haben den Befehl nach einer ausführlichen Chat-Diskussion getestet und kamen auf verschiedenen Rechnern und Betriebssystemen zu völlig unterschiedlichen Ergebnissen. Beispiel: Auf einem Computer mit arch wird die Datei nur für immer vergrößert, der Computer reagiert jedoch nicht mehr. Auf meinem Ubuntu-Rechner hatte ich das gleiche Ergebnis wie der Fragesteller, ohne die Chance, den Vorgang abzubrechen. Ein zweiter Rechner, der dasselbe in einer Ubuntu-VM testete, kam zum selben Stillstand.
Videonauth
Ein straceTeil des gesamten Prozesses auf der anderen Seite reproduzierte das Ergebnis nicht und dies auf meinem Computer und auf dem Computer eines anderen Benutzers. Sicher, es gibt Mechanismen, mit denen Sie nicht mehr reagierende Anwendungen beenden können. Wenn Ihr Computer jedoch nicht mehr reagiert, haben Sie nur noch eine Option, mit der Sie ihn zurücksetzen können. Ich teste dies immer noch und bevor ich nicht vollständig verstehe, was das beschriebene Verhalten verursacht, kann ich diesen Teil der Frage nicht beantworten.
Videonauth
Es ist wahrscheinlich ein Unterschied in den Kernelkonfigurationen, wie z. B. ein anderer Scheduler, der E / A priorisiert, oder Unterschiede im Festplatten- / Dateisystemtreiber zwischen den Systemen. Es ist gut zu sehen, welche Ermittlungen ihr durchgeführt habt, das sind gute Informationen.
Steve
Wenn Sie an einem anderen Datenpunkt interessiert sind; Ich habe dies auf einem CentOS-Computer mit einer relativ kleinen Datei versucht, und es hat genau das Gleiche wie meine Schwammlösung unten getan. Ich stelle mir vor, dass für eine kleine Datei seddas ganze Ding in den Speicher gepuffert und dann geschlossen wird, anstatt den Griff festzuhalten. Bei einer ~ 100-MB-Datei wuchs sie wie in OP auf unbestimmte Zeit, ohne die Maschine zu blockieren.
Ymbirtt