【问题标题】:C program refuses to pipe?C程序拒绝管道?
【发布时间】:2014-01-24 17:39:50
【问题描述】:

我正在尝试编译原始 Crowther/Woods FORTRAN Colossal Cave Adventure 的 1991 C 端口。代码是一团糟,但在更改了它的某些部分后,它可以正常编译和运行。

问题是,当我尝试将其输出通过管道传输到另一个程序或文件时,什么都没有显示。 ./adventure 工作正常,但 ./adventure | cat 不打印任何内容。想打电话给fstat 没有任何结果。

程序是否可以通过其他方式检测管道并进入静默模式?即使在主函数的第一行添加printf("Hello World"); 也不会导致通过cat 出现任何内容。

编辑:我使用的是 Jim Gillogly 的版本,但我从中获得源代码的链接已经失效。我会找到另一个下载链接。

【问题讨论】:

  • 可能不是“进入静音模式”。当 stdout 为 tty 时,默认为行缓冲。当它是管道时,它是块缓冲的。您的数据可能只是位于管道缓冲区中。
  • 要在更简单的程序中查看此行为,请编写一个打印“hello world\n”的 hello world 程序,然后进入休眠状态 10 秒。请注意程序写入终端与写入管道时的行为差异。 (确保打印换行符。)

标签: c gcc fortran pipe adventure


【解决方案1】:

正如现有的 cmets 所说,stdout 可能是块缓冲的,因为它不再向终端开放。尝试添加调用:

setvbuf(stdout, NULL, _IOLBF, 0);

在程序开始时的某个地方。这会将 stdout 更改为行缓冲模式,该模式将在程序写入换行符后立即刷新输出。

【讨论】:

    【解决方案2】:

    除了更改程序之外,在 Linux 上,您还可以尝试从命令行使用 stdbuf 更改缓冲区模式(尽管应用程序中的任何 setvbuf 调用显然都会覆盖这一点)。例如,您可以尝试:

    stdbuf -oL ./adventure | cat
    

    unbuffer(附带expect)和script也可以达到类似的效果。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      相关资源
      最近更新 更多