“Tail -f” çıkışını başka bir dosyaya yazma


34

"Nadir" olayların oluşumunu bulmak için kullandığım son yazımın bir devamı olarak grep & tail -f. Bunu başka bir dosyaya kaydetmek istiyorum.

Dönmeyi denedim

tail -f log.txt | egrep 'WARN|ERROR'

içine

tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

Dosya oluşturulur, ancak hiçbir şey doldurulmaz, bu önbellekleme sorunu mu yoksa başka bir şey mi? Kuyruğumun çıktısının gerçek zamanlı olarak yeni bir dosyaya eklenmesini nasıl sağlayabilirim?

Yanıtlar:


44

Tamponlama problemdir.

Bu şekilde yap,

kuyruk -f log.txt | egrep --line-buffered 'WARN | ERROR' | tee_tipucu.txt
# ^^^^^^^^^^^^^^^^

Cygwin'de de çalıştığını doğruladı.


6

Muhtemelen bir tamponlama sorunudur. Borular kullanırken otomatik tamponlamayı devre dışı bırakmak için bu SO yayına bakın . unbufferKomutu şuradan kullanabilirsiniz expect:

$ unbuffer tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

Düzenleme : Daha uzun bir boru hattınız olduğundan, muhtemelen her komutun çözülmesini kaldırmanız gerekir (sonuncusu hariç):

$ unbuffer tail -f log.txt | unbuffer egrep 'WARN|ERROR' | tee filtered_output.txt

Düzenleme 2 : unbufferden Cygwin mevcuttur expect(örn kaynak paketinin bekliyoruz-20030128-1-src.tar.bz2 , bulunan expect/examplesklasöre), ancak çok kısa bir senaryo. Eğer varsa expectzaten yüklü paketi, basitçe adında bir komut dosyası içine koymak unbufferiçin de /usr/local/bindizindeki:

#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST

eval spawn -noecho $argv
set timeout -1
expect

Debian'da, unbufferkomut expect-devpakette verilir ve olarak yüklenir expect_unbuffer.


Bunu cygwin ile başarmanın bir yolu var mı?
Mike,

cygwin'de kullanım hakkında bilgi eklendi; expectpakete ihtiyacınız olacak .
quack quixote

Teşekkürler, pazartesi gününe kadar ne yazık ki deneyemem. O zaman güncellenir.
Mike,

4

Gerçekten 'bitirmeyen' bir komut kullanıldığında (örneğin tail -f), bu gerçekten işe yaramadı ya da hiç de işe yaramaz.

Çıktıyı bir metin dosyasına yönlendirebilmelisiniz. Bunu dene:

tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt

1
Bu işe yaramadı.
Mike,

2

Bu unbufferbenim sahip olduğum versiyon :

#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST

if {[string compare [lindex $argv 0] "-p"] == 0} {
    # pipeline
    set stty_init "-echo"
    eval spawn -noecho [lrange $argv 1 end]
    close_on_eof -i $user_spawn_id 0
    interact {
    eof {
        # flush remaining output from child
        expect -timeout 1 -re .+
        return
    }
    }
} else {
    set stty_init "-opost"
    set timeout -1
    eval spawn -noecho $argv
    expect
}

+1 Ek bilgi için teşekkürler. Eğer cygwin-dostu ise ama daha zekice bir senaryo gibi gözüküyorsa bilmiyorum.
quack quixote

2

Diğerlerinin de belirttiği gibi, unbufferyardımcı programı Expect'ten kullanabilirsiniz.

Bununla birlikte, sisteminize ve kullanılabilir Bekleme sürümüne bağlı olarak, -parabellek çözme için anahtarı kullanmanız gerekebileceğini unutmayın . Man sayfasını alıntı:

   Normally, unbuffer does not read from stdin.  This simplifies use of unbuffer in some situations.  To use unbuffer in a  pipeline,  use
   the -p flag.  Example:

           process1 | unbuffer -p process2 | process3

Bu nedenle bu çağrıya ihtiyacınız olabilir:

unbuffer -p tail -f log.txt | unbuffer -p egrep 'WARN|ERROR' | tee filtered_output.txt

BTW, çıktı tamponlama probleminin tam açıklaması için bu makaleye bakın: http://www.pixelbeat.org/programming/stdio_buffering/

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.