C'è un modo per reindirizzare l'output su un file senza buffering su unix / linux?


49

Ho un processo batch di lunga durata che genera alcune informazioni di debug e di processo su stdout. Se corro da un terminale, posso tenere traccia di "dove si trova", ma i dati diventano troppi e scorrono dallo schermo.

Se reindirizzo all'output su un file '> out.txt' alla fine ottengo l'intero output ma è bufferizzato, quindi non riesco più a vedere cosa sta facendo in questo momento.

C'è un modo per reindirizzare l'output ma renderlo non bufferizzare le sue scritture?


1
Potresti dare un'occhiata al mio "dibattito" (e @cnst) qui sotto, suppongo che l'unica cosa che desideri sia vedere l'output contemporaneamente registrandolo su un file. Se hai trovato una soluzione, faccelo sapere;)!
Benj,

Risposte:


52

Puoi impostare esplicitamente le opzioni di buffering degli stream standard usando una setvbufchiamata in C (vedi questo link ), ma se stai provando a modificare il comportamento di un programma esistente prova stdbuf( coreutilsapparentemente parte dell'inizio con la versione 7.5).

Questo buffer stdoutfino a una linea:

stdbuf -oL command > output

Questo disabilita del stdouttutto il buffering:

stdbuf -o0 command > output

aaarghhh ... Il mio Ubuntu ha solo 7,4 coreutils ... :(
Calmarius,

@Calmarius: compilare coreutils dovrebbe essere abbastanza facile. Prendi una nuova versione da ftp.gnu.org/gnu/coreutils e provaci . È una ./configure && maketariffa standard . Non è nemmeno necessario installarlo in seguito, è possibile utilizzare semplicemente il stdbufbinario src/.
Eduardo Ivanec,

doppio argh. ne ho bisogno su un vecchio centro di distribuzione e OSX e Ubuntu.
edk750,


Esiste un modo per forzare i buffer pipe / printf esternamente per il processo già in esecuzione con PID noto?
Mvorisek,

9

È possibile ottenere l'output del buffer di linea in un file utilizzando il scriptcomando in questo modo:

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 perché: a) a differenza della risposta accettata, questo non funziona se si desidera eseguire il comando in background (il comando termina immediatamente senza finire batch_processse si aggiunge &al comando sopra, almeno sulla mia scatola di Linux), che sembra come un caso d'uso estremamente comune eb) non c'è spiegazione qui su come funziona questo incantesimo.
Mark Amery,

8

Su Ubuntu, il pacchetto del unbufferprogramma (dal expect-dev) ha fatto il trucco per me. Corri:

unbuffer your_command

e non lo bufferizzerà.


6

La soluzione più semplice che ho trovato (non necessitava di alcun pacchetto di terze parti installato) è stata menzionata in un thread simile sul sito Unix e Linux : utilizzare il scriptcomando. È vecchio e probabilmente già installato.

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

Si noti che il primo parametro del nome file per il scriptcomando è il file di registro da scrivere . Se si esegue semplicemente script -q your_command, si sovrascriverà il comando indentato per l'esecuzione con il file di registro. Controlla man script, per sicurezza, prima di provarlo.


4

prova il scriptcomando; se il tuo sistema lo possiede, prende un nome file come argomento, tutto il testo scaricato su stdout viene copiato nel file. È molto utile quando un programma di installazione richiede interazione.


Conosco il trucco "script -a out.txt". Mi chiedevo se ci fosse un altro modo per rendere il processo di scrittura non buffer.
James Dean,

3

Personalmente preferisco il piping dell'output di un comando che voglio esaminare tee.

scriptregistra troppe informazioni, inclusi i tempi di pressione dei tasti e molti caratteri non stampabili. Ciò che teesalva è molto più leggibile dall'uomo per me.


Vorrei anche aggiungere "| less" alla riga di comando.
HUB,

4
Sono abbastanza sicuro che teesia influenzato anche dal buffering. Spesso continuo a visualizzare righe parziali visualizzate per T quando si divide l'output dai findcomandi.
Magellan,

2

Reindirizza l'output in un file e segui il file con il tail -fcomando.

modificare

Se questo soffre ancora di buffering, usa la funzione syslog (che è generalmente senza buffer). Se il processo batch viene eseguito come script di shell, è possibile utilizzare il comando logger per farlo. Se il processo batch viene eseguito in un linguaggio di scripting, dovrebbe comunque esserci una funzione di registrazione.


3
Questo è quello che faccio in questo momento, ma il processo bufferizza la scrittura sul file ed è proprio quello che voglio evitare.
James Dean,

Vedi la mia modifica per una proposta aggiornata.
Wolfgangsz,

1
Questo non funziona per ovvi motivi. Chi diavolo dà This answer is usefulrisposte che non funzionano e che non possono funzionare?
primo

1

Puoi usare il teecomando, solo magia!

someCommand | tee logFile.logentrambi verranno visualizzati nella console e scriveranno nel file di registro.


Non funziona teenon impedirà l'esecuzione di alcun buffering.
primo

1
@cnst In effetti, teenon eviterà un po 'di buffering ma ti consentirà solo di dare un'occhiata a ciò che è l'output. Questo è ciò che voleva @JamesDean (dato che non capisco la sua domanda), ma penso che il buffering non sia proprio il problema qui. Se hai maggiori dettagli, fammi sapere.
Benj,

Voleva vedere l'output, e non sta ottenendo alcun output (in modo non bufferizzato), eppure suggerisci di utilizzare teeper ottenere una visione migliore dell'output che non si sta ottenendo?
CNST

1
Come faccio a red @JamesDean domanda: "Reindirizzamento per l'output su un file '> out.txt'" significa per me nessun output della console, attendere il completamento del processo mentre l'intero output viene reindirizzato. Quando stai usando >non vedi nulla sulla console. Immagino che @JamesDean stia usando la parola "buffering" per descriverlo. Pubblicherò un commento sulla sua domanda per lui per dire di più su ciò che vuole.
Benj,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.