Gibt es eine Möglichkeit, die Ausgabe in eine Datei umzuleiten, ohne sie unter Unix / Linux zu puffern?


49

Ich habe einen Batch-Prozess mit langer Laufzeit, der einige Debug- und Prozessinformationen an stdout ausgibt. Wenn ich nur von einem Terminal aus laufe, kann ich verfolgen, wo es ist, aber dann werden die Daten zu groß und rollen vom Bildschirm.

Wenn ich zur Ausgabe in eine Datei '> out.txt' umleitung, erhalte ich die gesamte Ausgabe, sie ist jedoch gepuffert, sodass ich nicht mehr sehen kann, was sie gerade tut.

Gibt es eine Möglichkeit, die Ausgabe umzuleiten, aber die Schreibvorgänge nicht zu puffern?


1
Könnten Sie bitte einen Blick auf meine (und @cnst 's) "Debatte" werfen, ich vermute, Sie möchten nur die Ausgabe gleichzeitig mit dem Protokollieren in eine Datei sehen. Wenn Sie eine Lösung gefunden haben, lassen Sie es uns wissen;)!
Benj

Antworten:


52

Sie können die Pufferungsoptionen der Standard-Streams explizit mithilfe eines setvbufAufrufs in C festlegen (siehe diesen Link ). Wenn Sie jedoch versuchen, das Verhalten eines vorhandenen Programms zu ändern, versuchen Sie es stdbuf(dies ist coreutilsanscheinend Teil des Starts mit Version 7.5).

Dies puffert stdoutbis zu einer Zeile:

stdbuf -oL command > output

Dies deaktiviert die stdoutPufferung insgesamt:

stdbuf -o0 command > output

aaarghhh ... Mein Ubuntu hat nur 7.4 coreutils ... :(
Calmarius

@Calmarius: Das Kompilieren von Coreutils sollte recht einfach sein. Holen Sie sich einfach eine neue Version von ftp.gnu.org/gnu/coreutils und probieren Sie es aus. Es ist Standardtarif ./configure && make. Sie müssen es nicht einmal nachträglich installieren, sondern können einfach die stdbufBinärdatei off verwenden src/.
Eduardo Ivanec

doppelte Argh. Ich brauche dies auf einem alten Centos Distro und OSX sowie Ubuntu.
edk750


Gibt es eine Möglichkeit, die Pipe- / Printf-Puffer extern für bereits laufende Prozesse mit bekannter PID zu erzwingen?
Mvorisek

9

Sie können eine zeilengepufferte Ausgabe in eine Datei erzielen, indem Sie den folgenden scriptBefehl verwenden:

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1 weil: a) im Gegensatz zur akzeptierten Antwort funktioniert dies nicht, wenn Sie den Befehl im Hintergrund ausführen möchten (der Befehl wird sofort beendet, batch_processwenn Sie &den obigen Befehl anhängen , zumindest auf meiner Linux-Box), wie es scheint wie ein extrem häufiger Anwendungsfall, und b) es gibt hier keine Erklärung dafür, wie diese Beschwörung funktioniert.
Mark Amery

8

Unter Ubuntu hat das unbufferProgramm (aus dem expect-dev) Paket den Trick für mich gemacht. Renn einfach:

unbuffer your_command

und es wird es nicht puffern.


6

Die einfachste Lösung, die ich gefunden habe (es mussten keine Pakete von Drittanbietern installiert sein), wurde in einem ähnlichen Thread auf der Unix- und Linux- Site erwähnt: Verwenden Sie den scriptBefehl. Es ist alt und wahrscheinlich bereits installiert.

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

Beachten Sie, dass der erste Dateinamenparameter für den scriptBefehl die zu schreibende Protokolldatei ist . Wenn Sie einfach ausführen script -q your_command, überschreiben Sie den Befehl, den Sie eingerückt haben, um ihn mit der Protokolldatei auszuführen. Überprüfen Sie man scriptdies aus Sicherheitsgründen, bevor Sie es versuchen.


4

versuche den scriptBefehl; Wenn Ihr System über einen Dateinamen verfügt, wird der gesamte in stdout abgelegte Text in die Datei kopiert. Dies ist sehr nützlich, wenn ein Setup-Programm eine Interaktion erfordert.


Ich kenne den Trick 'script -a out.txt'. Ich habe mich gefragt, ob es eine andere Möglichkeit gibt, den Schreibvorgang nicht puffern zu lassen.
James Dean

3

Persönlich bevorzuge ich die Weiterleitung der Ausgabe eines Befehls, den ich untersuchen möchte tee.

scriptzeichnet zu viele Informationen auf, einschließlich des Zeitpunkts für das Drücken von Tasten, und viele nicht druckbare Zeichen. Was teespart, ist für mich viel lesbarer.


Ich würde der Befehlszeile auch "| less" hinzufügen.
HUB

4
Ich bin mir ziemlich sicher, dass teedie Pufferung auch davon betroffen ist. Beim Aufteilen der Ausgabe von findBefehlen werden häufig noch Teilzeilen durch tee angezeigt .
Magellan

2

Leiten Sie die Ausgabe in eine Datei um und folgen Sie der Datei mit dem tail -fBefehl.

Bearbeiten

Wenn dies immer noch unter Pufferung leidet, verwenden Sie die Syslog-Funktion (die im Allgemeinen nicht gepuffert ist). Wenn der Batch-Prozess als Shell-Skript ausgeführt wird, können Sie dazu den Befehl logger verwenden. Wenn der Batch-Job in einer Skriptsprache ausgeführt wird, sollte es trotzdem eine Protokollierungsfunktion geben.


3
Dies ist, was ich jetzt mache, aber der Prozess puffert das Schreiben in die Datei und das ist genau das, was ich vermeiden möchte.
James Dean

In meiner Bearbeitung finden Sie einen aktualisierten Vorschlag.
Wolfgangsz

1
Dies funktioniert aus offensichtlichen Gründen nicht. Wer zum Teufel gibt This answer is usefulAntworten, die nicht funktionieren und möglicherweise nicht funktionieren können?
24.

1

Sie können den teeBefehl verwenden, nur Magie!

someCommand | tee logFile.logwird sowohl in der Konsole angezeigt als auch in die Protokolldatei geschrieben.


Funktioniert nicht teeverhindert keine Pufferung.
24.

1
@cnst Effektiv teevermeidet es nicht, etwas zu puffern, sondern ermöglicht Ihnen nur, einen Blick auf die Ausgabe zu werfen. Dies ist, was @JamesDean wollte (wie ich seine Frage verstanden habe), aber ich denke, Pufferung ist hier nicht wirklich das Problem. Wenn Sie weitere Informationen haben, lassen Sie es mich wissen.
Benj

Er wollte die Ausgabe sehen, und er bekommt keine Ausgabe (ungepuffert), und dennoch schlagen Sie vor, teedie Ausgabe zu verwenden, die man nicht bekommt, um eine bessere Ansicht zu bekommen?
30.

1
Wie ich @JamesDean-Frage rede: "Ich leite um, um in eine Datei '> out.txt' auszugeben" bedeutet für mich keine Konsolenausgabe, warte, bis der Vorgang abgeschlossen ist, während die gesamte Ausgabe umgeleitet wird. Wenn Sie verwenden, sehen >Sie nichts auf der Konsole. Ich denke, @JamesDean benutzt das Wort "buffering", um das zu beschreiben. Ich werde einen Kommentar zu seiner Frage posten, damit er mehr darüber sagt, was er will.
Benj
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.