【问题标题】:How do I check if my program has data piped into it如何检查我的程序是否有数据输入
【发布时间】:2011-02-03 14:29:33
【问题描述】:

我正在编写一个应该通过标准输入读取输入的程序,所以我有以下结构。

FILE *fp=stdin;

但是,如果用户没有将任何内容通过管道传输到程序中,这只会挂起,我如何检查用户是否真的将数据传输到我的程序中,例如

gunzip -c file.gz |./a.out #should work
./a.out  #should exit program with nice msg.

谢谢

【问题讨论】:

  • 备案,程序不挂;它只是在等待输入。如果您发送 EOF(在大多数平台上为 Ctrl-D),则会将其解释为输入提前结束。

标签: c++ c pipe stdin


【解决方案1】:

将标准输入传递给 select() 或 poll() 应该会告诉您输入是否正在等待。在许多操作系统下,您还可以判断标准输入是 tty 还是管道。

编辑:我知道我将不得不强调 tty 测试的 also 部分。 fifo 不是 tty,但可能在很长一段时间内都没有准备好输入。

【讨论】:

  • 我认为 OP 只是想涵盖 run-on-command-line-and-wonder-why-it-"hangs" 的情况。可能试图修复一个 PEBKAC 错误。坐在那里等待 FIFO 或其他管道是可以的。
【解决方案2】:

试试“man isatty”,我想这个功能会告诉你你是否在和用户说话。

【讨论】:

    【解决方案3】:

    使用isatty 检测标准输入来自终端而不是重定向。

    【讨论】:

      【解决方案4】:

      查看函数“isatty” - 如果 STDIN 是终端,您可以跳过读取它。如果它不是终端,则您将通过管道传输或重定向数据,并且您可以读取直到 EOF。

      【讨论】:

        【解决方案5】:

        由于您使用的是文件指针,因此您需要 isatty()fileno() 来执行此操作:

        #include <unistd.h>
        #include <stdio.h>
        
        int main(int argc, char* argv[])
        {
            FILE* fp = stdin;
        
            if(isatty(fileno(fp)))
            {
                fprintf(stderr, "A nice msg.\n");
                exit(1);
            }
        
            /* carry on... */
            return 0;
        }
        

        实际上,这是很长的路要走。简短的方法是不使用文件指针:

        #include <unistd.h>
        
        int main(int argc, char* argv[])
        {
            if(isatty(STDIN_FILENO))
            {
                fprintf(stderr, "A nice msg.\n");
                exit(1);
            }
        
            /* carry on... */
            return 0;
        }
        

        几个标准的 Unix 程序执行此检查以修改它们的行为。例如,如果您设置了 ls 以提供漂亮的颜色,如果您将其标准输出通过管道传输到另一个程序,它将关闭颜色。

        【讨论】:

          【解决方案6】:

          您使用 select() 获得的另一个选项是设置从 stdin 读取的超时(相对于从 stdin 的第一次读取或从 stdin 的连续读取)。

          有关在标准输入上使用 select 的代码示例,请参阅:

          How to check if stdin is still opened without blocking?

          【讨论】:

            猜你喜欢
            • 2021-05-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-15
            • 2022-12-09
            • 1970-01-01
            • 2021-02-15
            • 2021-06-06
            相关资源
            最近更新 更多