Запис "хвіст -f" виведення в інший файл


34

Як продовження мого останнього допису, де я grep & tail -fзнайшов випадки "рідкісних" подій. Я хотів би записати це в інший файл.

Я спробував повернути

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

в

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

Файл створюється, але нічого не заповнюється, це проблема кешування чи іншим чином? Як я можу в реальному часі додавати вихідний хвіст до нового файлу в реальному часі?

Відповіді:


44

Буферизація - це проблема.

Зробіть це так,

хвіст -f log.txt | egrep - буферний рядок 'ПОПЕРЕДЖЕННЯ | ПОМИЛКА' | tee filtered_output.txt
# ^^^^^^^^^^^^^^^

Підтверджено, що також працює над Cygwin.


6

Це, мабуть, буферизація. Дивіться цю публікацію SO про відключення автоматичної буферизації під час використання труб . Ви можете використовувати 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вихідного пакету (наприклад, очікуйте-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-devпакеті і встановлюється як expect_unbuffer.


чи є спосіб досягти цього за допомогою cygwin?
Майк

додана інформація про використання в cygwin; вам знадобиться expectпакет.
шарлатаний кіхот

Дякую, не можу спробувати до понеділка зараз сумно. Оновиться потім.
Майк

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 спасибі за додаткову інформацію. не знаю, якщо це добре для цигуна, але це схоже на більш розумний сценарій.
шарлатанний кіхот

2

Як зазначали інші, ви можете скористатися unbufferутилітою від Expect.

Однак зауважте, що залежно від вашої системи та доступної версії Expect, вам може знадобитися використовувати -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/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.