简体   繁体   English

在简单Shell C中重定向输入/输出

[英]Redirecting Input/Output in Simple Shell C

I am attempting to redirect output in C shell that I have built. 我试图重定向已构建的C Shell中的输出。 We are required to use fork(), dup2(), and execvp(). 我们需要使用fork(),dup2()和execvp()。 If I run the command "ls > test", the test file is created but it is blank. 如果运行命令“ ls> test”,则会创建测试文件,但该文件为空。 I am wondering if there is an issue with the order that I am calling the various required functions. 我想知道我调用各种所需功能的顺序是否有问题。 I am stripping out the ">" character and attempting to pass to the execvp(), but I am just getting a blank file. 我正在剥离“>”字符并尝试传递给execvp(),但是我只是得到一个空白文件。 I printed the array after the ">" was removed and it just contained "ls" and "test". 在删除“>”之后,我打印了该数组,它仅包含“ ls”和“ test”。 Is there an issue with the order or the way I am using these commands? 我使用这些命令的顺序或方式是否存在问题?

if(execArraySize > 2 && strcmp(execArray[1], ">") == 0){
    outputRedir = 1;
    outputIndex = 2;
    //printf("%s\n", execArray[1]);

    printf("Outputing to: %s\n", execArray[outputIndex]);
    //continue;
}

//Check if we are redirecting the output in a 5 argument set
//No error handling required
else if(execArraySize > 4 && strcmp(execArray[3], ">") == 0){
    outputRedir = 1;
    outputIndex = 4;
    // printf("%s\n", execArray[3]);
    // printf("Outputing to: %s\n", execArray[outputIndex]);
}

//Check if we are redirecting the input in a 3 argument set
//No error handling required
if(execArraySize > 2 && strcmp(execArray[1], "<") == 0){
    inputRedir = 1;
    inputIndex = 2;
    printf("%s\n", execArray[1]);
    printf("Input From: %s\n", execArray[inputIndex]);
}

//Check if we are redirecting the input in a 5 argument set
//No error handling required
else if(execArraySize > 4 && strcmp(execArray[3], "<") == 0){
    inputRedir = 1;
    inputIndex = 4;
    printf("%s\n", execArray[3]);
    printf("Input From: %s\n", execArray[inputIndex]);
}
//If we are in the background and are not redirectin input
if(bg == 1 && inputRedir == 0){

    fileDescriptor = open("/dev/null", O_RDONLY);

    if (fileDescriptor == -1)
    {
        printf("Error reading in input in bg %s\n", execArray[inputIndex]);
        exit(1);
    }

    dupInt = dup2(fileDescriptor,0);
    if (dupInt == -1)
    {
        printf("Error reading in dup2() in bg %s\n", execArray[inputIndex]);
        exit(1);
    }

}

//If we are redirecting input
if(inputRedir == 1){

    //Open the file

    fileDescriptor = open(execArray[inputIndex], O_RDONLY);

    //Check the file was opened properly
    if (fileDescriptor == -1)   
    {
        printf("cannot open %s for input\n", execArray[inputIndex]);
        exit(1);
    }
    else
    {
        //Duplicate file descriptor
        dupInt = dup2(fileDescriptor,0);
        close(fileDescriptor);
        if (dupInt == -1)
        {
            //Error Check and exit
            printf("Error in dup2() function!\n");
            exit(1);
        }
        else
        {
            printf("dup2() worked as expected\n");
        }
    }
}

//If we are redirecting output
if (outputRedir == 1)
{
    //Open the file to write to it

    fileDescriptor = open(execArray[outputIndex], O_WRONLY|O_CREAT|O_TRUNC, 0644);

    //Check the file was opened/created properly
    if (fileDescriptor == -1)   
    {
        printf("Error in output to: %s\n", execArray[outputIndex]);
        exit(1);
    }
    else
    {
        //Duplicate file descriptor
        //dupInt = dup2(fileDescriptor,1);
        //close(fileDescriptor);

        for(i=outputIndex-1; i < execArraySize; i++){
            execArray[i] = execArray[i+1];
        }

        for(i=0; i < execArraySize; i++){
            printf("%s\n", execArray[i]);
        }

        dupInt = dup2(fileDescriptor,1);
        close(fileDescriptor);

        if (dupInt == -1)
        {
            //Error handle and exit
            printf("Error in dup2() function\n");
            exit(1);
        }
        else
        {
            //printf("dup2() worked as expected\n");
            //printf("BEFORE EXEC\n");
            //execvp(execArray[0],execArray);
            //perror("execvp\n");
        }

        //exec(execArray[outputIndex - 2]);

    }

}

execvp(execArray[0], execArray);

printf("%s", execArray[0]);
fflush(NULL);
perror("");
//free(execArray);
//free(input);

exit(1);

Aside from the issues raised by @Barmar, the reason why your code doesn't actually redirect output from ls to test is that you actually close the file descriptor right before your exec . 除了@Barmar提出的问题外,您的代码实际上并未将ls输出重定向到test是,您实际上在exec之前关闭了文件描述符。

You should be doing your redirection and your exec in the child process after a fork . fork之后,您应该在子进程中exec重定向和exec Don't forget to close your output/input file descriptors and STDOUT & STDIN in your parent after the fork. 不要忘记在派生后关闭父级中的输出/输入文件描述符以及STDOUT和STDIN。

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

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