![Linux-Ausgabeumleitung funktioniert nicht mit awk](https://rvso.com/image/1337795/Linux-Ausgabeumleitung%20funktioniert%20nicht%20mit%20awk.png)
Ich versuche, eine schöne CSV-Datei basierend auf einigen Ausgaben von top zu schreiben. Ich formatiere die Ausgabe mit awk wie folgt neu:
top -b | nawk '/Cpu/ || /Tasks/ { if($1 ~ /Cpu/) { printf "%s,",$3 } else { printf "\n" } }'
Das funktioniert einwandfrei. Jetzt möchte ich die Ausgabe in einer Datei speichern. Ich würde denken, dass dies mit folgendem > output.log
funktionieren sollte:
top -b | nawk '/Cpu/ || /Tasks/ { if($1 ~ /Cpu/) { printf "%s,",$3 } else { printf "\n" } }' > output.log
Das Ergebnis ist jedoch einfach eine leere Datei, wenn ich den Top-Prozess mit Strg+C verlasse. Was mache ich falsch?
Antwort1
Die Standard-E/A-Bibliothek („stdio“) von Unix erkennt, in welche Art von Objekt (Datensenke) sie schreibt. Wenn sie ein Terminal (also ein Fenster) erkennt, schreibt sie die Daten sofort, wenn das Programm sie anfordert. Beim Schreiben in eine Datei puffert die E/A-Bibliothek die Daten jedoch und schreibt sie in Blöcken von 512 (oder mehr) Bytes auf einmal. Natürlich leert sie den Puffer (schreibt einen Teilblock aus), wenn das aufrufende Programm beendet wird – sofern es sauber beendet wird. Eine abnormale Beendigung (wie durch Ctrl+ verursacht C) kann zu einer unvollständigen Ausgabedatei führen.
Versuchen Sie zur Behebung des Problems Folgendes:
top -b | ( trap "" 2; nawk '
(Ihrnawk
Befehl)' > output.log)
`
Der trap
Befehl macht den nawk
Befehl immun gegen Ctrl+ C. (Natürlich wird Ctrl+ Cden Prozess trotzdem beenden top
und nawk
(sauber!) beenden, wenn er ein Dateiende (EOF) auf der Pipe erhält.
bash
PS: Dies setzt voraus (erfordert), dass Sie eine -kompatible Shell ausführen bash
.
Antwort2
Top läuft weiter. Sie möchten es eine begrenzte Anzahl von Malen ausführen. Verwenden Sie die Option -n. So:
top -b -n 1 | awk '{ ... }'
Alternativ können Sie top bei Bedarf mit C-\ beenden. Die Verwendung von Cc bricht es ab und unterbricht die Pipe vorzeitig (bevor awk etwas erhält).
$ top -b | cat -n > moo ; wc -l moo
^\Quit
352 moo