代码之家  ›  专栏  ›  技术社区  ›  bstpierre Edgar Aviles

bash:强制执行进程有无缓冲的标准输出

  •  20
  • bstpierre Edgar Aviles  · 技术社区  · 14 年前

    #!/bin/bash
    exec /usr/bin/some_binary > /tmp/my.log 2>&1
    

    问题是 some_binary 将其所有日志发送到stdout,缓冲使其只显示几行的输出。这是恼人的时候,有些东西卡住了,我需要看看最后一行说什么。

    在我执行exec之前,是否有任何方法可以使stdout取消缓冲,从而影响一些二进制文件,使其具有更有用的日志记录?

    (包装器脚本只在exec之前设置了一些环境变量,因此用perl或python实现的解决方案也是可行的。)

    6 回复  |  直到 10 年前
        1
  •  14
  •   Dennis Williamson    14 年前

    你可能会发现 unbuffer 随附的脚本 expect 可能会有帮助。

        2
  •  33
  •   Schlueter Joerg S    6 年前

    stdbuf 修改I/O流缓冲的命令:

    http://www.pixelbeat.org/programming/stdio_buffering/

    stdbuf -oL /usr/bin/some_binary > /tmp/my.log 2>&1
    

    这将允许文本立即逐行显示(一旦一行以行尾结束) "\n" C)中的字符。如果您真的想要立即输出,请使用 -o0 相反。

    expect 通过 unbuffer 解除缓冲 some_binary 认为它正面临一个真正的tty标准输出。

        3
  •  11
  •   Community CDub    8 年前

    一些命令行程序可以选择修改其标准数据流缓冲行为。如果C源代码可用,那么这就是方法。。。

    # two command options ...
    man file | less -p '--no-buffer'
    man grep | less -p '--line-buffered'
    
    # ... and their respective source code
    
    # from: http://www.opensource.apple.com/source/file/file-6.2.1/file/src/file.c
    if(nobuffer)
       (void) fflush(stdout);
    
    # from: http://www.opensource.apple.com/source/grep/grep-28/grep/src/grep.c
    if (line_buffered)
       fflush (stdout);
    

    除了使用expect的unbuffer脚本或修改程序的源代码之外,您还可以尝试使用script(1)来避免由管道引起的标准输出中断:

    Trick an application into thinking its stdin is interactive, not a pipe

    # Linux
    script -c "[executable string]" /dev/null
    
    # FreeBSD, Mac OS X
    script -q /dev/null "[executable string]"
    
        4
  •  3
  •   Dexter Legaspi    9 年前

    我在网上搜寻答案,但这些都不管用 uniq 它太顽固了,除了 stdbuf

    {piped_command_here} | stdbuf -oL uniq | {more_piped_command_here}

        5
  •  2
  •   Otheus    11 年前

    gnucoreutils-8包含一个名为stdbuf的程序,它基本上完成了ldu预加载技巧。它可以在Linux上工作,据说也可以在BSD系统上工作。

        6
  •  2
  •   EKM    8 年前

    export NSUnbufferedIO=是

    这将为C和Objective-C终端输出命令设置终端无缓冲。