【问题标题】:Cygwin reading input piped in from tail -fCygwin 读取从 tail -f 输入的输入
【发布时间】:2011-06-21 14:10:54
【问题描述】:

在 Windows 上使用 Cygwin,我希望在服务器日志中获得特定消息的声音通知。我写了以下内容:

#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) 我如何实现使系统在特定文本出现在文件中时发出蜂鸣声的最初目标?

【问题讨论】:

    标签: c windows-7 cygwin pipe


    【解决方案1】:
    1. 默认情况下,stdin/stdout 如果是终端则为行缓冲,否则为块缓冲。这不仅会影响您的程序(实际上,当有东西可用并且您正在打印行时,gets 会立即返回),而且也会影响 grep。它需要--line-buffered 标志。
    2. Sed 应该能够为您完成这项工作。试试吧:

      tail -f 服务器日志 | sed -une 's/myMessage/\a&/p'

      -u 设置无缓冲——希望 cygwin 支持它——我正在检查 Linux)

    【讨论】:

    • 对不起,但我不确定:为什么不简单地使用tail -f serverlog | grep myMessage --line-buffered | ./alerty.exe?这是:只是 O.P. 同一行,但添加了缓冲标志。我检查了我的 CygWin(更新),并且支持这个标志。不应该像sed 那样订购 fflush 吗?
    • @Sopalajo:我没有说不要使用它。我说使用它。就像你写的那样——tail -f serverlog | grep --line-buffered myMessage | ./alert.exe(选项应该放在位置参数之前)。 sed 是一个 alternate 选项。
    【解决方案2】:

    stdout 默认是缓冲的,所以输出不一定会立即出现。尝试在 printf("\a") 之后插入 fflush(stdout)

    正如 Jan 所提到的,您也可能在 stdin 上遇到缓冲问题。 grep--line-buffered 可能有帮助的选项。 (tail -f 会自行执行此操作,因此您无需担心。)

    【讨论】:

    • 奇怪。他们实际上也在打印文本本身,并且由于输出是 line 缓冲的,因此在打印换行符时它应该刷新。
    • @Jan:我认为您可能正在做一些事情,可能是上游缓冲而不是输出造成了困难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多