Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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
C语言中的重定向/管道错误_C_Redirect_Piping_Nano - Fatal编程技术网

C语言中的重定向/管道错误

C语言中的重定向/管道错误,c,redirect,piping,nano,C,Redirect,Piping,Nano,在这段代码中,我有两个主要问题 1:父级不等待子级打印,然后返回主级并打印。我包括了一个waitpid(),但它似乎没有按照我的预期工作 当我重定向时,我很好地创建了文件,但是nano和vim没有“看到”文件,但是Gedit可以(因此我知道我的输出被正确地发送) 此函数的流程: 输入一个字符串,检查该字符串是否有尾随&(如果存在,则删除该字符串并更新背景标志) 然后字符串在“|”上标记化 每个标记都在“”上标记 然后,其中的每个字符串都在“”上标记 根据上述标记化的结果重定向输出/输入,执行结果

在这段代码中,我有两个主要问题

1:父级不等待子级打印,然后返回主级并打印。我包括了一个waitpid(),但它似乎没有按照我的预期工作

  • 当我重定向时,我很好地创建了文件,但是nano和vim没有“看到”文件,但是Gedit可以(因此我知道我的输出被正确地发送)
  • 此函数的流程:

    输入一个字符串,检查该字符串是否有尾随&(如果存在,则删除该字符串并更新背景标志)

    然后字符串在“|”上标记化
    每个标记都在“”上标记 然后,其中的每个字符串都在“”上标记 根据上述标记化的结果重定向输出/输入,执行结果字符**

        void execute_command(char * s)
        {
            printf("\n");
            int fd[3][2]; //  since we are guaranteed each type of redirection will be used only once, I only need 3 pipes:  <  >  and |
            //int fd[2];    
            int res;
            pid_t pid;
            int status;
            int stdin_c = dup(0);
            int stdout_c = dup(1);
            int i;
            int background = 0;
    
            for(i = 0; s[i] != '\0'; i++);
                if(s[i-1] == '&')
                {
                    background = 1;
                    s[i-1] = '\0';
                }
    
            char ** piped = token_pipe(s);
            char ** left_a;
            char ** right_a;
            int output = 0;
            int input = 0;
    
            for(i = 0; piped[i] != NULL; i++)
            {
                left_a = token_leftarrow(piped[i]);
                right_a = token_rightarrow(piped[i]);
                if(left_a[1] != NULL)   
                {
                    free(piped[i]);
                    piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
                    strcpy(piped[i], left_a[0]);
                    fd[0][0] = open(left_a[1], O_RDONLY);
                    input = i;      
                }
    
                if(right_a[1] != NULL)  
                {
                    free(piped[i]);
                    piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
                    strcpy(piped[i], right_a[0]);
                    fd[1][1] = open(right_a[1], O_WRONLY | O_CREAT, 0666);
                    output = i;
                }   
            }
    
            char ** spaced = token_space(piped[0]);
            char ** spaced2 = NULL;
            if(piped[1] != NULL)
            {
                spaced2 = token_space(piped[1]);
                res = pipe(fd[2]);
                if(res < 0)
                {
                    printf("Pipe Failure\n");
                    exit(-1);
                }// end if
            }   
    
            if(fork() == 0)
            {
                if(background == 1)
                   setpgid(0, 0);
                if(piped[1] != NULL)
                {
                    close(fd[2][1]);
                    close(0);
                    dup(fd[2][0]);
    
                    if(output == 1 && right_a[1] != NULL)
                    {
                        dup2(fd[1][1], 1);
                        close(fd[1][1]);
                    }         
    
                    execvp(spaced2[0], spaced2);
                    perror("Invalid Command");
                    exit(-1);
                }
                else
                {   
                    if(input == 0 || output == 0)
                    {
                        if(right_a[1] != NULL)
                        {
                            dup2(fd[1][1], 1);
                            close(fd[1][1]);
                        }
                        if(left_a[1] != NULL)
                        {
                            dup2(fd[0][0], 0);
                            close(fd[0][0]);
                        }
    
                    }   
    
                    execvp(spaced[0], spaced);
                    perror("Invalid command\n");
                    exit(-1);
                }
            }
        else
        {
            if(piped[1] != NULL)
            {
                if((pid = fork()) == 0)
                {
                    close(fd[2][0]);
                    close(1);
                    dup(fd[2][1]); 
                    if(input == 0 && left_a[1] != NULL)
                    {
                        dup2(fd[0][0], 0);
                        close(fd[0][0]);
                    }     
    
                    execvp(spaced[0], spaced);
                    perror("Invalid Command");
                    exit(-1);
                }
                else
                    if(background == 0)
                        waitpid(pid, &status, WNOHANG);
    
            }
            else
                if(background == 0)
                    wait(NULL);
    
    
            close(fd[2][0]);
            close(fd[2][1]);
            close(fd[0][0]);
            close(fd[1][1]);
            dup2(stdin_c, 0);
            dup2(stdout_c, 1);
    
          } 
    
    
        }
    
    void execute_命令(char*s)
    {
    printf(“\n”);
    int fd[3][2];//因为我们保证每种类型的重定向只使用一次,所以我只需要3个管道:<>和|
    //int-fd[2];
    国际关系;
    pid_t pid;
    智力状态;
    int stdin_c=dup(0);
    int stdout_c=dup(1);
    int i;
    int背景=0;
    对于(i=0;s[i]!='\0';i++);
    如果(s[i-1]=='&')
    {
    背景=1;
    s[i-1]='\0';
    }
    字符**管道=令牌管道;
    字符**左a;
    字符**右a;
    int输出=0;
    int输入=0;
    对于(i=0;管道[i]!=NULL;i++)
    {
    left_a=令牌_leftarrow(管道[i]);
    右箭头a=令牌右箭头(管道[i]);
    if(左_a[1]!=NULL)
    {
    自由(管道[i]);
    管道[i]=calloc(strlen(left_a[0])+1,sizeof(char));
    strcpy(管道[i],左_a[0]);
    fd[0][0]=打开(仅左箭头[1],右箭头);
    输入=i;
    }
    if(right_a[1]!=NULL)
    {
    自由(管道[i]);
    管道[i]=calloc(strlen(left_a[0])+1,sizeof(char));
    strcpy(管道[i],右_a[0]);
    fd[1][1]=开放(右a[1],O_WRONLY | O_CREAT,0666);
    输出=i;
    }   
    }
    字符**间隔=令牌空间(管道[0]);
    char**spaced2=NULL;
    if(管道[1]!=NULL)
    {
    spaced2=令牌_空间(管道[1]);
    res=管道(fd[2]);
    如果(res<0)
    {
    printf(“管道故障”);
    出口(-1);
    }//如果结束
    }   
    如果(fork()==0)
    {
    如果(背景==1)
    setpgid(0,0);
    if(管道[1]!=NULL)
    {
    关闭(fd[2][1]);
    关闭(0);
    dup(fd[2][0]);
    if(输出=1&&right\u a[1]!=NULL)
    {
    dup2(fd[1][1],1);
    关闭(fd[1][1]);
    }         
    execvp(spaced2[0],spaced2);
    perror(“无效命令”);
    出口(-1);
    }
    其他的
    {   
    如果(输入=0 | |输出=0)
    {
    if(right_a[1]!=NULL)
    {
    dup2(fd[1][1],1);
    关闭(fd[1][1]);
    }
    if(左_a[1]!=NULL)
    {
    dup2(fd[0][0],0);
    收盘(fd[0][0]);
    }
    }   
    execvp(间隔[0],间隔);
    perror(“无效命令\n”);
    出口(-1);
    }
    }
    其他的
    {
    if(管道[1]!=NULL)
    {
    如果((pid=fork())==0)
    {
    收盘(fd[2][0]);
    关闭(1);
    dup(fd[2][1]);
    if(输入=0&&left_a[1]!=NULL)
    {
    dup2(fd[0][0],0);
    收盘(fd[0][0]);
    }     
    execvp(间隔[0],间隔);
    perror(“无效命令”);
    出口(-1);
    }
    其他的
    如果(背景==0)
    waitpid(pid和状态,WNOHANG);
    }
    其他的
    如果(背景==0)
    等待(空);
    收盘(fd[2][0]);
    关闭(fd[2][1]);
    收盘(fd[0][0]);
    关闭(fd[1][1]);
    dup2(标准值c,0);
    dup2(stdout_c,1);
    } 
    }
    
    如果对代码进行了注释,这样我们就知道每个代码块要完成的任务,那么我们可以提供帮助。事实上,我看到(我认为)有很多糟糕的逻辑序列,就像一个简单的开始,对waitpid()的调用有WNOHANG参数,因此它不会等待子函数完成fork()函数有三种退出情况,而不仅仅是两种。也就是说,代码需要始终检查错误情况并考虑到它们,而不是假设一切正常——阅读系统功能描述可能会有所帮助。顺便说一句:有三个标准的文件描述符需要复制,stdin、stdout、stderrI对注释表示歉意,我将尝试不使用WNOHANG参数,在这种情况下我不关心stderr。