c - 使用 dup2 重定向 stdin 和 stdout

标签 c linux stdout stdin 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不会被执行。

关于c - 使用 dup2 重定向 stdin 和 stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72003445/

相关文章:

c - Linux 模块 : performance counter does not work

c - 如何在 C 中用其他符号更改多字符符号?

c++ - 使用pthreads实现线程池

linux - 生成文件 NASM 错误 : more than one input file specified

python - 如何将 os.execlpe() 的 stdout stderr 重定向到文件中

在主函数内更改数组。错误:assignment to expression with array type

java - 在 Java 中更改 SAMBA 密码

c++ - 我们如何中断主线程

来自 IDLE 的 Python 标准输出重定向

bash - 通过套接字连接分别重定向 stdout 和 stderr