Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
简单的shell linux C实现,使用freopen重定向stdout_C_Linux_Bash_Shell_Redirect - Fatal编程技术网

简单的shell linux C实现,使用freopen重定向stdout

简单的shell linux C实现,使用freopen重定向stdout,c,linux,bash,shell,redirect,C,Linux,Bash,Shell,Redirect,我试图让shell实现使用freopen将stdout和stdin从控制台重定向到输出文件,但当我尝试执行类似“ls>outfile.txt”的操作时,我的程序继续等待子进程,直到我强制停止它,在强制停止后,输出文件成功创建,但是我想知道我需要做什么来解决这个问题,我需要在之后使用fclose()吗?下面是我的代码的一部分,如果您需要更多,请告诉我,但基本上,如果'>'是命令行中倒数第二个参数,则overrideOut是一个int,我将其设置为1。然后,我尝试分离>和path参数,只使用exec

我试图让shell实现使用freopen将stdout和stdin从控制台重定向到输出文件,但当我尝试执行类似“ls>outfile.txt”的操作时,我的程序继续等待子进程,直到我强制停止它,在强制停止后,输出文件成功创建,但是我想知道我需要做什么来解决这个问题,我需要在之后使用fclose()吗?下面是我的代码的一部分,如果您需要更多,请告诉我,但基本上,如果'>'是命令行中倒数第二个参数,则overrideOut是一个int,我将其设置为1。然后,我尝试分离>和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;
        }
    }
}
while(1){
如果((pid=fork())!=0){
等待(&状态);
printf(“%i”,覆盖);
printf(“Myshell>”);
fgets(缓冲区,512,标准输入);
if(buffer[strlen(buffer)-1]=='\n'){
缓冲区[strlen(buffer)-1]='\0';
}否则{
printf(“\n”);
返回0;
}
argv[0]=strtok(缓冲区“\n\0”);
for(argc=1;argv[argc-1];argc++){
如果(!strcmp(“&”,argv[argc-1])){
bg=1;
}
如果(!strcmp(“>”,argv[argc-1])){
超越=1;
}
如果(!strcmp(“>>”,argv[argc-1])){
appendOut=1;
}

如果(!strcmp(“),您可能需要研究一些简单的自由软件shell的实现。您可能希望在成功调用 您可以使用STDOUT\u FILENO
(这比常量1更容易让人阅读)

在编写shell代码时,我建议使用整数文件描述符,而不是
文件*
句柄

您可能不应该重定向父shell进程中的文件(仅在子进程中)。您可能应该调用父shell进程(可能不在子进程中)

您忘记处理代码中的
fork
故障

阅读这篇文章,它很好地解释了基本概念


您的代码片段不完整:显示在何处以及如何调用
fork
(也许还显示如何调用
execve
)非常重要。不要忘记测试所有三种情况:失败(导致
fork
的结果为
0
).

我已经添加了while循环的其余部分,以显示我是如何调用fork的。我将研究您建议的方法,谢谢您的帮助。我没有在这个程序中实现管道。我认为您的上标注释(或者是下标注释?)应该在级别1(
#
)标题-好吧,我夸大了,但这是这里的关键建议。我用粗体字说了这句话。在shell中使用
freopen()
进行I/O重定向是一种常规做法。这通常是使用文件描述符完成的,部分原因是
pipe()
创建文件描述符并
dup2()
操纵它们。