将多个文件重定向到stdin

时间:2017-06-14 18:32:49

标签: bash

我正在运行一个C程序(在Ubuntu - bash终端上),它需要3个文件的输入 - f1, f2, f3

for(...)
    scanf(....)//reads input from f1
for(...)
    scanf(....)//reads input from f2
for(...)
    scanf(....)//reads input from f3

我想在bash上使用重定向操作符为C程序提供输入。

但是如果按照以下方式运行我的程序,我只能从1个文件中读取:

./a.out < f1

如何将f1, f2,f3的输入重定向到我的C程序?

2 个答案:

答案 0 :(得分:5)

通常,您只对标准输入使用重定向(fd 0,使用<重定向运算符),标准输出(fd 1,>)和标准错误(fd 2, 2>),似乎只限制您一个输入流。

(当然你可以做cat f1 f2 f3 | program之类的事情,但是分开文件会很难。)

但是,如果你真的想要,你也可以使用其他文件描述符号作为输入。这与重定向stderr时的方式相同,只需在重定向运算符之前添加数字即可。所以,运行

./prog 3<file1 4<file2 5< file3

将打开fd&#39; 3和4中的给定文件,并将其传递给./prog。然后,程序可以使用fdopen将stdio流(FILE *)与它们相关联。这里最大的问题是你需要某种方式来了解在程序中使用哪些fd,并且很快就需要使用命令行参数之类的东西。下面的玩具示例是固定的,以使用这三个fd,这当然不会扩展至少。

相反,您最好不要执行所有其他程序所做的事情,并将文件名作为命令行参数传递。即使在需要引用已经打开的文件描述符的情况下,许多Unix也可以通过名称引用它们:/dev/fd/1等(Process substitution,类似于通用管道,是需要这样做的事情之一。)

愚蠢fdopen()示例:

#include <stdio.h>

void read_a_line(int fd)
{
    char buf[64];
    FILE *f = fdopen(fd, "r");
    fgets(buf, 64, f);
    printf("fd %d: %s\n", fd, buf);
    fclose(f);
}

int main(void)
{
    read_a_line(3);
    read_a_line(4);
    read_a_line(5);
    return 0;
}

答案 1 :(得分:1)

我认为您可能正在寻找的功能是getopt。这样,您可以获取命令行参数,而不是将三个文件重定向(仅用于一个输入流)三个文件到您的程序。然后就这样称呼它:

./a.out f1 f2 f3

此外,我刚刚看到this question,它使用了这样的结构:

#include <stdio.h>
int main(int argc, const char* argv[]) {
    for(int i = 1; i < argc; i++) {
       //work with each file name
       //note that argv[0] is: ./a.out
    }
}