Bash 在 freopen() 之后重定向到标准输入

问题描述 投票:0回答:1

我遇到了阻止我完成任务的 bash 输入重定向的限制,到目前为止我还没有找到解决它的方法。本质上,我需要能够将两个单独的文件分别重定向到程序的

stdin
,而不是一次全部重定向。

这是一个示例程序:

#include <stdio.h>

int main(void) {
    char myArr[200][100];

    int i = 0;
    while (fgets(myArr[i], 100, stdin)) {
        i++;
    }

    freopen("/dev/tty", "rw", stdin);

    int choice = 0;
    while (choice != 1 && choice != 2) {
        printf("Enter menu input: ");
        scanf("%d", &choice);
    }

    if (choice == 1) {
        for (int j = 0; j < i; j++) {
            printf("%s\n", myArr[j]);
        }
    } else if (choice == 2) {
        exit(-1);
    }
}

此程序从

stdin
开始接收输入,直到达到 EOF,并计算成功读取的次数(类似于计算输入中的行数)。我正在使用
./a.out < longInput.txt
传递整个文件的输入值,这会导致
fgets
在到达
longInput.txt
结束时停止读取。

我用

freopen()
重置
stdin
,这样我就可以在
longInput.txt
到达
EOF
后再次开始输入菜单选项。但是,当在程序的第二部分尝试使用 bash 重定向进行菜单输入时,这并不能按预期工作。

我的问题是:如何从only包含菜单选项的第二个输入文件重定向输入,after我从第一个文件重定向并重置

stdin
without硬编码第二个文件名在我打电话给
freopen()
?

假设我无法修改该程序的源代码,并且我只能访问已编译的可执行文件。以下是我已经尝试过的一些参考资料,但无济于事:

谢谢!

linux bash subprocess freopen
1个回答
0
投票

最常见的情况是,您会通过向程序提供参数而不是乱用标准输入来做这种事情。所以你会有这样的东西:

int main(int ac, char **av) {
    if (ac != 3) {
        fprintf(stderr, "usage: %s <data input> <menu input>\n", av[0]);
        exit(1); }
    FILE *dataInput = fopen(av[1], "r");
    if (!dataInput) {
        fprintf(stderr, "can't read data input from %s\n", av[1]);
        exit(1); }
    // read your data input
    char myArr[200][100];
    int i = 0;
    while (i < 200 && fgets(myArr[i], 100, dataInput)) {
        i++;
    }
    
    FILE *meunInput = fopen(av[2], "r");
    if (!menuInput) {
        fprintf(stderr, "Can't open menu input %s\n", av[2]);
        exit(1); }
    // now read your menu input.

然后在 bash 中,您只需使用两个参数和要读取的文件名调用您的程序。如果你想从管道读取(运行其他命令),你可以使用程序重定向:

myprogram <(command that generates data input) <(command that generates menu input)
© www.soinside.com 2019 - 2024. All rights reserved.