简体   繁体   English

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

[英]Redirecting stdin and stdout using dup2

I'm writing my own custom shell, and as a part of my project, when the program reads either "<" or ">" character from user input, it needs to redirect stdin and stdout to a custom file.我正在编写自己的自定义 shell,作为我项目的一部分,当程序从用户输入中读取“<”或“>”字符时,它需要将标准输入和标准输出重定向到自定义文件。 I wrote a function for this below.我在下面为此写了一个 function。 The part where I'm struggling is that even though I wrote the code for input and output redirections pretty much in the same manner, output redirection seems to work as expected, while input redirection does not.我挣扎的部分是,即使我以几乎相同的方式编写了输入代码和 output 重定向,output 重定向似乎按预期工作,而输入重定向却没有。 See the code below:请参阅下面的代码:

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);
    }
}

And here is how I call this function from my main:下面是我如何从我的 main 中调用这个 function:

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;
}

And here is an example of output redirection from my terminal screen这是从我的终端屏幕重定向output的示例

$ ls > output.txt
$ 

This creates "output.txt" file and prints the result inside this file in the current directory.这将创建“output.txt”文件并在当前目录中打印此文件中的结果。

And here is an example of input redirection from my terminal screen这是我终端屏幕的输入重定向示例

$ cat < output.txt
$ 

Input redirection does not work correctly.输入重定向无法正常工作。 It prints the prompt and waits for the input instead of showing the contents of output.txt in my terminal.它打印提示并等待输入,而不是在我的终端中显示 output.txt 的内容。

I appreciate any help you can provide in advance!感谢您提前提供的任何帮助!

The problem should be on this line of the function inOutReDirector问题应该出在function inOutReDirector这一行

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

should be changed to应该改成

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

When toks[i] is equal to "<", toks[i] will be set to NULL above, this line calling strcmp will cause SIGSEGV, so the child process will exit, and the subsequent execv will not be executed.toks[i]等于"<"时, toks[i]会被设置为上面的NULL,这行调用strcmp会引起SIGSEGV,所以子进程会退出,后面的execv不会执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM