Cygwin читает входные данные из tail -f - PullRequest
6 голосов
/ 04 февраля 2011

Используя Cygwin в Windows, я хотел получить звуковое уведомление о конкретных сообщениях в журнале сервера.Я написал следующее:

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *f = fopen("/dev/stdin", "r");
    char bar=' ';
    if(f==NULL) {
        return 1;
    }
    do {
        bar = fgetc(f);
        if((bar=='\n') || (bar=='\r')) {
            printf("\a");
        }
        if(bar!=EOF) {
            printf("%c", bar);
        }
    } while(bar!=EOF);
    fclose(f);
    printf("Done.\n");
    return 0;
}

Затем я выполнил следующую команду:

tail -f serverlog | grep myMessage | ./alerty.exe

Иногда я получаю уведомления, а иногда нет.

Мои вопросыв два раза: 1) Что в моей C-программе не так?Почему я не могу постоянно читать вводимые данные?Это пробудило моё любопытство, поэтому я отчаянно хочу знать.

2) Как мне достичь первоначальной цели - заставить мою систему подавать звуковой сигнал, когда конкретный текст появляется в файле?

Ответы [ 2 ]

3 голосов
/ 04 февраля 2011
  1. По умолчанию stdin / stdout буферизуются строкой, если они терминальны, и буферизованы блоком в противном случае.Это влияет не только на вашу программу (на самом деле get возвращается немедленно, когда что-то доступно, и вы печатаете строки), но также и grep .Требуется флаг --line-buffered.
  2. Сед должен быть в состоянии выполнить работу за вас.Попробуйте просто:

    tail -f serverlog |sed -une 's / myMessage / \ a & / p'

    (-u устанавливает небуферизованный - надеюсь, Cygwin поддерживает его - я проверяю в Linux)

1 голос
/ 04 февраля 2011

stdout буферизируется по умолчанию, поэтому вывод не обязательно появится сразу. Попробуйте вставить fflush(stdout) сразу после printf("\a").

Как упоминает Ян, у вас также могут возникнуть проблемы с буферизацией на stdin. grep имеет --line-buffered вариант, который может помочь. (tail -f делает это самостоятельно, поэтому вам не нужно об этом беспокоиться.)

...