繁体   English   中英

简单的Shell Linux C实现,使用freopen重定向标准输出

[英]simple shell linux C implementation, redirecting stdout with freopen

我正在尝试使用freopen使Shell实现将stdout和stdin从控制台重定向到输出文件,但是当我尝试通过执行类似“ ls> outfile.txt”的操作来执行此操作时,我的程序继续等待子进程,直到我强制停止它,在强制停止它之后,成功创建了输出文件,但是我想知道要解决此问题需要做什么,此后是否需要使用fclose()? 以下是我的代码的一部分,如果您需要更多,请告诉我,但是如果'>'是命令行中倒数第二个arg,则基本上OverrideOut是一个设置为1的int。 然后,我尝试将>和path参数分开,以仅使用execvp调用ls,但是我不确定是否正确执行了此操作。 感谢大家。

while(1){

if((pid = fork()) != 0){


    wait(&status);
    printf("%i", overrideOut);
    printf("Myshell> ");
    fgets(buffer, 512, stdin);

    if(buffer[strlen(buffer)-1] == '\n'){
        buffer[strlen(buffer)-1] = '\0';
    }else{
        printf("\n");
        return 0;
    }
    argv[0] = strtok(buffer, " \n\0");

    for(argc=1; argv[argc-1]; argc++){


        if(!strcmp("&", argv[argc-1])){
        bg = 1;
        }
        if(!strcmp(">", argv[argc-1])){
        overrideOut = 1;
        }
        if(!strcmp(">>", argv[argc-1])){
        appendOut = 1;
        }
        if(!strcmp("<", argv[argc-1])){
        overrideIn = 1;
        }
        if(!strcmp("<<", argv[argc-1])){
        appendIn = 1;
        }

        argv[argc] = strtok(NULL, " \n\0");

    }




    if(!strcmp("exit", argv[0])) exit(0);



    printf("Waiting for child (%d)\n", pid);        
    printf("Child (%d) finished\n", pid);
    if(overrideOut == 1){           
        freopen(argv[argc-2], "w+", stdout);
        //clear the > and path args to just call ls with execvp
        argv[argc-2] = strtok(NULL, " \n\0");
        argv[argc-3] = strtok(NULL, " \n\0");
        //for(argc=0; argv[argc-1]; argc++)
        //printf("argv[%d] = %s, ", argc, argv[argc]);
    }else if(appendOut == 1){
        freopen(argv[argc-2], "a", stdout);
        argv[argc-2] = strtok(NULL, " \n\0");
        argv[argc-3] = strtok(NULL, " \n\0");
    }else{
    freopen("/dev/tty", "rw", stdin);
    }

}else{


if(buffer[0] != '\0'){

        execvp(argv[0], argv);
            printf("error\n");
            return 0;
        }else{
            return 0;
        }
    }
}

您可能想研究一些简单的自由软件shell(如sash)的实现 您可能想在成功调用fork(2)之后进行重定向,并且可以将dup2(2)STDOUT_FILENO (这比常量1更易于STDOUT_FILENO )。

我建议在编码外壳时使用整数文件描述符 ,而不要使用FILE*句柄。

您可能不应该在父Shell进程中重定向文件(仅在子进程中)。 而且您可能应该在父shell进程中调用pipe(2) (也许不在子进程中)。

您忘记了在代码中处理fork的失败

阅读Advanced Linux Programming ,它很好地解释了基本概念。

您的代码段是不完整的:显示您在哪里和如何调用fork (也许还显示您如何调用execve )非常重要。 不要忘记测试所有三种情况:失败( fork结果为<0 ),子进程( ==0 ),父shell进程( >0 )。

暂无
暂无

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

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