使用 dup2 重定向标准输入和标准输出

Redirecting stdin and stdout using dup2

我正在编写自己的自定义 shell,作为我项目的一部分,当程序从用户输入中读取“<”或“>”字符时,它需要重定向标准输入和标准输出到自定义文件。我在下面为此写了一个函数。我苦苦挣扎的部分是,即使我以几乎相同的方式编写输入和输出重定向的代码,输出重定向似乎按预期工作,而输入重定向却没有。请看下面的代码:

void inOutReDirector(char **toks, char *inputFile, char *outputFile, int *fd0, int *fd1, int *in, int *out) {
    fflush(0);
    for (int i = 0; toks[i] != NULL; i++) {
        if (strcmp(toks[i], "<") == 0) {
            toks[i] = NULL;
            strcpy(inputFile, toks[i + 1]);
            toks[i + 1] = NULL;
            *in = 1;
        }

        if (strcmp(toks[i], ">") == 0) {
            toks[i] = NULL;
            strcpy(outputFile, toks[i + 1]);
            toks[i + 1] = NULL;
            *out = 1;
        }
    }
    //input redirection
    if (*in == 1) {

        if ((*fd0 = open(inputFile, O_RDONLY, 0)) < 0) {
            printf("Couldn't open input file: %s", strerror(errno));
            exit(1);
        }
        dup2(*fd0, STDIN_FILENO);
        close(*fd0);
    }
    //output redirection
    if (*out == 1) {

        if ((*fd1 = creat(outputFile, 0644)) < 0) {
            printf("Couldn't open output file: %s", strerror(errno));
            exit(1);
        }
        dup2(*fd1, STDOUT_FILENO);
        close(*fd1);
    }
}

下面是我如何从我的 main 中调用这个函数:

int main() {
    char *toks[STD_INPUT_SIZE] = {0};
    int fd0, fd1, in = 0, out = 0;
    char inputFile[64], outputFile[64];
    pid_t pid;
    while (1) {

//print prompt
//get user input

        pid = fork();

        if (pid < 0) {
            printf("%s \n", strerror(errno));
            exit(1);
        }
        int stopNeeded = strcmp(toks[0], "exit") == 0;

        if (pid == 0 && !stopNeeded) {

            pathFinder(toks, shellInput, currentDir); //finding path for execv input
            inOutReDirector(toks, inputFile, outputFile, &fd0, &fd1, &in, &out); // I/O redirection

            if (execv(shellInput, toks) != 0) {
                char *errMsg = strerror(errno);
                printf("%s \n", errMsg);
                //clean the old contents of toks
                for (int i = 0; i < STD_INPUT_SIZE; ++i) {
                    free(toks[i]);
                    toks[i] = NULL;
                }
                exit(1);
            }
        }

        if (pid > 0) {
            pid_t childPid = waitpid(pid, NULL, 0);
            (void) childPid;
        }
    }
    return 0;
}

这是从我的终端屏幕输出重定向的示例

$ ls > output.txt
$ 

这将创建“output.txt”文件并在当前目录中打印此文件中的结果。

这是从我的终端屏幕输入重定向的示例

$ cat < output.txt
$ 

输入重定向无法正常工作。它打印提示并等待输入,而不是在我的终端中显示 output.txt 的内容。

感谢您提前提供的任何帮助!

问题应该出在函数的这一行inOutReDirector

if (strcmp(toks[i], ">") == 0) {

应该改为

else if (strcmp(toks[i], ">") == 0) {

toks[i]等于"<"时,上面的toks[i]会被设置为NULL,这行调用strcmp会导致SIGSEGV,所以子进程会退出,后续的execv不会被执行。