กำลังเขียนเอาต์พุต“ tail -f” ไปยังไฟล์อื่น


34

เป็นการต่อเนื่องจากโพสต์ล่าสุดของฉันที่ฉันได้ใช้grep & tail -fเพื่อค้นหาเหตุการณ์ "หายาก" ที่เกิดขึ้น ฉันต้องการบันทึกสิ่งนี้ในไฟล์อื่น

ฉันได้ลองเลี้ยว

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

เข้าไป

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

ไฟล์ถูกสร้างขึ้น แต่ไม่มีสิ่งใดบรรจุอยู่นี่เป็นปัญหาการแคชหรือไม่? ฉันจะได้รับการต่อท้ายผลลัพธ์ของหางของฉันไปยังไฟล์ใหม่ได้อย่างไร

คำตอบ:


44

การบัฟเฟอร์เป็นปัญหา

ทำแบบนี้

tail -f log.txt | egrep - line-buffered 'WARN | ERROR' | tee filtered_output.txt
# ^^^^^^^^^^^^^^^

ยืนยันการทำงานกับ Cygwin ด้วย


6

มันอาจเป็นปัญหาการบัฟเฟอร์ เห็นนี้โพสต์อื่น ๆ ปิดการใช้งานอัตโนมัติเมื่อใช้บัฟเฟอร์ท่อ คุณสามารถใช้unbufferคำสั่งจากexpect:

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

แก้ไข : เนื่องจากคุณมีขั้นตอนที่ยาวกว่าคุณอาจต้องคลายคำสั่งแต่ละคำสั่ง (ยกเว้นอันสุดท้าย):

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

แก้ไข 2 : unbufferมีให้ใน Cygwin จากexpectซอร์สโค้ด (เช่นexpect-20030128-1-src.tar.bz2ซึ่งพบในexpect/examplesโฟลเดอร์) แต่มันเป็นสคริปต์สั้น ๆ หากคุณมีexpectแพ็คเกจที่ติดตั้งแล้วเพียงแค่ใส่มันลงในสคริปต์ที่เรียกว่าunbufferใน/usr/local/binไดเรกทอรีของคุณ:

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

eval spawn -noecho $argv
set timeout -1
expect

ใน Debian ที่unbufferคำสั่งให้ไว้ในแพคเกจและติดตั้งเป็นexpect-devexpect_unbuffer


จะมีวิธีในการบรรลุสิ่งนี้ด้วย cygwin หรือไม่?
Mike

เพิ่มข้อมูลเกี่ยวกับการใช้ใน cygwin; คุณจะต้องมีexpectแพ็คเกจ
ต้มตุ๋น Quixote

ขอบคุณไม่สามารถลองจนถึงวันจันทร์ที่น่าเศร้า จะอัปเดตแล้ว
Mike

4

เมื่อใช้คำสั่งที่ไม่ 'เสร็จสิ้น' จริง ๆ (เช่นtail -f) สิ่งนี้จะใช้งานไม่ได้หรือไม่ดี (เลย)

คุณควรจะสามารถเปลี่ยนเส้นทางการส่งออกไปยังไฟล์ข้อความ ลองสิ่งนี้:

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

1
ดูเหมือนจะใช้งานไม่ได้
ไมค์

2

นี่คือรุ่นunbufferที่ฉันมี:

#!/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 ขอบคุณสำหรับข้อมูลเพิ่มเติม dunno ถ้ามันเป็นมิตร cygwin แต่ดูเหมือนว่าสคริปต์ที่ชาญฉลาดมากขึ้น
ต้มตุ๋น Quixote

2

ตามที่คนอื่น ๆ ได้ชี้ให้เห็นคุณสามารถใช้unbufferยูทิลิตี้จากความคาดหวัง

อย่างไรก็ตามโปรดทราบว่าขึ้นอยู่กับระบบของคุณและรุ่นที่คาดหวังของคุณที่มีอยู่คุณอาจต้องใช้-pสวิตช์เพื่อคลายแรงกระแทก อ้างถึงหน้าคน:

   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

ดังนั้นคุณอาจต้องการคำเชิญนี้:

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

BTW ดูบทความนี้สำหรับคำอธิบายโดยละเอียดของปัญหาบัฟเฟอร์เอาต์พุต: http://www.pixelbeat.org/programming/stdio_buffering/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.